261
269
if a.InterfaceName == "" {
262
270
return errors.NotValidf("missing InterfaceName")
264
273
if a.MACAddress == "" {
265
274
return errors.NotValidf("missing MACAddress")
268
return errors.NotValidf("missing Subnet")
277
if a.Subnet != nil && a.VLAN != nil && a.Subnet.VLAN() != a.VLAN {
279
"given subnet %q on VLAN %d does not match given VLAN %d",
280
a.Subnet.CIDR(), a.Subnet.VLAN().ID(), a.VLAN.ID(),
282
return errors.NewNotValid(nil, msg)
284
299
return nil, errors.Trace(err)
302
defer func(err *error) {
288
303
// If there is an error return, at least try to delete the device we just created.
290
305
if innerErr := device.Delete(); innerErr != nil {
291
306
logger.Warningf("could not delete device %q", device.SystemID())
296
// There should be one interface created for each MAC Address, and since
297
// we only specified one, there should just be one response.
311
// Update the VLAN to use for the interface, if given.
312
vlanToUse := args.VLAN
313
if vlanToUse == nil && args.Subnet != nil {
314
vlanToUse = args.Subnet.VLAN()
317
// There should be one interface created for each MAC Address, and since we
318
// only specified one, there should just be one response.
298
319
interfaces := device.InterfaceSet()
299
320
if count := len(interfaces); count != 1 {
300
321
err := errors.Errorf("unexpected interface count for device: %d", count)
301
322
return nil, NewUnexpectedError(err)
303
324
iface := interfaces[0]
305
// Now update the name and vlan of interface that was created…
325
nameToUse := args.InterfaceName
327
if err := m.updateDeviceInterface(iface, nameToUse, vlanToUse); err != nil {
328
return nil, errors.Trace(err)
331
if args.Subnet == nil {
332
// Nothing further to update.
336
if err := m.linkDeviceInterfaceToSubnet(iface, args.Subnet); err != nil {
337
return nil, errors.Trace(err)
343
func (m *machine) updateDeviceInterface(iface Interface, nameToUse string, vlanToUse VLAN) error {
306
344
updateArgs := UpdateInterfaceArgs{}
307
if iface.Name() != args.InterfaceName {
308
updateArgs.Name = args.InterfaceName
310
if iface.VLAN().ID() != args.Subnet.VLAN().ID() {
311
updateArgs.VLAN = args.Subnet.VLAN()
313
err = iface.Update(updateArgs)
315
return nil, errors.Trace(err)
318
err = iface.LinkSubnet(LinkSubnetArgs{
345
updateArgs.Name = nameToUse
347
if vlanToUse != nil {
348
updateArgs.VLAN = vlanToUse
351
if err := iface.Update(updateArgs); err != nil {
352
return errors.Annotatef(err, "updating device interface %q failed", iface.Name())
358
func (m *machine) linkDeviceInterfaceToSubnet(iface Interface, subnetToUse Subnet) error {
359
err := iface.LinkSubnet(LinkSubnetArgs{
319
360
Mode: LinkModeStatic,
323
return nil, errors.Trace(err)
364
return errors.Annotatef(
365
err, "linking device interface %q to subnet %q failed",
366
iface.Name(), subnetToUse.CIDR())
372
// OwnerData implements OwnerDataHolder.
373
func (m *machine) OwnerData() map[string]string {
374
result := make(map[string]string)
375
for key, value := range m.ownerData {
381
// SetOwnerData implements OwnerDataHolder.
382
func (m *machine) SetOwnerData(ownerData map[string]string) error {
383
params := make(url.Values)
384
for key, value := range ownerData {
385
params.Add(key, value)
387
result, err := m.controller.post(m.resourceURI, "set_owner_data", params)
389
return errors.Trace(err)
391
machine, err := readMachine(m.controller.apiVersion, result)
393
return errors.Trace(err)
395
m.updateFrom(machine)
329
399
func readMachine(controllerVersion version.Number, source interface{}) (*machine, error) {
395
465
fields := schema.Fields{
396
466
"resource_uri": schema.String(),
398
"system_id": schema.String(),
399
"hostname": schema.String(),
400
"fqdn": schema.String(),
401
"tag_names": schema.List(schema.String()),
468
"system_id": schema.String(),
469
"hostname": schema.String(),
470
"fqdn": schema.String(),
471
"tag_names": schema.List(schema.String()),
472
"owner_data": schema.StringMap(schema.String()),
403
474
"osystem": schema.String(),
404
475
"distro_series": schema.String(),
459
530
result := &machine{
460
531
resourceURI: valid["resource_uri"].(string),
462
systemID: valid["system_id"].(string),
463
hostname: valid["hostname"].(string),
464
fqdn: valid["fqdn"].(string),
465
tags: convertToStringSlice(valid["tag_names"]),
533
systemID: valid["system_id"].(string),
534
hostname: valid["hostname"].(string),
535
fqdn: valid["fqdn"].(string),
536
tags: convertToStringSlice(valid["tag_names"]),
537
ownerData: convertToStringMap(valid["owner_data"]),
467
539
operatingSystem: valid["osystem"].(string),
468
540
distroSeries: valid["distro_series"].(string),