1
// Copyright 2016 Canonical Ltd.
2
// Licensed under the LGPLv3, see LICENCE file for details.
9
"github.com/juju/errors"
10
"github.com/juju/testing"
11
jc "github.com/juju/testing/checkers"
12
"github.com/juju/version"
13
gc "gopkg.in/check.v1"
16
type machineSuite struct {
17
testing.LoggingCleanupSuite
20
var _ = gc.Suite(&machineSuite{})
22
func (*machineSuite) TestNilGetters(c *gc.C) {
24
c.Check(empty.Zone() == nil, jc.IsTrue)
25
c.Check(empty.PhysicalBlockDevice(0) == nil, jc.IsTrue)
26
c.Check(empty.Interface(0) == nil, jc.IsTrue)
27
c.Check(empty.BootInterface() == nil, jc.IsTrue)
30
func (*machineSuite) TestReadMachinesBadSchema(c *gc.C) {
31
_, err := readMachines(twoDotOh, "wat?")
32
c.Check(err, jc.Satisfies, IsDeserializationError)
33
c.Assert(err.Error(), gc.Equals, `machine base schema check failed: expected list, got string("wat?")`)
35
_, err = readMachines(twoDotOh, []map[string]interface{}{
40
c.Check(err, jc.Satisfies, IsDeserializationError)
41
c.Assert(err, gc.ErrorMatches, `machine 0: machine 2.0 schema check failed: .*`)
44
func (*machineSuite) TestReadMachines(c *gc.C) {
45
machines, err := readMachines(twoDotOh, parseJSON(c, machinesResponse))
46
c.Assert(err, jc.ErrorIsNil)
47
c.Assert(machines, gc.HasLen, 3)
49
machine := machines[0]
51
c.Check(machine.SystemID(), gc.Equals, "4y3ha3")
52
c.Check(machine.Hostname(), gc.Equals, "untasted-markita")
53
c.Check(machine.FQDN(), gc.Equals, "untasted-markita.maas")
54
c.Check(machine.Tags(), jc.DeepEquals, []string{"virtual", "magic"})
56
c.Check(machine.IPAddresses(), jc.DeepEquals, []string{"192.168.100.4"})
57
c.Check(machine.Memory(), gc.Equals, 1024)
58
c.Check(machine.CPUCount(), gc.Equals, 1)
59
c.Check(machine.PowerState(), gc.Equals, "on")
60
c.Check(machine.Zone().Name(), gc.Equals, "default")
61
c.Check(machine.OperatingSystem(), gc.Equals, "ubuntu")
62
c.Check(machine.DistroSeries(), gc.Equals, "trusty")
63
c.Check(machine.Architecture(), gc.Equals, "amd64/generic")
64
c.Check(machine.StatusName(), gc.Equals, "Deployed")
65
c.Check(machine.StatusMessage(), gc.Equals, "From 'Deploying' to 'Deployed'")
67
bootInterface := machine.BootInterface()
68
c.Assert(bootInterface, gc.NotNil)
69
c.Check(bootInterface.Name(), gc.Equals, "eth0")
71
interfaceSet := machine.InterfaceSet()
72
c.Assert(interfaceSet, gc.HasLen, 2)
73
id := interfaceSet[0].ID()
74
c.Assert(machine.Interface(id), jc.DeepEquals, interfaceSet[0])
75
c.Assert(machine.Interface(id+5), gc.IsNil)
77
blockDevices := machine.BlockDevices()
78
c.Assert(blockDevices, gc.HasLen, 2)
79
c.Assert(blockDevices[0].Name(), gc.Equals, "sda")
80
c.Assert(blockDevices[1].Name(), gc.Equals, "sdb")
82
blockDevices = machine.PhysicalBlockDevices()
83
c.Assert(blockDevices, gc.HasLen, 2)
84
c.Assert(blockDevices[0].Name(), gc.Equals, "sda")
85
c.Assert(blockDevices[1].Name(), gc.Equals, "sdb")
87
id = blockDevices[0].ID()
88
c.Assert(machine.PhysicalBlockDevice(id), jc.DeepEquals, blockDevices[0])
89
c.Assert(machine.PhysicalBlockDevice(id+5), gc.IsNil)
92
func (*machineSuite) TestReadMachinesNilValues(c *gc.C) {
93
json := parseJSON(c, machinesResponse)
94
data := json.([]interface{})[0].(map[string]interface{})
95
data["architecture"] = nil
96
data["status_message"] = nil
97
data["boot_interface"] = nil
98
machines, err := readMachines(twoDotOh, json)
99
c.Assert(err, jc.ErrorIsNil)
100
c.Assert(machines, gc.HasLen, 3)
101
machine := machines[0]
102
c.Check(machine.Architecture(), gc.Equals, "")
103
c.Check(machine.StatusMessage(), gc.Equals, "")
104
c.Check(machine.BootInterface(), gc.IsNil)
107
func (*machineSuite) TestLowVersion(c *gc.C) {
108
_, err := readMachines(version.MustParse("1.9.0"), parseJSON(c, machinesResponse))
109
c.Assert(err, jc.Satisfies, IsUnsupportedVersionError)
110
c.Assert(err.Error(), gc.Equals, `no machine read func for version 1.9.0`)
113
func (*machineSuite) TestHighVersion(c *gc.C) {
114
machines, err := readMachines(version.MustParse("2.1.9"), parseJSON(c, machinesResponse))
115
c.Assert(err, jc.ErrorIsNil)
116
c.Assert(machines, gc.HasLen, 3)
119
func (s *machineSuite) getServerAndMachine(c *gc.C) (*SimpleTestServer, *machine) {
120
server, controller := createTestServerController(c, s)
121
// Just have machines return one machine
122
server.AddGetResponse("/api/2.0/machines/", http.StatusOK, "["+machineResponse+"]")
123
machines, err := controller.Machines(MachinesArgs{})
124
c.Assert(err, jc.ErrorIsNil)
125
c.Check(machines, gc.HasLen, 1)
126
machine := machines[0].(*machine)
127
return server, machine
130
func (s *machineSuite) TestStart(c *gc.C) {
131
server, machine := s.getServerAndMachine(c)
132
response := updateJSONMap(c, machineResponse, map[string]interface{}{
133
"status_name": "Deploying",
134
"status_message": "for testing",
136
server.AddPostResponse(machine.resourceURI+"?op=deploy", http.StatusOK, response)
138
err := machine.Start(StartArgs{
139
UserData: "userdata",
140
DistroSeries: "trusty",
142
Comment: "a comment",
144
c.Assert(err, jc.ErrorIsNil)
145
c.Assert(machine.StatusName(), gc.Equals, "Deploying")
146
c.Assert(machine.StatusMessage(), gc.Equals, "for testing")
148
request := server.LastRequest()
149
// There should be one entry in the form values for each of the args.
150
form := request.PostForm
151
c.Assert(form, gc.HasLen, 4)
152
c.Check(form.Get("user_data"), gc.Equals, "userdata")
153
c.Check(form.Get("distro_series"), gc.Equals, "trusty")
154
c.Check(form.Get("hwe_kernel"), gc.Equals, "kernel")
155
c.Check(form.Get("comment"), gc.Equals, "a comment")
158
func (s *machineSuite) TestStartMachineNotFound(c *gc.C) {
159
server, machine := s.getServerAndMachine(c)
160
server.AddPostResponse(machine.resourceURI+"?op=deploy", http.StatusNotFound, "can't find machine")
161
err := machine.Start(StartArgs{})
162
c.Assert(err, jc.Satisfies, IsBadRequestError)
163
c.Assert(err.Error(), gc.Equals, "can't find machine")
166
func (s *machineSuite) TestStartMachineConflict(c *gc.C) {
167
server, machine := s.getServerAndMachine(c)
168
server.AddPostResponse(machine.resourceURI+"?op=deploy", http.StatusConflict, "machine not allocated")
169
err := machine.Start(StartArgs{})
170
c.Assert(err, jc.Satisfies, IsBadRequestError)
171
c.Assert(err.Error(), gc.Equals, "machine not allocated")
174
func (s *machineSuite) TestStartMachineForbidden(c *gc.C) {
175
server, machine := s.getServerAndMachine(c)
176
server.AddPostResponse(machine.resourceURI+"?op=deploy", http.StatusForbidden, "machine not yours")
177
err := machine.Start(StartArgs{})
178
c.Assert(err, jc.Satisfies, IsPermissionError)
179
c.Assert(err.Error(), gc.Equals, "machine not yours")
182
func (s *machineSuite) TestStartMachineServiceUnavailable(c *gc.C) {
183
server, machine := s.getServerAndMachine(c)
184
server.AddPostResponse(machine.resourceURI+"?op=deploy", http.StatusServiceUnavailable, "no ip addresses available")
185
err := machine.Start(StartArgs{})
186
c.Assert(err, jc.Satisfies, IsCannotCompleteError)
187
c.Assert(err.Error(), gc.Equals, "no ip addresses available")
190
func (s *machineSuite) TestStartMachineUnknown(c *gc.C) {
191
server, machine := s.getServerAndMachine(c)
192
server.AddPostResponse(machine.resourceURI+"?op=deploy", http.StatusMethodNotAllowed, "wat?")
193
err := machine.Start(StartArgs{})
194
c.Assert(err, jc.Satisfies, IsUnexpectedError)
195
c.Assert(err.Error(), gc.Equals, "unexpected: ServerError: 405 Method Not Allowed (wat?)")
198
func (s *machineSuite) TestDevices(c *gc.C) {
199
server, machine := s.getServerAndMachine(c)
200
server.AddGetResponse("/api/2.0/devices/", http.StatusOK, devicesResponse)
201
devices, err := machine.Devices(DevicesArgs{})
202
c.Assert(err, jc.ErrorIsNil)
203
c.Assert(devices, gc.HasLen, 1)
204
c.Assert(devices[0].Parent(), gc.Equals, machine.SystemID())
207
func (s *machineSuite) TestDevicesNone(c *gc.C) {
208
server, machine := s.getServerAndMachine(c)
209
response := updateJSONMap(c, deviceResponse, map[string]interface{}{
212
server.AddGetResponse("/api/2.0/devices/", http.StatusOK, "["+response+"]")
213
devices, err := machine.Devices(DevicesArgs{})
214
c.Assert(err, jc.ErrorIsNil)
215
c.Assert(devices, gc.HasLen, 0)
218
func (s *machineSuite) TestCreateMachineDeviceArgsValidate(c *gc.C) {
219
for i, test := range []struct {
220
args CreateMachineDeviceArgs
223
errText: "missing InterfaceName not valid",
225
args: CreateMachineDeviceArgs{
226
InterfaceName: "eth1",
228
errText: `missing MACAddress not valid`,
230
args: CreateMachineDeviceArgs{
231
InterfaceName: "eth1",
232
MACAddress: "something",
234
errText: `missing Subnet not valid`,
236
args: CreateMachineDeviceArgs{
237
InterfaceName: "eth1",
238
MACAddress: "something",
239
Subnet: &fakeSubnet{},
242
args: CreateMachineDeviceArgs{
243
Hostname: "is-optional",
244
InterfaceName: "eth1",
245
MACAddress: "something",
246
Subnet: &fakeSubnet{},
250
err := test.args.Validate()
251
if test.errText == "" {
252
c.Check(err, jc.ErrorIsNil)
254
c.Check(err, jc.Satisfies, errors.IsNotValid)
255
c.Check(err.Error(), gc.Equals, test.errText)
260
func (s *machineSuite) TestCreateDeviceValidates(c *gc.C) {
261
_, machine := s.getServerAndMachine(c)
262
_, err := machine.CreateDevice(CreateMachineDeviceArgs{})
263
c.Assert(err, jc.Satisfies, errors.IsNotValid)
264
c.Assert(err.Error(), gc.Equals, "missing InterfaceName not valid")
267
func (s *machineSuite) TestCreateDevice(c *gc.C) {
268
server, machine := s.getServerAndMachine(c)
269
// The createDeviceResponse returns a single interface with the name "eth0".
270
server.AddPostResponse("/api/2.0/devices/?op=", http.StatusOK, createDeviceResponse)
271
updateInterfaceResponse := updateJSONMap(c, interfaceResponse, map[string]interface{}{
273
"links": []interface{}{},
274
"resource_uri": "/MAAS/api/2.0/nodes/4y3haf/interfaces/48/",
276
server.AddPutResponse("/MAAS/api/2.0/nodes/4y3haf/interfaces/48/", http.StatusOK, updateInterfaceResponse)
277
linkSubnetResponse := updateJSONMap(c, interfaceResponse, map[string]interface{}{
279
"resource_uri": "/MAAS/api/2.0/nodes/4y3haf/interfaces/48/",
281
server.AddPostResponse("/MAAS/api/2.0/nodes/4y3haf/interfaces/48/?op=link_subnet", http.StatusOK, linkSubnetResponse)
282
subnet := machine.BootInterface().Links()[0].Subnet()
283
device, err := machine.CreateDevice(CreateMachineDeviceArgs{
284
InterfaceName: "eth4",
285
MACAddress: "fake-mac-address",
288
c.Assert(err, jc.ErrorIsNil)
289
c.Assert(device.InterfaceSet()[0].Name(), gc.Equals, "eth4")
290
c.Assert(device.InterfaceSet()[0].VLAN().ID(), gc.Equals, subnet.VLAN().ID())
293
func (s *machineSuite) TestCreateDeviceTriesToDeleteDeviceOnError(c *gc.C) {
294
server, machine := s.getServerAndMachine(c)
295
// The createDeviceResponse returns a single interface with the name "eth0".
296
server.AddPostResponse("/api/2.0/devices/?op=", http.StatusOK, createDeviceResponse)
297
updateInterfaceResponse := updateJSONMap(c, interfaceResponse, map[string]interface{}{
299
"links": []interface{}{},
300
"resource_uri": "/MAAS/api/2.0/nodes/4y3haf/interfaces/48/",
302
server.AddPutResponse("/MAAS/api/2.0/nodes/4y3haf/interfaces/48/", http.StatusOK, updateInterfaceResponse)
303
server.AddPostResponse("/MAAS/api/2.0/nodes/4y3haf/interfaces/48/?op=link_subnet", http.StatusServiceUnavailable, "no addresses")
304
// We'll ignore that that it fails to delete, all we care about testing is that it tried.
305
subnet := machine.BootInterface().Links()[0].Subnet()
306
_, err := machine.CreateDevice(CreateMachineDeviceArgs{
307
InterfaceName: "eth4",
308
MACAddress: "fake-mac-address",
311
c.Assert(err, jc.Satisfies, IsCannotCompleteError)
313
request := server.LastRequest()
314
c.Assert(request.Method, gc.Equals, "DELETE")
315
c.Assert(request.RequestURI, gc.Equals, "/MAAS/api/2.0/devices/4y3haf/")
322
"system_id": "4y3ha3",
326
"virtualblockdevice_set": [],
329
"hwe_kernel": "hwe-t",
332
"node_type_name": "Machine",
335
"mac_address": "52:54:00:55:b6:80"
338
"special_filesystems": [],
340
"physicalblockdevice_set": [
342
"path": "/dev/disk/by-dname/sda",
344
"used_for": "MBR partitioned with 1 partition",
349
"path": "/dev/disk/by-dname/sda-part1",
354
"mount_options": null,
355
"uuid": "fcd7745e-f1b5-4f5d-9575-9b0bb796b752"
358
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha3/blockdevices/34/partition/1",
359
"uuid": "6199b7c9-b66f-40f6-a238-a938a58a0adf",
360
"used_for": "ext4 formatted filesystem mounted at /",
365
"id_path": "/dev/disk/by-id/ata-QEMU_HARDDISK_QM00001",
366
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha3/blockdevices/34/",
371
"used_size": 8586788864,
373
"partition_table_type": "MBR",
376
"model": "QEMU HARDDISK",
382
"path": "/dev/disk/by-dname/sdb",
384
"used_for": "MBR partitioned with 1 partition",
389
"path": "/dev/disk/by-dname/sdb-part1",
392
"mount_point": "/home",
394
"mount_options": null,
395
"uuid": "fcd7745e-f1b5-4f5d-9575-9b0bb796b753"
398
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha3/blockdevices/98/partition/101",
399
"uuid": "6199b7c9-b66f-40f6-a238-a938a58a0ae0",
400
"used_for": "ext4 formatted filesystem mounted at /home",
405
"id_path": "/dev/disk/by-id/ata-QEMU_HARDDISK_QM00002",
406
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha3/blockdevices/98/",
411
"used_size": 8586788864,
413
"partition_table_type": "MBR",
416
"model": "QEMU HARDDISK",
424
"effective_mtu": 1500,
425
"mac_address": "52:54:00:55:b6:80",
430
"resource_uri": "/MAAS/api/2.0/vlans/1/",
432
"secondary_rack": null,
434
"primary_rack": "4y3h7n",
436
"fabric": "fabric-0",
445
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha3/interfaces/35/",
450
"ip_address": "192.168.100.4",
452
"resource_uri": "/MAAS/api/2.0/subnets/1/",
456
"resource_uri": "/MAAS/api/2.0/vlans/1/",
458
"secondary_rack": null,
460
"primary_rack": "4y3h7n",
462
"fabric": "fabric-0",
468
"name": "192.168.100.0/24",
469
"gateway_ip": "192.168.100.1",
470
"cidr": "192.168.100.0/24"
477
"effective_mtu": 1500,
478
"mac_address": "52:54:00:55:b6:81",
483
"resource_uri": "/MAAS/api/2.0/vlans/1/",
485
"secondary_rack": null,
487
"primary_rack": "4y3h7n",
489
"fabric": "fabric-0",
498
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha3/interfaces/99/",
503
"ip_address": "192.168.100.5",
505
"resource_uri": "/MAAS/api/2.0/subnets/1/",
509
"resource_uri": "/MAAS/api/2.0/vlans/1/",
511
"secondary_rack": null,
513
"primary_rack": "4y3h7n",
515
"fabric": "fabric-0",
521
"name": "192.168.100.0/24",
522
"gateway_ip": "192.168.100.1",
523
"cidr": "192.168.100.0/24"
530
"resource_uri": "/MAAS/api/2.0/machines/4y3ha3/",
531
"hostname": "untasted-markita",
532
"status_name": "Deployed",
533
"min_hwe_kernel": "",
536
"effective_mtu": 1500,
537
"mac_address": "52:54:00:55:b6:80",
542
"resource_uri": "/MAAS/api/2.0/vlans/1/",
544
"secondary_rack": null,
546
"primary_rack": "4y3h7n",
548
"fabric": "fabric-0",
557
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha3/interfaces/35/",
562
"ip_address": "192.168.100.4",
564
"resource_uri": "/MAAS/api/2.0/subnets/1/",
568
"resource_uri": "/MAAS/api/2.0/vlans/1/",
570
"secondary_rack": null,
572
"primary_rack": "4y3h7n",
574
"fabric": "fabric-0",
580
"name": "192.168.100.0/24",
581
"gateway_ip": "192.168.100.1",
582
"cidr": "192.168.100.0/24"
589
"architecture": "amd64/generic",
590
"power_type": "virsh",
591
"distro_series": "trusty",
595
"disable_ipv4": false,
596
"status_message": "From 'Deploying' to 'Deployed'",
600
"path": "/dev/disk/by-dname/sda",
601
"partition_table_type": "MBR",
603
"used_for": "MBR partitioned with 1 partition",
608
"path": "/dev/disk/by-dname/sda-part1",
613
"mount_options": null,
614
"uuid": "fcd7745e-f1b5-4f5d-9575-9b0bb796b752"
617
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha3/blockdevices/34/partition/1",
618
"uuid": "6199b7c9-b66f-40f6-a238-a938a58a0adf",
619
"used_for": "ext4 formatted filesystem mounted at /",
624
"id_path": "/dev/disk/by-id/ata-QEMU_HARDDISK_QM00001",
625
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha3/blockdevices/34/",
630
"used_size": 8586788864,
637
"model": "QEMU HARDDISK"
640
"path": "/dev/disk/by-dname/sdb",
642
"used_for": "MBR partitioned with 1 partition",
647
"path": "/dev/disk/by-dname/sdb-part1",
650
"mount_point": "/home",
652
"mount_options": null,
653
"uuid": "fcd7745e-f1b5-4f5d-9575-9b0bb796b753"
656
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha3/blockdevices/98/partition/101",
657
"uuid": "6199b7c9-b66f-40f6-a238-a938a58a0ae0",
658
"used_for": "ext4 formatted filesystem mounted at /home",
663
"id_path": "/dev/disk/by-id/ata-QEMU_HARDDISK_QM00002",
664
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha3/blockdevices/98/",
669
"used_size": 8586788864,
671
"partition_table_type": "MBR",
674
"model": "QEMU HARDDISK",
682
"resource_uri": "/MAAS/api/2.0/zones/default/",
685
"fqdn": "untasted-markita.maas",
686
"storage": 8589.934592,
693
"resource_uri": "/MAAS/api/2.0/domains/0/",
694
"resource_record_count": 0,
696
"authoritative": true
700
machinesResponse = "[" + machineResponse + `,
703
"system_id": "4y3ha4",
705
"virtualblockdevice_set": [],
711
"node_type_name": "Machine",
714
"mac_address": "52:54:00:33:6b:2c"
717
"special_filesystems": [],
719
"physicalblockdevice_set": [
721
"path": "/dev/disk/by-dname/sda",
723
"used_for": "MBR partitioned with 1 partition",
728
"path": "/dev/disk/by-dname/sda-part1",
733
"mount_options": null,
734
"uuid": "7a0e75a8-0bc6-456b-ac92-4769e97baf02"
737
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha4/blockdevices/35/partition/2",
738
"uuid": "6fe782cf-ad1a-4b31-8beb-333401b4d4bb",
739
"used_for": "ext4 formatted filesystem mounted at /",
744
"id_path": "/dev/disk/by-id/ata-QEMU_HARDDISK_QM00001",
745
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha4/blockdevices/35/",
750
"used_size": 8586788864,
752
"partition_table_type": "MBR",
755
"model": "QEMU HARDDISK",
763
"effective_mtu": 1500,
764
"mac_address": "52:54:00:33:6b:2c",
769
"resource_uri": "/MAAS/api/2.0/vlans/1/",
771
"secondary_rack": null,
773
"primary_rack": "4y3h7n",
775
"fabric": "fabric-0",
784
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha4/interfaces/39/",
791
"resource_uri": "/MAAS/api/2.0/subnets/1/",
795
"resource_uri": "/MAAS/api/2.0/vlans/1/",
797
"secondary_rack": null,
799
"primary_rack": "4y3h7n",
801
"fabric": "fabric-0",
807
"name": "192.168.100.0/24",
808
"gateway_ip": "192.168.100.1",
809
"cidr": "192.168.100.0/24"
815
"resource_uri": "/MAAS/api/2.0/machines/4y3ha4/",
816
"hostname": "lowlier-glady",
817
"status_name": "Ready",
818
"min_hwe_kernel": "",
821
"effective_mtu": 1500,
822
"mac_address": "52:54:00:33:6b:2c",
827
"resource_uri": "/MAAS/api/2.0/vlans/1/",
829
"secondary_rack": null,
831
"primary_rack": "4y3h7n",
833
"fabric": "fabric-0",
842
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha4/interfaces/39/",
849
"resource_uri": "/MAAS/api/2.0/subnets/1/",
853
"resource_uri": "/MAAS/api/2.0/vlans/1/",
855
"secondary_rack": null,
857
"primary_rack": "4y3h7n",
859
"fabric": "fabric-0",
865
"name": "192.168.100.0/24",
866
"gateway_ip": "192.168.100.1",
867
"cidr": "192.168.100.0/24"
872
"power_state": "off",
873
"architecture": "amd64/generic",
874
"power_type": "virsh",
879
"disable_ipv4": false,
880
"status_message": "From 'Commissioning' to 'Ready'",
884
"path": "/dev/disk/by-dname/sda",
885
"partition_table_type": "MBR",
887
"used_for": "MBR partitioned with 1 partition",
892
"path": "/dev/disk/by-dname/sda-part1",
897
"mount_options": null,
898
"uuid": "7a0e75a8-0bc6-456b-ac92-4769e97baf02"
901
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha4/blockdevices/35/partition/2",
902
"uuid": "6fe782cf-ad1a-4b31-8beb-333401b4d4bb",
903
"used_for": "ext4 formatted filesystem mounted at /",
908
"id_path": "/dev/disk/by-id/ata-QEMU_HARDDISK_QM00001",
909
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha4/blockdevices/35/",
914
"used_size": 8586788864,
921
"model": "QEMU HARDDISK"
926
"resource_uri": "/MAAS/api/2.0/zones/default/",
929
"fqdn": "lowlier-glady.maas",
930
"storage": 8589.934592,
937
"resource_uri": "/MAAS/api/2.0/domains/0/",
938
"resource_record_count": 0,
940
"authoritative": true
945
"system_id": "4y3ha6",
947
"virtualblockdevice_set": [],
953
"node_type_name": "Machine",
956
"mac_address": "52:54:00:c9:6a:45"
959
"special_filesystems": [],
961
"physicalblockdevice_set": [
963
"path": "/dev/disk/by-dname/sda",
965
"used_for": "MBR partitioned with 1 partition",
970
"path": "/dev/disk/by-dname/sda-part1",
975
"mount_options": null,
976
"uuid": "f15b4e94-7dc3-460d-8838-0c299905c799"
979
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha6/blockdevices/36/partition/3",
980
"uuid": "a20ae130-bd8f-41b5-bdb3-47ab11a621b5",
981
"used_for": "ext4 formatted filesystem mounted at /",
986
"id_path": "/dev/disk/by-id/ata-QEMU_HARDDISK_QM00001",
987
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha6/blockdevices/36/",
992
"used_size": 8586788864,
994
"partition_table_type": "MBR",
997
"model": "QEMU HARDDISK",
1005
"effective_mtu": 1500,
1006
"mac_address": "52:54:00:c9:6a:45",
1011
"resource_uri": "/MAAS/api/2.0/vlans/1/",
1013
"secondary_rack": null,
1015
"primary_rack": "4y3h7n",
1017
"fabric": "fabric-0",
1026
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha6/interfaces/40/",
1033
"resource_uri": "/MAAS/api/2.0/subnets/1/",
1037
"resource_uri": "/MAAS/api/2.0/vlans/1/",
1039
"secondary_rack": null,
1041
"primary_rack": "4y3h7n",
1043
"fabric": "fabric-0",
1049
"name": "192.168.100.0/24",
1050
"gateway_ip": "192.168.100.1",
1051
"cidr": "192.168.100.0/24"
1057
"resource_uri": "/MAAS/api/2.0/machines/4y3ha6/",
1058
"hostname": "icier-nina",
1059
"status_name": "Ready",
1060
"min_hwe_kernel": "",
1061
"address_ttl": null,
1063
"effective_mtu": 1500,
1064
"mac_address": "52:54:00:c9:6a:45",
1069
"resource_uri": "/MAAS/api/2.0/vlans/1/",
1071
"secondary_rack": null,
1073
"primary_rack": "4y3h7n",
1075
"fabric": "fabric-0",
1084
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha6/interfaces/40/",
1091
"resource_uri": "/MAAS/api/2.0/subnets/1/",
1095
"resource_uri": "/MAAS/api/2.0/vlans/1/",
1097
"secondary_rack": null,
1099
"primary_rack": "4y3h7n",
1101
"fabric": "fabric-0",
1107
"name": "192.168.100.0/24",
1108
"gateway_ip": "192.168.100.1",
1109
"cidr": "192.168.100.0/24"
1114
"power_state": "off",
1115
"architecture": "amd64/generic",
1116
"power_type": "virsh",
1117
"distro_series": "",
1121
"disable_ipv4": false,
1122
"status_message": "From 'Commissioning' to 'Ready'",
1124
"blockdevice_set": [
1126
"path": "/dev/disk/by-dname/sda",
1127
"partition_table_type": "MBR",
1129
"used_for": "MBR partitioned with 1 partition",
1134
"path": "/dev/disk/by-dname/sda-part1",
1139
"mount_options": null,
1140
"uuid": "f15b4e94-7dc3-460d-8838-0c299905c799"
1142
"type": "partition",
1143
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha6/blockdevices/36/partition/3",
1144
"uuid": "a20ae130-bd8f-41b5-bdb3-47ab11a621b5",
1145
"used_for": "ext4 formatted filesystem mounted at /",
1150
"id_path": "/dev/disk/by-id/ata-QEMU_HARDDISK_QM00001",
1151
"resource_uri": "/MAAS/api/2.0/nodes/4y3ha6/blockdevices/36/",
1153
"serial": "QM00001",
1156
"used_size": 8586788864,
1160
"available_size": 0,
1163
"model": "QEMU HARDDISK"
1168
"resource_uri": "/MAAS/api/2.0/zones/default/",
1171
"fqdn": "icier-nina.maas",
1172
"storage": 8589.934592,
1179
"resource_uri": "/MAAS/api/2.0/domains/0/",
1180
"resource_record_count": 0,
1182
"authoritative": true
1188
createDeviceResponse = `
1192
"resource_uri": "/MAAS/api/2.0/zones/default/",
1196
"resource_record_count": 0,
1197
"resource_uri": "/MAAS/api/2.0/domains/0/",
1198
"authoritative": true,
1203
"node_type_name": "Device",
1204
"address_ttl": null,
1205
"hostname": "furnacelike-brittney",
1207
"resource_uri": "/MAAS/api/2.0/devices/4y3haf/",
1208
"ip_addresses": ["192.168.100.11"],
1211
"fqdn": "furnacelike-brittney.maas",
1212
"system_id": "4y3haf",
1216
"resource_uri": "/MAAS/api/2.0/nodes/4y3haf/interfaces/48/",
1218
"mac_address": "78:f0:f1:16:a7:46",
1221
"effective_mtu": 1500,
1227
"secondary_rack": null,
1229
"fabric": "fabric-0",
1231
"primary_rack": "4y3h7n",
1232
"resource_uri": "/MAAS/api/2.0/vlans/1/",
1233
"external_dhcp": null,