func (s *SpacesSuite) checkAddSpaces(c *gc.C, p checkAddSpacesParams) { args := params.CreateSpaceParams{} if p.Name != "" { args.SpaceTag = "space-" + p.Name } if len(p.Subnets) > 0 { for _, cidr := range p.Subnets { args.SubnetTags = append(args.SubnetTags, "subnet-"+cidr) } } args.Public = p.Public spaces := params.CreateSpacesParams{} spaces.Spaces = append(spaces.Spaces, args) results, err := s.facade.CreateSpaces(spaces) c.Assert(len(results.Results), gc.Equals, 1) c.Assert(err, gc.IsNil) if p.Error == "" { c.Assert(results.Results[0].Error, gc.IsNil) } else { c.Assert(results.Results[0].Error, gc.NotNil) c.Assert(results.Results[0].Error, gc.ErrorMatches, p.Error) } if p.Error == "" || p.MakesCall { apiservertesting.CheckMethodCalls(c, apiservertesting.SharedStub, apiservertesting.BackingCall("AddSpace", p.Name, p.Subnets, p.Public), ) } else { apiservertesting.CheckMethodCalls(c, apiservertesting.SharedStub) } }
func (s *SpacesSuite) checkCreateSpaces(c *gc.C, p checkCreateSpacesParams) { args := params.CreateSpaceParams{} if p.Name != "" { args.SpaceTag = "space-" + p.Name } if len(p.Subnets) > 0 { for _, cidr := range p.Subnets { args.SubnetTags = append(args.SubnetTags, "subnet-"+cidr) } } args.Public = p.Public args.ProviderId = p.ProviderId spaces := params.CreateSpacesParams{} spaces.Spaces = append(spaces.Spaces, args) results, err := networkingcommon.CreateSpaces(apiservertesting.BackingInstance, spaces) c.Assert(len(results.Results), gc.Equals, 1) c.Assert(err, gc.IsNil) if p.Error == "" { c.Assert(results.Results[0].Error, gc.IsNil) } else { c.Assert(results.Results[0].Error, gc.NotNil) c.Assert(results.Results[0].Error, gc.ErrorMatches, p.Error) } baseCalls := []apiservertesting.StubMethodCall{ apiservertesting.BackingCall("ModelConfig"), apiservertesting.BackingCall("CloudSpec"), apiservertesting.ProviderCall("Open", apiservertesting.BackingInstance.EnvConfig), apiservertesting.ZonedNetworkingEnvironCall("SupportsSpaces"), } addSpaceCalls := append(baseCalls, apiservertesting.BackingCall("AddSpace", p.Name, network.Id(p.ProviderId), p.Subnets, p.Public)) if p.Error == "" { apiservertesting.CheckMethodCalls(c, apiservertesting.SharedStub, addSpaceCalls...) } else { apiservertesting.CheckMethodCalls(c, apiservertesting.SharedStub, baseCalls...) } }
func (dw *discoverspacesWorker) handleSubnets() error { environ, ok := environs.SupportsNetworking(dw.config.Environ) if !ok { logger.Debugf("not a networking environ") return nil } if supported, err := environ.SupportsSpaceDiscovery(); err != nil { return errors.Trace(err) } else if !supported { logger.Debugf("environ does not support space discovery") return nil } providerSpaces, err := environ.Spaces() if err != nil { return errors.Trace(err) } facade := dw.config.Facade listSpacesResult, err := facade.ListSpaces() if err != nil { return errors.Trace(err) } stateSubnets, err := facade.ListSubnets(params.SubnetsFilters{}) if err != nil { return errors.Trace(err) } stateSubnetIds := make(set.Strings) for _, subnet := range stateSubnets.Results { stateSubnetIds.Add(subnet.ProviderId) } stateSpaceMap := make(map[string]params.ProviderSpace) spaceNames := make(set.Strings) for _, space := range listSpacesResult.Results { stateSpaceMap[space.ProviderId] = space spaceNames.Add(space.Name) } // TODO(mfoord): we need to delete spaces and subnets that no longer // exist, so long as they're not in use. var createSpacesArgs params.CreateSpacesParams var addSubnetsArgs params.AddSubnetsParams for _, space := range providerSpaces { // Check if the space is already in state, in which case we know // its name. stateSpace, ok := stateSpaceMap[string(space.ProviderId)] var spaceTag names.SpaceTag if ok { spaceName := stateSpace.Name if !names.IsValidSpace(spaceName) { // Can only happen if an invalid name is stored // in state. logger.Errorf("space %q has an invalid name, ignoring", spaceName) continue } spaceTag = names.NewSpaceTag(spaceName) } else { // The space is new, we need to create a valid name for it // in state. spaceName := string(space.Name) // Convert the name into a valid name that isn't already in // use. spaceName = dw.config.NewName(spaceName, spaceNames) spaceNames.Add(spaceName) spaceTag = names.NewSpaceTag(spaceName) // We need to create the space. createSpacesArgs.Spaces = append(createSpacesArgs.Spaces, params.CreateSpaceParams{ Public: false, SpaceTag: spaceTag.String(), ProviderId: string(space.ProviderId), }) } // TODO(mfoord): currently no way of removing subnets, or // changing the space they're in, so we can only add ones we // don't already know about. for _, subnet := range space.Subnets { if stateSubnetIds.Contains(string(subnet.ProviderId)) { continue } zones := subnet.AvailabilityZones if len(zones) == 0 { logger.Tracef( "provider does not specify zones for subnet %q; using 'default' zone as fallback", subnet.CIDR, ) zones = []string{"default"} } addSubnetsArgs.Subnets = append(addSubnetsArgs.Subnets, params.AddSubnetParams{ SubnetProviderId: string(subnet.ProviderId), SpaceTag: spaceTag.String(), Zones: zones, }) } } if err := dw.createSpacesFromArgs(createSpacesArgs); err != nil { return errors.Trace(err) } if err := dw.addSubnetsFromArgs(addSubnetsArgs); err != nil { return errors.Trace(err) } return nil }