func (s *ListSuite) TestRunWithFilteringSucceeds(c *gc.C) { // Simulate one subnet is using the "public" space or "zone1". s.api.Subnets = s.api.Subnets[0:1] expected := ` subnets: 10.20.0.0/24: type: ipv4 provider-id: subnet-foo status: in-use space: public zones: - zone1 - zone2 `[1:] // Filter by space name first. s.AssertRunSucceeds(c, "", // empty stderr. expected, "--space", "public", ) s.api.CheckCallNames(c, "ListSubnets", "Close") tag := names.NewSpaceTag("public") s.api.CheckCall(c, 0, "ListSubnets", &tag, "") s.api.ResetCalls() // Now filter by zone. s.AssertRunSucceeds(c, "", // empty stderr. expected, "--zone", "zone1", ) s.api.CheckCallNames(c, "ListSubnets", "Close") s.api.CheckCall(c, 0, "ListSubnets", nil, "zone1") s.api.ResetCalls() // Finally, filter by both space and zone. s.AssertRunSucceeds(c, "", // empty stderr. expected, "--zone", "zone1", "--space", "public", ) s.api.CheckCallNames(c, "ListSubnets", "Close") tag = names.NewSpaceTag("public") s.api.CheckCall(c, 0, "ListSubnets", &tag, "zone1") }
func (s *spaceSuite) TestSpaceNames(c *gc.C) { for i, test := range spaceNameTests { c.Logf("test %d: %q", i, test.pattern) c.Check(names.IsValidSpace(test.pattern), gc.Equals, test.valid) if test.valid { expectTag := fmt.Sprintf("%s-%s", names.SpaceTagKind, test.pattern) c.Check(names.NewSpaceTag(test.pattern).String(), gc.Equals, expectTag) } else { expectErr := fmt.Sprintf("%q is not a valid space name", test.pattern) testTag := func() { names.NewSpaceTag(test.pattern) } c.Check(testTag, gc.PanicMatches, regexp.QuoteMeta(expectErr)) } } }
func makeCreateSubnetsArgs(cidr, space string, zones []string, isPublic bool) apitesting.CheckArgs { spaceTag := names.NewSpaceTag(space).String() subnetTag := names.NewSubnetTag(cidr).String() expectArgs := params.CreateSubnetsParams{ Subnets: []params.CreateSubnetParams{{ SpaceTag: spaceTag, SubnetTag: subnetTag, Zones: zones, IsPublic: isPublic, }}} expectResults := params.ErrorResults{ Results: []params.ErrorResult{{}}, } args := apitesting.CheckArgs{ Facade: "Subnets", Method: "CreateSubnets", Args: expectArgs, Results: expectResults, } return args }
func makeArgs(name string, subnets []string) (string, []string, apitesting.CheckArgs) { spaceTag := names.NewSpaceTag(name).String() subnetTags := []string{} for _, s := range subnets { subnetTags = append(subnetTags, names.NewSubnetTag(s).String()) } expectArgs := params.CreateSpacesParams{ Spaces: []params.CreateSpaceParams{ params.CreateSpaceParams{ SpaceTag: spaceTag, SubnetTags: subnetTags, Public: true, }}} expectResults := params.ErrorResults{ Results: []params.ErrorResult{{}}, } args := apitesting.CheckArgs{ Facade: "Spaces", Method: "CreateSpaces", Args: expectArgs, Results: expectResults, } return name, subnets, args }
func (s *WorkerSuite) TestWorkerIgnoresExistingSpacesAndSubnets(c *gc.C) { dummy.SetSupportsSpaceDiscovery(true) spaceTag := names.NewSpaceTag("foo") args := params.CreateSpacesParams{ Spaces: []params.CreateSpaceParams{{ Public: false, SpaceTag: spaceTag.String(), ProviderId: "foo", }}} result, err := s.API.CreateSpaces(args) c.Assert(err, jc.ErrorIsNil) c.Assert(result.Results, gc.HasLen, 1) c.Assert(result.Results[0].Error, gc.IsNil) subnetArgs := params.AddSubnetsParams{ Subnets: []params.AddSubnetParams{{ SubnetProviderId: "1", SpaceTag: spaceTag.String(), Zones: []string{"zone1"}, }}} subnetResult, err := s.API.AddSubnets(subnetArgs) c.Assert(err, jc.ErrorIsNil) c.Assert(subnetResult.Results, gc.HasLen, 1) c.Assert(subnetResult.Results[0].Error, gc.IsNil) s.unlockCheck(c, func(c *gc.C) { spaces, err := s.State.AllSpaces() c.Assert(err, jc.ErrorIsNil) c.Assert(spaces, gc.HasLen, 5) }) }
func makeAddSubnetsArgs(cidr, providerId, space string, zones []string) apitesting.CheckArgs { spaceTag := names.NewSpaceTag(space).String() subnetTag := names.NewSubnetTag(cidr).String() if providerId != "" { subnetTag = "" } expectArgs := params.AddSubnetsParams{ Subnets: []params.AddSubnetParams{{ SpaceTag: spaceTag, SubnetTag: subnetTag, SubnetProviderId: providerId, Zones: zones, }}} expectResults := params.ErrorResults{ Results: []params.ErrorResult{{}}, } args := apitesting.CheckArgs{ Facade: "Subnets", Method: "AddSubnets", Args: expectArgs, Results: expectResults, } return args }
func (s *commonSuite) TestAuthFuncForTagKind(c *gc.C) { // TODO(dimitern): This list of all supported tags and kinds needs // to live in juju/names. uuid, err := utils.NewUUID() c.Assert(err, jc.ErrorIsNil) allTags := []names.Tag{ nil, // invalid tag names.NewActionTag(uuid.String()), names.NewCharmTag("cs:precise/missing"), names.NewModelTag(uuid.String()), names.NewFilesystemTag("20/20"), names.NewLocalUserTag("user"), names.NewMachineTag("42"), names.NewNetworkTag("public"), names.NewRelationTag("wordpress:mysql mysql:db"), names.NewServiceTag("wordpress"), names.NewSpaceTag("apps"), names.NewStorageTag("foo/42"), names.NewUnitTag("wordpress/5"), names.NewUserTag("joe"), names.NewVolumeTag("80/20"), } for i, allowedTag := range allTags { c.Logf("test #%d: allowedTag: %v", i, allowedTag) var allowedKind string if allowedTag != nil { allowedKind = allowedTag.Kind() } getAuthFunc := common.AuthFuncForTagKind(allowedKind) authFunc, err := getAuthFunc() if allowedKind == "" { c.Check(err, gc.ErrorMatches, "tag kind cannot be empty") c.Check(authFunc, gc.IsNil) continue } else if !c.Check(err, jc.ErrorIsNil) { continue } for j, givenTag := range allTags { c.Logf("test #%d.%d: givenTag: %v", i, j, givenTag) var givenKind string if givenTag != nil { givenKind = givenTag.Kind() } if allowedKind == givenKind { c.Check(authFunc(givenTag), jc.IsTrue) } else { c.Check(authFunc(givenTag), jc.IsFalse) } } } }
func (s *CreateSuite) TestRunOneZoneSucceeds(c *gc.C) { s.AssertRunSucceeds(c, `created a private subnet "10.20.0.0/24" in space "myspace" with zones zone1\n`, "", // empty stdout. "10.20.0.0/24", "myspace", "zone1", ) s.api.CheckCallNames(c, "AllZones", "CreateSubnet", "Close") s.api.CheckCall(c, 1, "CreateSubnet", names.NewSubnetTag("10.20.0.0/24"), names.NewSpaceTag("myspace"), s.Strings("zone1"), false, ) }
func (s *CreateSuite) TestRunWithPublicAndIPv6CIDRSucceeds(c *gc.C) { s.AssertRunSucceeds(c, `created a public subnet "2001:db8::/32" in space "space" with zones zone1\n`, "", // empty stdout. "2001:db8::/32", "space", "zone1", "--public", ) s.api.CheckCallNames(c, "AllZones", "CreateSubnet", "Close") s.api.CheckCall(c, 1, "CreateSubnet", names.NewSubnetTag("2001:db8::/32"), names.NewSpaceTag("space"), s.Strings("zone1"), true, ) }
func (s *SubnetsSuite) TestListSubnetsFails(c *gc.C) { space := names.NewSpaceTag("foo") zone := "bar" args := makeListSubnetsArgs(&space, zone) s.prepareAPICall(c, &args, errors.New("bang")) results, err := s.api.ListSubnets(&space, zone) c.Assert(s.called, gc.Equals, 1) c.Assert(err, gc.ErrorMatches, "bang") var expectedResults []params.Subnet c.Assert(results, jc.DeepEquals, expectedResults) }
func (s *CreateSuite) TestRunWithExistingSubnetFails(c *gc.C) { s.api.SetErrors(nil, errors.AlreadyExistsf("subnet %q", "10.10.0.0/24")) err := s.AssertRunFails(c, `cannot create subnet "10.10.0.0/24": subnet "10.10.0.0/24" already exists`, "10.10.0.0/24", "space", "zone1", ) c.Assert(err, jc.Satisfies, errors.IsAlreadyExists) s.api.CheckCallNames(c, "AllZones", "CreateSubnet", "Close") s.api.CheckCall(c, 1, "CreateSubnet", names.NewSubnetTag("10.10.0.0/24"), names.NewSpaceTag("space"), s.Strings("zone1"), false, ) }
func makeCreateSpaceParams(name string, subnetIds []string, public bool) params.CreateSpaceParams { spaceTag := names.NewSpaceTag(name).String() subnetTags := make([]string, len(subnetIds)) for i, s := range subnetIds { subnetTags[i] = names.NewSubnetTag(s).String() } return params.CreateSpaceParams{ SpaceTag: spaceTag, SubnetTags: subnetTags, Public: public, } }
// AssertAllSpacesResult makes it easier to verify AllSpaces results. func (s *SubnetsSuite) AssertAllSpacesResult(c *gc.C, got params.SpaceResults, expected []common.BackingSpace) { seen := set.Strings{} results := []params.SpaceResult{} for _, space := range expected { if seen.Contains(space.Name()) { continue } seen.Add(space.Name()) result := params.SpaceResult{} result.Tag = names.NewSpaceTag(space.Name()).String() results = append(results, result) } c.Assert(got, jc.DeepEquals, params.SpaceResults{Results: results}) }
func (s *ListSuite) TestRunWhenNoneMatchSucceeds(c *gc.C) { // Simulate no subnets are using the "default" space. s.api.Subnets = s.api.Subnets[0:0] s.AssertRunSucceeds(c, `no subnets found matching requested criteria\n`, "", // empty stdout. "--space", "default", ) s.api.CheckCallNames(c, "ListSubnets", "Close") tag := names.NewSpaceTag("default") s.api.CheckCall(c, 0, "ListSubnets", &tag, "") }
func (s *CreateSuite) TestRunWithMultipleZonesSucceeds(c *gc.C) { s.AssertRunSucceeds(c, // The list of zones is sorted both when displayed and passed // to CreateSubnet. `created a private subnet "10.20.0.0/24" in space "foo" with zones zone1, zone2\n`, "", // empty stdout. "10.20.0.0/24", "foo", "zone2", "zone1", // unsorted zones ) s.api.CheckCallNames(c, "AllZones", "CreateSubnet", "Close") s.api.CheckCall(c, 1, "CreateSubnet", names.NewSubnetTag("10.20.0.0/24"), names.NewSpaceTag("foo"), s.Strings("zone1", "zone2"), false, ) }
func (s *CreateSuite) TestRunWithNonExistingSpaceFails(c *gc.C) { s.api.SetErrors(nil, errors.NotFoundf("space %q", "space")) err := s.AssertRunFails(c, `cannot create subnet "10.10.0.0/24": space "space" not found`, "10.10.0.0/24", "space", "zone1", ) c.Assert(err, jc.Satisfies, errors.IsNotFound) s.api.CheckCallNames(c, "AllZones", "CreateSubnet", "Close") s.api.CheckCall(c, 1, "CreateSubnet", names.NewSubnetTag("10.10.0.0/24"), names.NewSpaceTag("space"), s.Strings("zone1"), false, ) }
// NewStubAPI creates a StubAPI suitable for passing to // subnet.New*Command(). func NewStubAPI() *StubAPI { subnets := []params.Subnet{{ // IPv4 subnet. CIDR: "10.20.0.0/24", ProviderId: "subnet-foo", Life: params.Alive, SpaceTag: "space-public", Zones: []string{"zone1", "zone2"}, StaticRangeLowIP: net.ParseIP("10.20.0.10"), StaticRangeHighIP: net.ParseIP("10.20.0.100"), }, { // IPv6 subnet. CIDR: "2001:db8::/32", ProviderId: "subnet-bar", Life: params.Dying, SpaceTag: "space-dmz", Zones: []string{"zone2"}, }, { // IPv4 VLAN subnet. CIDR: "10.10.0.0/16", Life: params.Dead, SpaceTag: "space-vlan-42", Zones: []string{"zone1"}, VLANTag: 42, }} return &StubAPI{ Stub: &testing.Stub{}, Zones: []string{"zone1", "zone2"}, Subnets: subnets, Spaces: []names.Tag{ names.NewSpaceTag("default"), names.NewSpaceTag("public"), names.NewSpaceTag("dmz"), names.NewSpaceTag("vlan-42"), }, } }
func (s *AddSuite) TestRunWithIPv6CIDRSucceeds(c *gc.C) { s.AssertRunSucceeds(c, `added subnet with CIDR "2001:db8::/32" in space "hyperspace"\n`, "", // empty stdout. "2001:db8::/32", "hyperspace", ) s.api.CheckCallNames(c, "AddSubnet", "Close") s.api.CheckCall(c, 0, "AddSubnet", names.NewSubnetTag("2001:db8::/32"), network.Id(""), names.NewSpaceTag("hyperspace"), []string(nil), ) }
func (s *AddSuite) TestRunWithProviderIdSucceeds(c *gc.C) { s.AssertRunSucceeds(c, `added subnet with ProviderId "foo" in space "myspace"\n`, "", // empty stdout. "foo", "myspace", "zone1", "zone2", ) s.api.CheckCallNames(c, "AddSubnet", "Close") s.api.CheckCall(c, 0, "AddSubnet", names.SubnetTag{}, network.Id("foo"), names.NewSpaceTag("myspace"), s.Strings("zone1", "zone2"), ) }
func (s *AddSuite) TestRunWithIPv4CIDRSucceeds(c *gc.C) { s.AssertRunSucceeds(c, `added subnet with CIDR "10.20.0.0/24" in space "myspace"\n`, "", // empty stdout. "10.20.0.0/24", "myspace", ) s.api.CheckCallNames(c, "AddSubnet", "Close") s.api.CheckCall(c, 0, "AddSubnet", names.NewSubnetTag("10.20.0.0/24"), network.Id(""), names.NewSpaceTag("myspace"), []string(nil), ) }
func (s *SubnetsSuite) TestCreateSubnet(c *gc.C) { cidr := "1.1.1.0/24" space := "bar" zones := []string{"foo", "bar"} isPublic := true args := makeCreateSubnetsArgs(cidr, space, zones, isPublic) s.prepareAPICall(c, &args, nil) err := s.api.CreateSubnet( names.NewSubnetTag(cidr), names.NewSpaceTag(space), zones, isPublic, ) c.Assert(s.called, gc.Equals, 1) c.Assert(err, jc.ErrorIsNil) }
func (s *SubnetsSuite) TestCreateSubnetFails(c *gc.C) { cidr := "1.1.1.0/24" isPublic := true space := "bar" zones := []string{"foo", "bar"} args := makeCreateSubnetsArgs(cidr, space, zones, isPublic) s.prepareAPICall(c, &args, errors.New("bang")) err := s.api.CreateSubnet( names.NewSubnetTag(cidr), names.NewSpaceTag(space), zones, isPublic, ) c.Check(s.called, gc.Equals, 1) c.Assert(err, gc.ErrorMatches, "bang") }
func (s *SubnetsSuite) TestAddSubnetFails(c *gc.C) { cidr := "1.1.1.0/24" providerId := "foo" space := "bar" zones := []string{"foo", "bar"} args := makeAddSubnetsArgs(cidr, providerId, space, zones) s.prepareAPICall(c, &args, errors.New("bang")) err := s.api.AddSubnet( names.NewSubnetTag(cidr), network.Id(providerId), names.NewSpaceTag(space), zones, ) c.Check(s.called, gc.Equals, 1) c.Assert(err, gc.ErrorMatches, "bang") }
func (s *AddSuite) TestRunWithNonExistingSpaceFails(c *gc.C) { s.api.SetErrors(errors.NotFoundf("space %q", "space")) err := s.AssertRunFails(c, `cannot add subnet: space "space" not found`, "10.10.0.0/24", "space", "zone1", "zone2", ) c.Assert(err, jc.Satisfies, errors.IsNotFound) s.api.CheckCallNames(c, "AddSubnet", "Close") s.api.CheckCall(c, 0, "AddSubnet", names.NewSubnetTag("10.10.0.0/24"), network.Id(""), names.NewSpaceTag("space"), s.Strings("zone1", "zone2"), ) }
func (s *AddSuite) TestRunWithExistingSubnetFails(c *gc.C) { s.api.SetErrors(errors.AlreadyExistsf("subnet %q", "10.10.0.0/24")) err := s.AssertRunFails(c, `cannot add subnet: subnet "10.10.0.0/24" already exists`, "10.10.0.0/24", "space", ) c.Assert(err, jc.Satisfies, errors.IsAlreadyExists) s.api.CheckCallNames(c, "AddSubnet", "Close") s.api.CheckCall(c, 0, "AddSubnet", names.NewSubnetTag("10.10.0.0/24"), network.Id(""), names.NewSpaceTag("space"), []string(nil), ) }
// AllSpaces is defined on the API interface. func (api *subnetsAPI) AllSpaces() (params.SpaceResults, error) { var results params.SpaceResults spaces, err := api.backing.AllSpaces() if err != nil { return results, errors.Trace(err) } results.Results = make([]params.SpaceResult, len(spaces)) for i, space := range spaces { // TODO(dimitern): Add a Tag() a method and use it here. Too // early to do it now as it will just complicate the tests. tag := names.NewSpaceTag(space.Name()) results.Results[i].Tag = tag.String() } return results, nil }
// ListSubnets lists all the available subnets or only those matching // all given optional filters. func ListSubnets(api NetworkBacking, args params.SubnetsFilters) (results params.ListSubnetsResults, err error) { subnets, err := api.AllSubnets() if err != nil { return results, errors.Trace(err) } var spaceFilter string if args.SpaceTag != "" { tag, err := names.ParseSpaceTag(args.SpaceTag) if err != nil { return results, errors.Trace(err) } spaceFilter = tag.Id() } zoneFilter := args.Zone for _, subnet := range subnets { if spaceFilter != "" && subnet.SpaceName() != spaceFilter { logger.Tracef( "filtering subnet %q from space %q not matching filter %q", subnet.CIDR(), subnet.SpaceName(), spaceFilter, ) continue } zoneSet := set.NewStrings(subnet.AvailabilityZones()...) if zoneFilter != "" && !zoneSet.IsEmpty() && !zoneSet.Contains(zoneFilter) { logger.Tracef( "filtering subnet %q with zones %v not matching filter %q", subnet.CIDR(), subnet.AvailabilityZones(), zoneFilter, ) continue } result := params.Subnet{ CIDR: subnet.CIDR(), ProviderId: string(subnet.ProviderId()), VLANTag: subnet.VLANTag(), Life: subnet.Life(), SpaceTag: names.NewSpaceTag(subnet.SpaceName()).String(), Zones: subnet.AvailabilityZones(), Status: subnet.Status(), } results.Results = append(results.Results, result) } return results, nil }
func (s *AddSuite) TestRunWithAmbiguousCIDRDisplaysError(c *gc.C) { apiError := errors.New(`multiple subnets with CIDR "10.10.0.0/24" <snip>`) s.api.SetErrors(apiError) s.AssertRunSucceeds(c, fmt.Sprintf("ERROR: %v.\n", apiError), "", "10.10.0.0/24", "space", "zone1", "zone2", ) s.api.CheckCallNames(c, "AddSubnet", "Close") s.api.CheckCall(c, 0, "AddSubnet", names.NewSubnetTag("10.10.0.0/24"), network.Id(""), names.NewSpaceTag("space"), s.Strings("zone1", "zone2"), ) }
func (s *workerSuite) TestWorkerIgnoresExistingSpacesAndSubnets(c *gc.C) { dummy.SetSupportsSpaceDiscovery(true) spaceTag := names.NewSpaceTag("foo") args := params.CreateSpacesParams{ Spaces: []params.CreateSpaceParams{{ Public: false, SpaceTag: spaceTag.String(), ProviderId: "foo", }}} result, err := s.API.CreateSpaces(args) c.Assert(err, jc.ErrorIsNil) c.Assert(result.Results, gc.HasLen, 1) c.Assert(result.Results[0].Error, gc.IsNil) subnetArgs := params.AddSubnetsParams{ Subnets: []params.AddSubnetParams{{ SubnetProviderId: "1", SpaceTag: spaceTag.String(), Zones: []string{"zone1"}, }}} subnetResult, err := s.API.AddSubnets(subnetArgs) c.Assert(err, jc.ErrorIsNil) c.Assert(subnetResult.Results, gc.HasLen, 1) c.Assert(subnetResult.Results[0].Error, gc.IsNil) s.startWorker() for a := common.ShortAttempt.Start(); a.Next(); { spaces, err := s.State.AllSpaces() if err != nil { break } if len(spaces) == 4 { // All spaces have been created. break } if !a.HasNext() { c.Fatalf("spaces not imported") } } c.Assert(err, jc.ErrorIsNil) }
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(), } }