예제 #1
0
파일: machine.go 프로젝트: makyo/juju
// 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
}
예제 #2
0
파일: subnet_test.go 프로젝트: juju/names
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)
	}
}
예제 #3
0
// 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
}
예제 #4
0
파일: subnet_test.go 프로젝트: juju/names
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")
}
예제 #5
0
파일: spaces.go 프로젝트: mhilton/juju
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
}
예제 #6
0
파일: subnets.go 프로젝트: makyo/juju
// 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
}