lxd/maas/controller.go
func (c *Controller) UpdateContainer(name string, interfaces []ContainerInterface) error {
	// Parse the provided interfaces
	macInterfaces, err := parseInterfaces(interfaces)
	if err != nil {
		return err
	}

	// Get all the subnets
	subnets, err := c.getSubnets()
	if err != nil {
		return err
	}

	device, err := c.getDevice(name)
	if err != nil {
		return err
	}

	// Iterate over existing interfaces, drop all removed ones and update existing ones
	existingInterfaces := map[string]gomaasapi.Interface{}
	for _, entry := range device.InterfaceSet() {
		// Check if the interface has been removed from the container
		iface, ok := macInterfaces[entry.MACAddress()]
		if !ok {
			// Delete the interface in MAAS
			err = entry.Delete()
			if err != nil {
				return err
			}

			continue
		}

		// Update the subnets
		existingSubnets := map[string]gomaasapi.Subnet{}
		for _, link := range entry.Links() {
			// Check if the MAAS subnet matches any of the container's
			found := false
			for _, subnet := range iface.Subnets {
				if subnet.Name == link.Subnet().Name() {
					if subnet.Address == "" || subnet.Address == link.IPAddress() {
						found = true
					}
					break
				}
			}

			// If no exact match could be found, remove it from MAAS
			if !found {
				err = entry.UnlinkSubnet(link.Subnet())
				if err != nil {
					return err
				}

				continue
			}

			// Record the existing up to date subnet
			existingSubnets[link.Subnet().Name()] = link.Subnet()
		}

		// Add any missing (or updated) subnet to MAAS
		for _, subnet := range iface.Subnets {
			// Check that it's not configured yet
			_, ok := existingSubnets[subnet.Name]
			if ok {
				continue
			}

			// Add the link
			err := entry.LinkSubnet(gomaasapi.LinkSubnetArgs{
				Mode:      gomaasapi.LinkModeStatic,
				Subnet:    subnets[subnet.Name],
				IPAddress: subnet.Address,
			})
			if err != nil {
				return err
			}
		}

		// Record the interface has being configured
		existingInterfaces[entry.MACAddress()] = entry
	}

	// Iterate over expected interfaces, add any missing one
	for _, iface := range macInterfaces {
		_, ok := existingInterfaces[iface.MACAddress]
		if ok {
			// We already have it so just move on
			continue
		}

		// Create the new interface
		entry, err := device.CreateInterface(gomaasapi.CreateInterfaceArgs{
			Name:       iface.Name,
			MACAddress: iface.MACAddress,
			VLAN:       subnets[iface.Subnets[0].Name].VLAN(),
		})
		if err != nil {
			return err
		}

		// Add the subnets
		for _, subnet := range iface.Subnets {
			err := entry.LinkSubnet(gomaasapi.LinkSubnetArgs{
				Mode:      gomaasapi.LinkModeStatic,
				Subnet:    subnets[subnet.Name],
				IPAddress: subnet.Address,
			})
			if err != nil {
				return err
			}
		}
	}

	return nil
}
func (c *Controller) UpdateContainer(name string, interfaces []ContainerInterface) error {
	// Parse the provided interfaces
	macInterfaces, err := parseInterfaces(interfaces)
	if err != nil {
		return err
	}

	// Get all the subnets
	subnets, err := c.getSubnets()
	if err != nil {
		return err
	}

	device, err := c.getDevice(name)
	if err != nil {
		return err
	}

	// Iterate over existing interfaces, drop all removed ones and update existing ones
	existingInterfaces := map[string]gomaasapi.Interface{}
	for _, entry := range device.InterfaceSet() {
		// Check if the interface has been removed from the container
		iface, ok := macInterfaces[entry.MACAddress()]
		if !ok {
			// Delete the interface in MAAS
			err = entry.Delete()
			if err != nil {
				return err
			}

			continue
		}

		// Update the subnets
		existingSubnets := map[string]gomaasapi.Subnet{}
		for _, link := range entry.Links() {
			// Check if the MAAS subnet matches any of the container's
			found := false
			for _, subnet := range iface.Subnets {
				if subnet.Name == link.Subnet().Name() {
					if subnet.Address == "" || subnet.Address == link.IPAddress() {
						found = true
					}
					break
				}
			}

			// If no exact match could be found, remove it from MAAS
			if !found {
				err = entry.UnlinkSubnet(link.Subnet())
				if err != nil {
					return err
				}

				continue
			}

			// Record the existing up to date subnet
			existingSubnets[link.Subnet().Name()] = link.Subnet()
		}

		// Add any missing (or updated) subnet to MAAS
		for _, subnet := range iface.Subnets {
			// Check that it's not configured yet
			_, ok := existingSubnets[subnet.Name]
			if ok {
				continue
			}

			// Add the link
			err := entry.LinkSubnet(gomaasapi.LinkSubnetArgs{
				Mode:      gomaasapi.LinkModeStatic,
				Subnet:    subnets[subnet.Name],
				IPAddress: subnet.Address,
			})
			if err != nil {
				return err
			}
		}

		// Record the interface has being configured
		existingInterfaces[entry.MACAddress()] = entry
	}

	// Iterate over expected interfaces, add any missing one
	for _, iface := range macInterfaces {
		_, ok := existingInterfaces[iface.MACAddress]
		if ok {
			// We already have it so just move on
			continue
		}

		// Create the new interface
		entry, err := device.CreateInterface(gomaasapi.CreateInterfaceArgs{
			Name:       iface.Name,
			MACAddress: iface.MACAddress,
			VLAN:       subnets[iface.Subnets[0].Name].VLAN(),
		})
		if err != nil {
			return err
		}

		// Add the subnets
		for _, subnet := range iface.Subnets {
			err := entry.LinkSubnet(gomaasapi.LinkSubnetArgs{
				Mode:      gomaasapi.LinkModeStatic,
				Subnet:    subnets[subnet.Name],
				IPAddress: subnet.Address,
			})
			if err != nil {
				return err
			}
		}
	}

	return nil
}
// UpdateContainer updates the MAAS device's interfaces with the new provided state