Exemple #1
0
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
}
Exemple #2
0
// 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
}
Exemple #3
0
// 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()
}
Exemple #4
0
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(),
	}
}
Exemple #5
0
// 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()
}
Exemple #6
0
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
}
Exemple #7
0
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
}