// ActiveSubnets returns a list of subnet tags for which the machine has opened // ports. func (m *Machine) ActiveSubnets() ([]names.SubnetTag, error) { var results params.StringsResults args := params.Entities{ Entities: []params.Entity{{Tag: m.tag.String()}}, } err := m.st.facade.FacadeCall("GetMachineActiveSubnets", args, &results) if err != nil { return nil, err } if len(results.Results) != 1 { return nil, fmt.Errorf("expected 1 result, got %d", len(results.Results)) } result := results.Results[0] if result.Error != nil { return nil, result.Error } // Convert string tags to names.SubnetTag before returning. tags := make([]names.SubnetTag, len(result.Result)) for i, tag := range result.Result { var subnetTag names.SubnetTag if tag != "" { subnetTag, err = names.ParseSubnetTag(tag) if err != nil { return nil, err } } tags[i] = subnetTag } return tags, nil }
func (s *subnetSuite) TestParseSubnetTag(c *gc.C) { for i, t := range parseSubnetTagTests { c.Logf("test %d: %s", i, t.tag) got, err := names.ParseSubnetTag(t.tag) if err != nil || t.err != nil { c.Check(err, gc.DeepEquals, t.err) continue } c.Check(got, gc.FitsTypeOf, t.expected) c.Check(got, gc.Equals, t.expected) } }
// GetMachinePorts returns the port ranges opened on a machine for the specified // subnet as a map mapping port ranges to the tags of the units that opened // them. func (f *FirewallerAPI) GetMachinePorts(args params.MachinePortsParams) (params.MachinePortsResults, error) { result := params.MachinePortsResults{ Results: make([]params.MachinePortsResult, len(args.Params)), } canAccess, err := f.accessMachine() if err != nil { return params.MachinePortsResults{}, err } for i, param := range args.Params { machineTag, err := names.ParseMachineTag(param.MachineTag) if err != nil { result.Results[i].Error = common.ServerError(err) continue } var subnetTag names.SubnetTag if param.SubnetTag != "" { subnetTag, err = names.ParseSubnetTag(param.SubnetTag) if err != nil { result.Results[i].Error = common.ServerError(err) continue } } machine, err := f.getMachine(canAccess, machineTag) if err != nil { result.Results[i].Error = common.ServerError(err) continue } ports, err := machine.OpenedPorts(subnetTag.Id()) if err != nil { result.Results[i].Error = common.ServerError(err) continue } if ports != nil { portRangeMap := ports.AllPortRanges() var portRanges []network.PortRange for portRange := range portRangeMap { portRanges = append(portRanges, portRange) } network.SortPortRanges(portRanges) for _, portRange := range portRanges { unitTag := names.NewUnitTag(portRangeMap[portRange]).String() result.Results[i].Ports = append(result.Results[i].Ports, params.MachinePortRange{ UnitTag: unitTag, PortRange: params.FromNetworkPortRange(portRange), }) } } } return result, nil }
func (s *subnetSuite) TestNewSubnetTag(c *gc.C) { cidr := "10.20.0.0/16" tag := names.NewSubnetTag(cidr) parsed, err := names.ParseSubnetTag(tag.String()) c.Assert(err, gc.IsNil) c.Assert(parsed.Kind(), gc.Equals, names.SubnetTagKind) c.Assert(parsed.Id(), gc.Equals, cidr) c.Assert(parsed.String(), gc.Equals, names.SubnetTagKind+"-"+cidr) f := func() { tag = names.NewSubnetTag("foo") } c.Assert(f, gc.PanicMatches, "foo is not a valid subnet CIDR") }
func (api *spacesAPI) createOneSpace(args params.CreateSpaceParams) error { // Validate the args, assemble information for api.backing.AddSpaces var subnets []string spaceTag, err := names.ParseSpaceTag(args.SpaceTag) if err != nil { return errors.Trace(err) } for _, tag := range args.SubnetTags { subnetTag, err := names.ParseSubnetTag(tag) if err != nil { return errors.Trace(err) } subnets = append(subnets, subnetTag.Id()) } // Add the validated space err = api.backing.AddSpace(spaceTag.Id(), subnets, args.Public) if err != nil { return errors.Trace(err) } return nil }
// validateSubnet ensures either subnetTag or providerId is valid (not both), // then uses the cache to validate and lookup the provider SubnetInfo for the // subnet, if found. func (cache *addSubnetsCache) validateSubnet(subnetTag, providerId string) (*network.SubnetInfo, error) { haveTag := subnetTag != "" haveProviderId := providerId != "" if !haveTag && !haveProviderId { return nil, errors.Errorf("either SubnetTag or SubnetProviderId is required") } else if haveTag && haveProviderId { return nil, errors.Errorf("SubnetTag and SubnetProviderId cannot be both set") } var tag names.SubnetTag if haveTag { var err error tag, err = names.ParseSubnetTag(subnetTag) if err != nil { return nil, errors.Annotate(err, "given SubnetTag is invalid") } } // Otherwise we need the cache to validate. if err := cache.cacheSubnets(); err != nil { return nil, errors.Trace(err) } if haveTag { providerIds, ok := cache.providerIdsByCIDR[tag.Id()] if !ok || providerIds.IsEmpty() { return nil, errors.NotFoundf("subnet with CIDR %q", tag.Id()) } if providerIds.Size() > 1 { ids := `"` + strings.Join(providerIds.SortedValues(), `", "`) + `"` return nil, errors.Errorf( "multiple subnets with CIDR %q: retry using ProviderId from: %s", tag.Id(), ids, ) } // A single CIDR matched. providerId = providerIds.Values()[0] } info, ok := cache.subnetsByProviderId[providerId] if !ok || info == nil { return nil, errors.NotFoundf( "subnet with CIDR %q and ProviderId %q", tag.Id(), providerId, ) } // Do last-call validation. if !names.IsValidSubnet(info.CIDR) { _, ipnet, err := net.ParseCIDR(info.CIDR) if err != nil && info.CIDR != "" { // The underlying error is not important here, just that // the CIDR is invalid. return nil, errors.Errorf( "subnet with CIDR %q and ProviderId %q: invalid CIDR", info.CIDR, providerId, ) } if info.CIDR == "" { return nil, errors.Errorf( "subnet with ProviderId %q: empty CIDR", providerId, ) } return nil, errors.Errorf( "subnet with ProviderId %q: incorrect CIDR format %q, expected %q", providerId, info.CIDR, ipnet.String(), ) } return info, nil }