func makeListSubnetsArgs(space *names.SpaceTag, zone string) apitesting.CheckArgs { expectResults := params.ListSubnetsResults{} expectArgs := params.SubnetsFilters{ SpaceTag: space.String(), Zone: zone, } args := apitesting.CheckArgs{ Facade: "Subnets", Method: "ListSubnets", Results: expectResults, Args: expectArgs, } return args }
// ListSubnets fetches all the subnets known by the environment. func (api *API) ListSubnets(spaceTag *names.SpaceTag, zone string) ([]params.Subnet, error) { var response params.ListSubnetsResults var space string if spaceTag != nil { space = spaceTag.String() } args := params.SubnetsFilters{ SpaceTag: space, Zone: zone, } err := api.facade.FacadeCall("ListSubnets", args, &response) if err != nil { return nil, errors.Trace(err) } return response.Results, nil }
// CreateSubnet creates a new subnet with the provider. func (api *API) CreateSubnet(subnet names.SubnetTag, space names.SpaceTag, zones []string, isPublic bool) error { var response params.ErrorResults params := params.CreateSubnetsParams{ Subnets: []params.CreateSubnetParams{{ SubnetTag: subnet.String(), SpaceTag: space.String(), Zones: zones, IsPublic: isPublic, }}, } err := api.facade.FacadeCall("CreateSubnets", params, &response) if err != nil { return errors.Trace(err) } return response.OneError() }
func BackingSubnetToParamsSubnet(subnet BackingSubnet) params.Subnet { cidr := subnet.CIDR() vlantag := subnet.VLANTag() providerid := subnet.ProviderId() zones := subnet.AvailabilityZones() status := subnet.Status() var spaceTag names.SpaceTag if subnet.SpaceName() != "" { spaceTag = names.NewSpaceTag(subnet.SpaceName()) } return params.Subnet{ CIDR: cidr, VLANTag: vlantag, ProviderId: string(providerid), Zones: zones, Status: status, SpaceTag: spaceTag.String(), Life: subnet.Life(), } }
// AddSubnet adds an existing subnet to the environment. func (api *API) AddSubnet(subnet names.SubnetTag, providerId network.Id, space names.SpaceTag, zones []string) error { var response params.ErrorResults // Prefer ProviderId when set over CIDR. subnetTag := subnet.String() if providerId != "" { subnetTag = "" } params := params.AddSubnetsParams{ Subnets: []params.AddSubnetParams{{ SubnetTag: subnetTag, SubnetProviderId: string(providerId), SpaceTag: space.String(), Zones: zones, }}, } err := api.facade.FacadeCall("AddSubnets", params, &response) if err != nil { return errors.Trace(err) } return response.OneError() }
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 }
func (dw *discoverspacesWorker) handleSubnets(env environs.NetworkingEnviron) error { ok, err := env.SupportsSpaceDiscovery() if err != nil { return errors.Trace(err) } if !ok { // Nothing to do. return nil } providerSpaces, err := env.Spaces() if err != nil { return errors.Trace(err) } listSpacesResult, err := dw.api.ListSpaces() if err != nil { return errors.Trace(err) } stateSubnets, err := dw.api.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. 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.ProviderId) // Convert the name into a valid name that isn't already in // use. spaceName = convertSpaceName(spaceName, spaceNames) spaceNames.Add(spaceName) spaceTag = names.NewSpaceTag(spaceName) // We need to create the space. args := params.CreateSpacesParams{ Spaces: []params.CreateSpaceParams{{ Public: false, SpaceTag: spaceTag.String(), ProviderId: string(space.ProviderId), }}} result, err := dw.api.CreateSpaces(args) if err != nil { logger.Errorf("error creating space %v", err) return errors.Trace(err) } if len(result.Results) != 1 { return errors.Errorf("unexpected number of results from CreateSpaces, should be 1: %v", result) } if result.Results[0].Error != nil { return errors.Errorf("error from CreateSpaces: %v", result.Results[0].Error) } } // 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. logger.Debugf("Created space %v with %v subnets", spaceTag.String(), len(space.Subnets)) for _, subnet := range space.Subnets { if stateSubnetIds.Contains(string(subnet.ProviderId)) { continue } zones := subnet.AvailabilityZones if len(zones) == 0 { zones = []string{"default"} } args := params.AddSubnetsParams{ Subnets: []params.AddSubnetParams{{ SubnetProviderId: string(subnet.ProviderId), SpaceTag: spaceTag.String(), Zones: zones, }}} logger.Tracef("Adding subnet %v", subnet.CIDR) result, err := dw.api.AddSubnets(args) if err != nil { logger.Errorf("invalid creating subnet %v", err) return errors.Trace(err) } if len(result.Results) != 1 { return errors.Errorf("unexpected number of results from AddSubnets, should be 1: %v", result) } if result.Results[0].Error != nil { logger.Errorf("error creating subnet %v", result.Results[0].Error) return errors.Errorf("error creating subnet %v", result.Results[0].Error) } } } return nil }