func (c *client) GetNetworkInterfaces(inst instance.Id, ecfg *environConfig) ([]network.InterfaceInfo, error) { vm, err := c.getVm(string(inst)) if err != nil { return nil, errors.Trace(err) } if vm.Guest == nil { return nil, errors.Errorf("vm guest is not initialized") } res := make([]network.InterfaceInfo, 0) for _, net := range vm.Guest.Net { ipScope := network.ScopeCloudLocal if net.Network == ecfg.externalNetwork() { ipScope = network.ScopePublic } res = append(res, network.InterfaceInfo{ DeviceIndex: net.DeviceConfigId, MACAddress: net.MacAddress, NetworkName: net.Network, Disabled: !net.Connected, ProviderId: network.Id(fmt.Sprintf("net-device%d", net.DeviceConfigId)), ProviderSubnetId: network.Id(net.Network), InterfaceName: fmt.Sprintf("unsupported%d", net.DeviceConfigId), ConfigType: network.ConfigDHCP, Address: network.NewScopedAddress(net.IpAddress[0], ipScope), }) } return res, nil }
func createSubnetInfo(subnetID, spaceID, ipRange uint) network.SubnetInfo { return network.SubnetInfo{ CIDR: fmt.Sprintf("192.168.%d.0/24", ipRange), ProviderId: network.Id(strconv.Itoa(int(subnetID))), SpaceProviderId: network.Id(fmt.Sprintf("%d", spaceID)), } }
func (env *environ) subnetsForSpaceDiscovery(estate *environState) ([]network.SubnetInfo, error) { result := []network.SubnetInfo{{ ProviderId: network.Id("1"), AvailabilityZones: []string{"zone1"}, CIDR: "192.168.1.0/24", }, { ProviderId: network.Id("2"), AvailabilityZones: []string{"zone1"}, CIDR: "192.168.2.0/24", VLANTag: 1, }, { ProviderId: network.Id("3"), AvailabilityZones: []string{"zone1"}, CIDR: "192.168.3.0/24", }, { ProviderId: network.Id("4"), AvailabilityZones: []string{"zone1"}, CIDR: "192.168.4.0/24", }, { ProviderId: network.Id("5"), AvailabilityZones: []string{"zone1"}, CIDR: "192.168.5.0/24", }} estate.ops <- OpSubnets{ Env: env.name, InstanceId: instance.UnknownId, SubnetIds: []network.Id{}, Info: result, } return result, nil }
// addTestingSubnets adds a testing default VPC with 3 subnets in the EC2 test // server: 2 of the subnets are in the "test-available" AZ, the remaining - in // "test-unavailable". Returns a slice with the IDs of the created subnets. func (t *localServerSuite) addTestingSubnets(c *gc.C) []network.Id { vpc := t.srv.ec2srv.AddVPC(amzec2.VPC{ CIDRBlock: "0.1.0.0/16", IsDefault: true, }) results := make([]network.Id, 3) sub1, err := t.srv.ec2srv.AddSubnet(amzec2.Subnet{ VPCId: vpc.Id, CIDRBlock: "0.1.2.0/24", AvailZone: "test-available", DefaultForAZ: true, }) c.Assert(err, jc.ErrorIsNil) results[0] = network.Id(sub1.Id) sub2, err := t.srv.ec2srv.AddSubnet(amzec2.Subnet{ VPCId: vpc.Id, CIDRBlock: "0.1.3.0/24", AvailZone: "test-available", }) c.Assert(err, jc.ErrorIsNil) results[1] = network.Id(sub2.Id) sub3, err := t.srv.ec2srv.AddSubnet(amzec2.Subnet{ VPCId: vpc.Id, CIDRBlock: "0.1.4.0/24", AvailZone: "test-unavailable", DefaultForAZ: true, }) c.Assert(err, jc.ErrorIsNil) results[2] = network.Id(sub3.Id) return results }
func (suite *maas2EnvironSuite) TestSpaces(c *gc.C) { controller := &fakeController{ spaces: []gomaasapi.Space{ fakeSpace{ name: "pepper", id: 1234, }, fakeSpace{ name: "freckles", id: 4567, subnets: []gomaasapi.Subnet{ fakeSubnet{id: 99, vlan: fakeVLAN{vid: 66}, cidr: "192.168.10.0/24"}, fakeSubnet{id: 98, vlan: fakeVLAN{vid: 67}, cidr: "192.168.11.0/24"}, }, }, }, } env := suite.makeEnviron(c, controller) result, err := env.Spaces() c.Assert(err, jc.ErrorIsNil) c.Assert(result, gc.HasLen, 1) c.Assert(result[0].Name, gc.Equals, "freckles") c.Assert(result[0].ProviderId, gc.Equals, network.Id("4567")) subnets := result[0].Subnets c.Assert(subnets, gc.HasLen, 2) c.Assert(subnets[0].ProviderId, gc.Equals, network.Id("99")) c.Assert(subnets[0].VLANTag, gc.Equals, 66) c.Assert(subnets[0].CIDR, gc.Equals, "192.168.10.0/24") c.Assert(subnets[0].SpaceProviderId, gc.Equals, network.Id("4567")) c.Assert(subnets[1].ProviderId, gc.Equals, network.Id("98")) c.Assert(subnets[1].VLANTag, gc.Equals, 67) c.Assert(subnets[1].CIDR, gc.Equals, "192.168.11.0/24") c.Assert(subnets[1].SpaceProviderId, gc.Equals, network.Id("4567")) }
func (env *maasEnviron) deviceInterfaceInfo(deviceID instance.Id, nameToParentName map[string]string) ([]network.InterfaceInfo, error) { interfaces, err := env.deviceInterfaces(deviceID) if err != nil { return nil, errors.Trace(err) } interfaceInfo := make([]network.InterfaceInfo, 0, len(interfaces)) for _, nic := range interfaces { nicInfo := network.InterfaceInfo{ InterfaceName: nic.Name, InterfaceType: network.EthernetInterface, MACAddress: nic.MACAddress, MTU: nic.EffectveMTU, VLANTag: nic.VLAN.VID, ProviderId: network.Id(strconv.Itoa(nic.ID)), ProviderVLANId: network.Id(strconv.Itoa(nic.VLAN.ID)), Disabled: !nic.Enabled, NoAutoStart: !nic.Enabled, ParentInterfaceName: nameToParentName[nic.Name], } if len(nic.Links) == 0 { logger.Debugf("device %q interface %q has no links", deviceID, nic.Name) interfaceInfo = append(interfaceInfo, nicInfo) continue } for _, link := range nic.Links { nicInfo.ConfigType = maasLinkToInterfaceConfigType(string(link.Mode)) if link.IPAddress == "" { logger.Debugf("device %q interface %q has no address", deviceID, nic.Name) interfaceInfo = append(interfaceInfo, nicInfo) continue } if link.Subnet == nil { logger.Debugf("device %q interface %q link %d missing subnet", deviceID, nic.Name, link.ID) interfaceInfo = append(interfaceInfo, nicInfo) continue } nicInfo.CIDR = link.Subnet.CIDR nicInfo.Address = network.NewAddressOnSpace(link.Subnet.Space, link.IPAddress) nicInfo.ProviderSubnetId = network.Id(strconv.Itoa(link.Subnet.ID)) nicInfo.ProviderAddressId = network.Id(strconv.Itoa(link.ID)) if link.Subnet.GatewayIP != "" { nicInfo.GatewayAddress = network.NewAddressOnSpace(link.Subnet.Space, link.Subnet.GatewayIP) } if len(link.Subnet.DNSServers) > 0 { nicInfo.DNSServers = network.NewAddressesOnSpace(link.Subnet.Space, link.Subnet.DNSServers...) } interfaceInfo = append(interfaceInfo, nicInfo) } } logger.Debugf("device %q has interface info: %+v", deviceID, interfaceInfo) return interfaceInfo, nil }
func createSubnetInfo(subnetID, spaceID, ipRange uint) network.SubnetInfo { return network.SubnetInfo{ CIDR: fmt.Sprintf("192.168.%d.0/24", ipRange), ProviderId: network.Id(strconv.Itoa(int(subnetID))), AllocatableIPLow: net.ParseIP(fmt.Sprintf("192.168.%d.139", ipRange)).To4(), AllocatableIPHigh: net.ParseIP(fmt.Sprintf("192.168.%d.255", ipRange)).To4(), SpaceProviderId: network.Id(fmt.Sprintf("Space %d", spaceID)), } }
// Spaces is specified on environs.Networking. func (env *environ) Spaces() ([]network.SpaceInfo, error) { if err := env.checkBroken("Spaces"); err != nil { return []network.SpaceInfo{}, err } return []network.SpaceInfo{{ ProviderId: network.Id("foo"), Subnets: []network.SubnetInfo{{ ProviderId: network.Id("1"), AvailabilityZones: []string{"zone1"}, }, { ProviderId: network.Id("2"), AvailabilityZones: []string{"zone1"}, }}}, { ProviderId: network.Id("Another Foo 99!"), Subnets: []network.SubnetInfo{{ ProviderId: network.Id("3"), AvailabilityZones: []string{"zone1"}, }}}, { ProviderId: network.Id("foo-"), Subnets: []network.SubnetInfo{{ ProviderId: network.Id("4"), AvailabilityZones: []string{"zone1"}, }}}, { ProviderId: network.Id("---"), Subnets: []network.SubnetInfo{{ ProviderId: network.Id("5"), AvailabilityZones: []string{"zone1"}, }}}}, nil }
func (s *ipAddressesInternalSuite) TestProviderIDDoesNotIncludeModelUUIDWhenSet(c *gc.C) { const localProviderID = "foo" globalProviderID := coretesting.ModelTag.Id() + ":" + localProviderID result := s.newIPAddressWithDummyState(ipAddressDoc{ProviderID: localProviderID}) c.Assert(result.ProviderID(), gc.Equals, network.Id(localProviderID)) c.Assert(result.localProviderID(), gc.Equals, localProviderID) result = s.newIPAddressWithDummyState(ipAddressDoc{ProviderID: globalProviderID}) c.Assert(result.ProviderID(), gc.Equals, network.Id(localProviderID)) c.Assert(result.localProviderID(), gc.Equals, localProviderID) }
func (s *interfacesSuite) TestMAASObjectNetworkInterfaces(c *gc.C) { nodeJSON := fmt.Sprintf(`{ "system_id": "foo", "interface_set": %s }`, exampleInterfaceSetJSON) obj := s.testMAASObject.TestServer.NewNode(nodeJSON) subnetsMap := make(map[string]network.Id) subnetsMap["10.250.19.0/24"] = network.Id("3") subnetsMap["192.168.1.0/24"] = network.Id("0") infos, err := maasObjectNetworkInterfaces(&obj, subnetsMap) c.Assert(err, jc.ErrorIsNil) c.Check(infos, jc.DeepEquals, exampleParsedInterfaceSetJSON) }
// prepareOrGetContainerInterfaceInfo returns the necessary information to // configure network interfaces of a container with allocated static // IP addresses. // // TODO(dimitern): Before we start using this, we need to rename both // the method and the network.InterfaceInfo type to be called // InterfaceConfig. func (st *State) prepareOrGetContainerInterfaceInfo( containerTag names.MachineTag, allocateNewAddress bool) ( []network.InterfaceInfo, error) { var result params.MachineNetworkConfigResults args := params.Entities{ Entities: []params.Entity{{Tag: containerTag.String()}}, } facadeName := "" if allocateNewAddress { facadeName = "PrepareContainerInterfaceInfo" } else { facadeName = "GetContainerInterfaceInfo" } if err := st.facade.FacadeCall(facadeName, args, &result); err != nil { return nil, err } if len(result.Results) != 1 { return nil, errors.Errorf("expected 1 result, got %d", len(result.Results)) } if err := result.Results[0].Error; err != nil { return nil, err } ifaceInfo := make([]network.InterfaceInfo, len(result.Results[0].Config)) for i, cfg := range result.Results[0].Config { ifaceInfo[i] = network.InterfaceInfo{ DeviceIndex: cfg.DeviceIndex, MACAddress: cfg.MACAddress, CIDR: cfg.CIDR, MTU: cfg.MTU, ProviderId: network.Id(cfg.ProviderId), ProviderSubnetId: network.Id(cfg.ProviderSubnetId), ProviderSpaceId: network.Id(cfg.ProviderSpaceId), ProviderVLANId: network.Id(cfg.ProviderVLANId), ProviderAddressId: network.Id(cfg.ProviderAddressId), VLANTag: cfg.VLANTag, InterfaceName: cfg.InterfaceName, ParentInterfaceName: cfg.ParentInterfaceName, InterfaceType: network.InterfaceType(cfg.InterfaceType), Disabled: cfg.Disabled, NoAutoStart: cfg.NoAutoStart, ConfigType: network.InterfaceConfigType(cfg.ConfigType), Address: network.NewAddress(cfg.Address), DNSServers: network.NewAddresses(cfg.DNSServers...), DNSSearchDomains: cfg.DNSSearchDomains, GatewayAddress: network.NewAddress(cfg.GatewayAddress), } } return ifaceInfo, nil }
func (i *importer) addLinkLayerDevice(device description.LinkLayerDevice) error { providerID := device.ProviderID() modelUUID := i.st.ModelUUID() localID := linkLayerDeviceGlobalKey(device.MachineID(), device.Name()) linkLayerDeviceDocID := i.st.docID(localID) newDoc := &linkLayerDeviceDoc{ ModelUUID: modelUUID, DocID: linkLayerDeviceDocID, MachineID: device.MachineID(), ProviderID: providerID, Name: device.Name(), MTU: device.MTU(), Type: LinkLayerDeviceType(device.Type()), MACAddress: device.MACAddress(), IsAutoStart: device.IsAutoStart(), IsUp: device.IsUp(), ParentName: device.ParentName(), } ops := []txn.Op{{ C: linkLayerDevicesC, Id: newDoc.DocID, Insert: newDoc, }, insertLinkLayerDevicesRefsOp(modelUUID, linkLayerDeviceDocID), } if providerID != "" { id := network.Id(providerID) ops = append(ops, i.st.networkEntityGlobalKeyOp("linklayerdevice", id)) } if err := i.st.runTransaction(ops); err != nil { return errors.Trace(err) } return nil }
func (c *client) Subnets(inst instance.Id, ids []network.Id) ([]network.SubnetInfo, error) { if len(ids) == 0 { return nil, errors.Errorf("subnetIds must not be empty") } vm, err := c.getVm(string(inst)) if err != nil { return nil, errors.Trace(err) } res := make([]network.SubnetInfo, 0) for _, vmNet := range vm.Guest.Net { existId := false for _, id := range ids { if string(id) == vmNet.Network { existId = true break } } if !existId { continue } res = append(res, network.SubnetInfo{ ProviderId: network.Id(vmNet.Network), }) } return res, nil }
// setupNetworks prepares a []network.InterfaceInfo for the given instance. Any // disabled network interfaces (as discovered from the lshw output for the node) // will stay disabled. func (environ *maasEnviron) setupNetworks(inst instance.Instance) ([]network.InterfaceInfo, error) { // Get the instance network interfaces first. interfaces, err := environ.getInstanceNetworkInterfaces(inst) if err != nil { return nil, errors.Annotatef(err, "getInstanceNetworkInterfaces failed") } logger.Debugf("node %q has network interfaces %v", inst.Id(), interfaces) networks, err := environ.getInstanceNetworks(inst) if err != nil { return nil, errors.Annotatef(err, "getInstanceNetworks failed") } logger.Debugf("node %q has networks %v", inst.Id(), networks) var tempInterfaceInfo []network.InterfaceInfo for _, netw := range networks { netCIDR := &net.IPNet{ IP: net.ParseIP(netw.IP), Mask: net.IPMask(net.ParseIP(netw.Mask)), } macs, err := environ.getNetworkMACs(netw.Name) if err != nil { return nil, errors.Annotatef(err, "getNetworkMACs failed") } logger.Debugf("network %q has MACs: %v", netw.Name, macs) var defaultGateway network.Address if netw.DefaultGateway != "" { defaultGateway = network.NewAddress(netw.DefaultGateway) } for _, mac := range macs { if ifinfo, ok := interfaces[mac]; ok { tempInterfaceInfo = append(tempInterfaceInfo, network.InterfaceInfo{ MACAddress: mac, InterfaceName: ifinfo.InterfaceName, DeviceIndex: ifinfo.DeviceIndex, CIDR: netCIDR.String(), VLANTag: netw.VLANTag, ProviderId: network.Id(netw.Name), NetworkName: netw.Name, Disabled: ifinfo.Disabled, GatewayAddress: defaultGateway, }) } } } // Verify we filled-in everything for all networks/interfaces // and drop incomplete records. var interfaceInfo []network.InterfaceInfo for _, info := range tempInterfaceInfo { if info.ProviderId == "" || info.NetworkName == "" || info.CIDR == "" { logger.Infof("ignoring interface %q: missing subnet info", info.InterfaceName) continue } if info.MACAddress == "" || info.InterfaceName == "" { logger.Infof("ignoring subnet %q: missing interface info", info.ProviderId) continue } interfaceInfo = append(interfaceInfo, info) } logger.Debugf("node %q network information: %#v", inst.Id(), interfaceInfo) return interfaceInfo, nil }
func networkParamsToStateParams(networks []params.Network, ifaces []params.NetworkInterface) ( []state.NetworkInfo, []state.NetworkInterfaceInfo, error, ) { stateNetworks := make([]state.NetworkInfo, len(networks)) for i, net := range networks { tag, err := names.ParseNetworkTag(net.Tag) if err != nil { return nil, nil, err } stateNetworks[i] = state.NetworkInfo{ Name: tag.Id(), ProviderId: network.Id(net.ProviderId), CIDR: net.CIDR, VLANTag: net.VLANTag, } } stateInterfaces := make([]state.NetworkInterfaceInfo, len(ifaces)) for i, iface := range ifaces { tag, err := names.ParseNetworkTag(iface.NetworkTag) if err != nil { return nil, nil, err } stateInterfaces[i] = state.NetworkInterfaceInfo{ MACAddress: iface.MACAddress, NetworkName: tag.Id(), InterfaceName: iface.InterfaceName, IsVirtual: iface.IsVirtual, Disabled: iface.Disabled, } } return stateNetworks, stateInterfaces, nil }
func constructStartInstanceParams( machine *apiprovisioner.Machine, instanceConfig *instancecfg.InstanceConfig, provisioningInfo *params.ProvisioningInfo, possibleTools coretools.List, ) (environs.StartInstanceParams, error) { volumes := make([]storage.VolumeParams, len(provisioningInfo.Volumes)) for i, v := range provisioningInfo.Volumes { volumeTag, err := names.ParseVolumeTag(v.VolumeTag) if err != nil { return environs.StartInstanceParams{}, errors.Trace(err) } if v.Attachment == nil { return environs.StartInstanceParams{}, errors.Errorf("volume params missing attachment") } machineTag, err := names.ParseMachineTag(v.Attachment.MachineTag) if err != nil { return environs.StartInstanceParams{}, errors.Trace(err) } if machineTag != machine.Tag() { return environs.StartInstanceParams{}, errors.Errorf("volume attachment params has invalid machine tag") } if v.Attachment.InstanceId != "" { return environs.StartInstanceParams{}, errors.Errorf("volume attachment params specifies instance ID") } volumes[i] = storage.VolumeParams{ volumeTag, v.Size, storage.ProviderType(v.Provider), v.Attributes, v.Tags, &storage.VolumeAttachmentParams{ AttachmentParams: storage.AttachmentParams{ Machine: machineTag, ReadOnly: v.Attachment.ReadOnly, }, Volume: volumeTag, }, } } var subnetsToZones map[network.Id][]string if provisioningInfo.SubnetsToZones != nil { // Convert subnet provider ids from string to network.Id. subnetsToZones = make(map[network.Id][]string, len(provisioningInfo.SubnetsToZones)) for providerId, zones := range provisioningInfo.SubnetsToZones { subnetsToZones[network.Id(providerId)] = zones } } return environs.StartInstanceParams{ Constraints: provisioningInfo.Constraints, Tools: possibleTools, InstanceConfig: instanceConfig, Placement: provisioningInfo.Placement, DistributionGroup: machine.DistributionGroup, Volumes: volumes, SubnetsToZones: subnetsToZones, }, nil }
// AddSubnetsWithTemplate adds numSubnets subnets, using the given // infoTemplate. Any string field in the infoTemplate can be specified // as a text/template string containing {{.}}, which is the current // index of the subnet-to-add (between 0 and numSubnets-1). // // Example: // // AddSubnetsWithTemplate(c, st, 2, state.SubnetInfo{ // CIDR: "10.10.{{.}}.0/24", // ProviderId: "subnet-{{.}}", // SpaceName: "space1", // AvailabilityZone: "zone-{{.}}", // AllocatableIPLow: "{{if (gt . 0)}}10.10.{{.}}.5{{end}}", // AllocatableIPHigh: "{{if (gt . 0)}}10.10.{{.}}.254{{end}}", // VLANTag: 42, // }) // // This is equivalent to the following calls: // // _, err := st.AddSubnet(state.SubnetInfo{ // CIDR: "10.10.0.0/24", // ProviderId: "subnet-0", // SpaceName: "space1", // AvailabilityZone: "zone-0", // VLANTag: 42, // }) // c.Assert(err, jc.ErrorIsNil) // _, err = st.AddSubnet(state.SubnetInfo{ // CIDR: "10.10.1.0/24", // ProviderId: "subnet-1", // SpaceName: "space1", // AvailabilityZone: "zone-1", // AllocatableIPLow: "10.10.1.5", // AllocatableIPHigh: "10.10.1.254", // VLANTag: 42, // }) func AddSubnetsWithTemplate(c *gc.C, st *state.State, numSubnets uint, infoTemplate state.SubnetInfo) { for subnetIndex := 0; subnetIndex < int(numSubnets); subnetIndex++ { info := infoTemplate // make a copy each time. // permute replaces the contents of *s with the result of interpreting // *s as a template. permute := func(s string) string { t, err := template.New("").Parse(s) c.Assert(err, jc.ErrorIsNil) var buf bytes.Buffer err = t.Execute(&buf, subnetIndex) c.Assert(err, jc.ErrorIsNil) return buf.String() } info.ProviderId = network.Id(permute(string(info.ProviderId))) info.CIDR = permute(info.CIDR) info.AllocatableIPHigh = permute(info.AllocatableIPHigh) info.AllocatableIPLow = permute(info.AllocatableIPLow) info.AvailabilityZone = permute(info.AvailabilityZone) info.SpaceName = permute(info.SpaceName) _, err := st.AddSubnet(info) c.Assert(err, jc.ErrorIsNil) } }
// Run implements Command.Run. func (c *addCommand) Run(ctx *cmd.Context) error { return c.RunWithAPI(ctx, func(api SubnetAPI, ctx *cmd.Context) error { if c.CIDR.Id() != "" && c.RawCIDR != c.CIDR.Id() { ctx.Infof( "WARNING: using CIDR %q instead of the incorrectly specified %q.", c.CIDR.Id(), c.RawCIDR, ) } // Add the existing subnet. err := api.AddSubnet(c.CIDR, network.Id(c.ProviderId), c.Space, c.Zones) // TODO(dimitern): Change this once the API returns a concrete error. if err != nil && strings.Contains(err.Error(), "multiple subnets with") { // Special case: multiple subnets with the same CIDR exist ctx.Infof("ERROR: %v.", err) return nil } else if err != nil { return errors.Annotatef(err, "cannot add subnet") } if c.ProviderId != "" { ctx.Infof("added subnet with ProviderId %q in space %q", c.ProviderId, c.Space.Id()) } else { ctx.Infof("added subnet with CIDR %q in space %q", c.CIDR.Id(), c.Space.Id()) } return nil }) }
func (s *suite) TestAllocateAddress(c *gc.C) { e := s.bootstrapTestEnviron(c, false) defer func() { err := e.Destroy() c.Assert(err, gc.IsNil) }() inst, _ := jujutesting.AssertStartInstance(c, e, "0") c.Assert(inst, gc.NotNil) netId := network.Id("net1") opc := make(chan dummy.Operation, 200) dummy.Listen(opc) expectAddress := network.NewAddress("0.1.2.1", network.ScopeCloudLocal) address, err := e.AllocateAddress(inst.Id(), netId) c.Assert(err, gc.IsNil) c.Assert(address, gc.DeepEquals, expectAddress) assertAllocateAddress(c, e, opc, inst.Id(), netId, expectAddress) expectAddress = network.NewAddress("0.1.2.2", network.ScopeCloudLocal) address, err = e.AllocateAddress(inst.Id(), netId) c.Assert(err, gc.IsNil) c.Assert(address, gc.DeepEquals, expectAddress) assertAllocateAddress(c, e, opc, inst.Id(), netId, expectAddress) }
func (t *localServerSuite) TestNetworkInterfaces(c *gc.C) { env, instId := t.setUpInstanceWithDefaultVpc(c) interfaces, err := env.NetworkInterfaces(instId) c.Assert(err, jc.ErrorIsNil) // The CIDR isn't predictable, but it is in the 10.10.x.0/24 format // The subnet ID is in the form "subnet-x", where x matches the same // number from the CIDR. The interfaces address is part of the CIDR. // For these reasons we check that the CIDR is in the expected format // and derive the expected values for ProviderSubnetId and Address. c.Assert(interfaces, gc.HasLen, 1) cidr := interfaces[0].CIDR re := regexp.MustCompile(`10\.10\.(\d+)\.0/24`) c.Assert(re.Match([]byte(cidr)), jc.IsTrue) index := re.FindStringSubmatch(cidr)[1] addr := fmt.Sprintf("10.10.%s.5", index) subnetId := network.Id("subnet-" + index) expectedInterfaces := []network.InterfaceInfo{{ DeviceIndex: 0, MACAddress: "20:01:60:cb:27:37", CIDR: cidr, ProviderId: "eni-0", ProviderSubnetId: subnetId, VLANTag: 0, InterfaceName: "unsupported0", Disabled: false, NoAutoStart: false, ConfigType: network.ConfigDHCP, Address: network.NewScopedAddress(addr, network.ScopeCloudLocal), }} c.Assert(interfaces, jc.DeepEquals, expectedInterfaces) }
func (s *AddressSuite) TestNewAddressesOnSpace(c *gc.C) { addrs := network.NewAddressesOnSpace("bar", "0.2.3.4", "fc00::1") c.Check(addrs, jc.DeepEquals, []network.Address{{ Value: "0.2.3.4", Type: "ipv4", Scope: "public", SpaceName: "bar", SpaceProviderId: network.Id(""), }, { Value: "fc00::1", Type: "ipv6", Scope: "local-cloud", SpaceName: "bar", SpaceProviderId: network.Id(""), }}) }
func (s *ipAddressesStateSuite) testMachineSetDevicesAddressesIdempotently(c *gc.C) { err := s.machine.SetParentLinkLayerDevicesBeforeTheirChildren(nestedDevicesArgs) c.Assert(err, jc.ErrorIsNil) args := []state.LinkLayerDeviceAddress{{ DeviceName: "lo", CIDRAddress: "127.0.0.1/8", ConfigMethod: state.LoopbackAddress, }, { DeviceName: "br-bond0", CIDRAddress: "10.20.0.100/16", ConfigMethod: state.StaticAddress, ProviderID: "200", }, { DeviceName: "br-bond0.12", CIDRAddress: "0.1.2.112/24", ConfigMethod: state.StaticAddress, ProviderID: "201", }, { DeviceName: "br-bond0.34", CIDRAddress: "0.1.2.134/24", ConfigMethod: state.StaticAddress, ProviderID: "202", }} err = s.machine.SetDevicesAddressesIdempotently(args) c.Assert(err, jc.ErrorIsNil) allAddresses, err := s.machine.AllAddresses() c.Assert(err, jc.ErrorIsNil) c.Assert(allAddresses, gc.HasLen, len(args)) for _, address := range allAddresses { if address.ConfigMethod() != state.LoopbackAddress && address.ConfigMethod() != state.ManualAddress { c.Check(address.ProviderID(), gc.Not(gc.Equals), network.Id("")) } } }
func (suite *environSuite) TestSubnetsWithInstanceIdAndSubnetIds(c *gc.C) { server := suite.testMAASObject.TestServer var subnetIDs []network.Id var uintIDs []uint for _, i := range []uint{1, 2, 3} { server.NewSpace(spaceJSON(gomaasapi.CreateSpace{Name: fmt.Sprintf("space-%d", i)})) id := suite.addSubnet(c, i, i, "node1") subnetIDs = append(subnetIDs, network.Id(fmt.Sprintf("%v", id))) uintIDs = append(uintIDs, id) suite.addSubnet(c, i+5, i, "node2") suite.addSubnet(c, i+10, i, "") // not linked to a node } testInstance := suite.getInstance("node1") env := suite.makeEnviron() subnetsInfo, err := env.Subnets(testInstance.Id(), subnetIDs) c.Assert(err, jc.ErrorIsNil) expectedInfo := []network.SubnetInfo{ createSubnetInfo(uintIDs[0], 2, 1), createSubnetInfo(uintIDs[1], 3, 2), createSubnetInfo(uintIDs[2], 4, 3), } c.Assert(subnetsInfo, jc.DeepEquals, expectedInfo) subnetsInfo, err = env.Subnets(testInstance.Id(), subnetIDs[1:]) c.Assert(err, jc.ErrorIsNil) c.Assert(subnetsInfo, jc.DeepEquals, expectedInfo[1:]) }
func (s *SpacesSuite) TestAddSpaceWithNonEmptyProviderIdAndInvalidNameFails(c *gc.C) { args := addSpaceArgs{ Name: "-bad name-", ProviderId: network.Id("My Provider ID"), } _, err := s.addSpaceWithSubnets(c, args) s.assertInvalidSpaceNameErrorAndWasNotAdded(c, err, args.Name) }
func (s *SpacesSuite) TestAddSpaceWithEmptyNameAndNonEmptyProviderIdFails(c *gc.C) { args := addSpaceArgs{ Name: "", ProviderId: network.Id("doesn't matter"), } _, err := s.addSpaceWithSubnets(c, args) s.assertInvalidSpaceNameErrorAndWasNotAdded(c, err, args.Name) }
func (suite *environSuite) TestSubnetsNoInstanceIdWithSubnetIds(c *gc.C) { suite.createTwoSpaces() id1 := suite.addSubnet(c, 1, 1, "node1") id2 := suite.addSubnet(c, 2, 2, "node2") subnetIDs := []network.Id{ network.Id(fmt.Sprintf("%v", id1)), network.Id(fmt.Sprintf("%v", id2)), } subnetsInfo, err := suite.makeEnviron().Subnets(instance.UnknownId, subnetIDs) c.Assert(err, jc.ErrorIsNil) expectedInfo := []network.SubnetInfo{ createSubnetInfo(id1, 2, 1), createSubnetInfo(id2, 3, 2), } c.Assert(subnetsInfo, jc.DeepEquals, expectedInfo) }
// NetworkInterfaces implements Environ.NetworkInterfaces(). func (env *environ) NetworkInterfaces(instId instance.Id) ([]network.InterfaceInfo, error) { if err := env.checkBroken("NetworkInterfaces"); err != nil { return nil, err } estate, err := env.state() if err != nil { return nil, err } estate.mu.Lock() defer estate.mu.Unlock() // Simulate 3 NICs - primary and secondary enabled plus a disabled NIC. // all configured using DHCP and having fake DNS servers and gateway. info := make([]network.InterfaceInfo, 3) for i, netName := range []string{"private", "public", "disabled"} { info[i] = network.InterfaceInfo{ DeviceIndex: i, ProviderId: network.Id(fmt.Sprintf("dummy-eth%d", i)), ProviderSubnetId: network.Id("dummy-" + netName), InterfaceType: network.EthernetInterface, CIDR: fmt.Sprintf("0.%d.0.0/24", (i+1)*10), InterfaceName: fmt.Sprintf("eth%d", i), VLANTag: i, MACAddress: fmt.Sprintf("aa:bb:cc:dd:ee:f%d", i), Disabled: i == 2, NoAutoStart: i%2 != 0, ConfigType: network.ConfigDHCP, Address: network.NewAddress( fmt.Sprintf("0.%d.0.%d", (i+1)*10, estate.maxAddr+2), ), DNSServers: network.NewAddresses("ns1.dummy", "ns2.dummy"), GatewayAddress: network.NewAddress( fmt.Sprintf("0.%d.0.1", (i+1)*10), ), } } estate.ops <- OpNetworkInterfaces{ Env: env.name, InstanceId: instId, Info: info, } return info, nil }
func (s *SpacesSuite) TestAddTwoSpacesWithSameNamesAndProviderIdsFailsInTheSameModel(c *gc.C) { args := addSpaceArgs{ Name: "my-space", ProviderId: network.Id("does not matter if not empty"), } _, err := s.addTwoSpacesReturnSecond(c, args, args) s.assertSpaceAlreadyExistsErrorForArgs(c, err, args) }
func (m *Machine) setDevicesAddressesFromDocsOps(newDocs []ipAddressDoc) ([]txn.Op, error) { addresses, closer := m.st.getCollection(ipAddressesC) defer closer() var ops []txn.Op for _, newDoc := range newDocs { deviceDocID := m.linkLayerDeviceDocIDFromName(newDoc.DeviceName) ops = append(ops, assertLinkLayerDeviceExistsOp(deviceDocID)) var existingDoc ipAddressDoc err := addresses.FindId(newDoc.DocID).One(&existingDoc) if err == mgo.ErrNotFound { // Address does not exist yet - insert it. ops = append(ops, insertIPAddressDocOp(&newDoc)) if newDoc.ProviderID != "" { id := network.Id(newDoc.ProviderID) ops = append(ops, m.st.networkEntityGlobalKeyOp("address", id)) } } else if err == nil { // Address already exists - update what's possible. ops = append(ops, updateIPAddressDocOp(&existingDoc, &newDoc)) if newDoc.ProviderID != "" { if existingDoc.ProviderID != "" && existingDoc.ProviderID != newDoc.ProviderID { return nil, errors.Errorf("cannot change ProviderID of link address %q", existingDoc.Value) } if existingDoc.ProviderID != newDoc.ProviderID { // Need to insert the new provider id in providerIDsC id := network.Id(newDoc.ProviderID) ops = append(ops, m.st.networkEntityGlobalKeyOp("address", id)) } } } else { return nil, errors.Trace(err) } ops, err = m.maybeAssertSubnetAliveOps(&newDoc, ops) if err != nil { return nil, errors.Trace(err) } } return ops, nil }
func (s *SpacesSuite) TestAddSpaceWithMultipleIPv4AndIPv6SubnetsAndNonEmptyProviderId(c *gc.C) { args := addSpaceArgs{ Name: "my-space", ProviderId: network.Id("My Provider ID"), SubnetCIDRs: []string{"fc00:123::/64", "2.2.2.0/20", "fc00:321::/64", "1.1.1.0/24"}, } space, err := s.addSpaceWithSubnets(c, args) c.Assert(err, jc.ErrorIsNil) s.assertSpaceMatchesArgs(c, space, args) }