Skip to content

Commit

Permalink
docr: add region support (#1118)
Browse files Browse the repository at this point in the history
  • Loading branch information
Collin Shoop authored Mar 10, 2022
1 parent 8e935f9 commit 770b1fc
Show file tree
Hide file tree
Showing 16 changed files with 226 additions and 59 deletions.
35 changes: 35 additions & 0 deletions commands/displayers/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ func (r *Registry) Cols() []string {
return []string{
"Name",
"Endpoint",
"Region",
}
}

func (r *Registry) ColMap() map[string]string {
return map[string]string{
"Name": "Name",
"Endpoint": "Endpoint",
"Region": "Region slug",
}
}

Expand All @@ -51,6 +53,7 @@ func (r *Registry) KV() []map[string]interface{} {
m := map[string]interface{}{
"Name": reg.Name,
"Endpoint": reg.Endpoint(),
"Region": reg.Region,
}

out = append(out, m)
Expand Down Expand Up @@ -359,3 +362,35 @@ func (t *RegistrySubscriptionTiers) KV() []map[string]interface{} {

return out
}

type RegistryAvailableRegions struct {
Regions []string
}

func (t *RegistryAvailableRegions) JSON(out io.Writer) error {
return writeJSON(t, out)
}

func (t *RegistryAvailableRegions) Cols() []string {
return []string{
"Slug",
}
}

func (t *RegistryAvailableRegions) ColMap() map[string]string {
return map[string]string{
"Slug": "Region Slug",
}
}

func (t *RegistryAvailableRegions) KV() []map[string]interface{} {
out := make([]map[string]interface{}, 0, len(t.Regions))

for _, region := range t.Regions {
out = append(out, map[string]interface{}{
"Slug": region,
})
}

return out
}
21 changes: 21 additions & 0 deletions commands/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ func Registry() *Command {
"Create a private container registry", createRegDesc, Writer)
AddStringFlag(cmdRunRegistryCreate, doctl.ArgSubscriptionTier, "", "basic",
"Subscription tier for the new registry. Possible values: see `doctl registry options subscription-tiers`", requiredOpt())
AddStringFlag(cmdRunRegistryCreate, doctl.ArgRegionSlug, "", "",
"Region for the new registry. Possible values: see `doctl registry options available-regions`")

getRegDesc := "This command retrieves details about a private container registry including its name and the endpoint used to access it."
CmdBuilder(cmd, RunRegistryGet, "get", "Retrieve details about a container registry",
Expand Down Expand Up @@ -304,6 +306,8 @@ func RegistryOptions() *Command {

tiersDesc := "List available container registry subscription tiers"
CmdBuilder(cmd, RunRegistryOptionsTiers, "subscription-tiers", tiersDesc, tiersDesc, Writer, aliasOpt("tiers"))
regionsDesc := "List available container registry regions"
CmdBuilder(cmd, RunGetRegistryOptionsRegions, "available-regions", regionsDesc, regionsDesc, Writer, aliasOpt("regions"))

return cmd
}
Expand All @@ -322,12 +326,17 @@ func RunRegistryCreate(c *CmdConfig) error {
if err != nil {
return err
}
region, err := c.Doit.GetString(c.NS, doctl.ArgRegionSlug)
if err != nil {
return err
}

rs := c.Registry()

rcr := &godo.RegistryCreateRequest{
Name: name,
SubscriptionTierSlug: subscriptionTier,
Region: region,
}
r, err := rs.Create(rcr)
if err != nil {
Expand Down Expand Up @@ -906,3 +915,15 @@ func RunRegistryOptionsTiers(c *CmdConfig) error {
}
return c.Display(item)
}

func RunGetRegistryOptionsRegions(c *CmdConfig) error {
regions, err := c.Registry().GetAvailableRegions()
if err != nil {
return err
}

item := &displayers.RegistryAvailableRegions{
Regions: regions,
}
return c.Display(item)
}
55 changes: 45 additions & 10 deletions commands/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (

var (
testRegistryName = "container-registry"
testRegistryRegion = "r1"
testSubscriptionTier = "basic"
invalidRegistryName = "invalid-container-registry"
testRegistry = do.Registry{Registry: &godo.Registry{Name: testRegistryName}}
Expand Down Expand Up @@ -159,17 +160,36 @@ func TestGarbageCollectionCommand(t *testing.T) {
}

func TestRegistryCreate(t *testing.T) {
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
rcr := godo.RegistryCreateRequest{
Name: testRegistryName,
SubscriptionTierSlug: testSubscriptionTier,
}
tm.registry.EXPECT().Create(&rcr).Return(&testRegistry, nil)
config.Args = append(config.Args, testRegistryName)
config.Doit.Set(config.NS, doctl.ArgSubscriptionTier, "basic")
t.Run("success", func(t *testing.T) {
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
rcr := godo.RegistryCreateRequest{
Name: testRegistryName,
SubscriptionTierSlug: testSubscriptionTier,
Region: testRegistryRegion,
}
tm.registry.EXPECT().Create(&rcr).Return(&testRegistry, nil)
config.Args = append(config.Args, testRegistryName)
config.Doit.Set(config.NS, doctl.ArgSubscriptionTier, testSubscriptionTier)
config.Doit.Set(config.NS, doctl.ArgRegionSlug, testRegistryRegion)

err := RunRegistryCreate(config)
assert.NoError(t, err)
})
})

err := RunRegistryCreate(config)
assert.NoError(t, err)
t.Run("region omitted", func(t *testing.T) {
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
rcr := godo.RegistryCreateRequest{
Name: testRegistryName,
SubscriptionTierSlug: testSubscriptionTier,
}
tm.registry.EXPECT().Create(&rcr).Return(&testRegistry, nil)
config.Args = append(config.Args, testRegistryName)
config.Doit.Set(config.NS, doctl.ArgSubscriptionTier, testSubscriptionTier)

err := RunRegistryCreate(config)
assert.NoError(t, err)
})
})
}

Expand Down Expand Up @@ -1025,3 +1045,18 @@ func TestGarbageCollectionUpdate(t *testing.T) {
})
}
}

func TestGetAvailableRegions(t *testing.T) {
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
t.Run("success", func(t *testing.T) {
tm.registry.EXPECT().GetAvailableRegions().Return([]string{"fra1", "sfo2", "blr1"}, nil)
err := RunGetRegistryOptionsRegions(config)
assert.NoError(t, err)
})
t.Run("error", func(t *testing.T) {
tm.registry.EXPECT().GetAvailableRegions().Return(nil, errors.New("whoops"))
err := RunGetRegistryOptionsRegions(config)
assert.Error(t, err)
})
})
}
15 changes: 15 additions & 0 deletions do/mocks/RegistryService.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions do/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ type RegistryService interface {
ListGarbageCollections(string) ([]GarbageCollection, error)
CancelGarbageCollection(string, string) (*GarbageCollection, error)
GetSubscriptionTiers() ([]RegistrySubscriptionTier, error)
GetAvailableRegions() ([]string, error)
RevokeOAuthToken(token string, endpoint string) error
}

Expand Down Expand Up @@ -342,6 +343,15 @@ func (rs *registryService) GetSubscriptionTiers() ([]RegistrySubscriptionTier, e
return ret, nil
}

func (rs *registryService) GetAvailableRegions() ([]string, error) {
opts, _, err := rs.client.Registry.GetOptions(rs.ctx)
if err != nil {
return nil, err
}

return opts.AvailableRegions, nil
}

func (rs *registryService) RevokeOAuthToken(token string, endpoint string) error {
data := url.Values{}
data.Set("token", token)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/blang/semver v3.5.1+incompatible
github.com/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb // indirect
github.com/creack/pty v1.1.11
github.com/digitalocean/godo v1.75.0
github.com/digitalocean/godo v1.76.0
github.com/docker/cli v0.0.0-20200622130859-87db43814b48
github.com/docker/docker v17.12.0-ce-rc1.0.20200531234253-77e06fda0c94+incompatible // indirect
github.com/docker/docker-credential-helpers v0.6.3 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/digitalocean/godo v1.75.0 h1:UijUv60I095CqJqGKdjY2RTPnnIa4iFddmq+1wfyS4Y=
github.com/digitalocean/godo v1.75.0/go.mod h1:GBmu8MkjZmNARE7IXRPmkbbnocNN8+uBm0xbEVw2LCs=
github.com/digitalocean/godo v1.76.0 h1:pRXXYkoOYyviwPy8tTxOYEIL6OQd3RlewzGAkKUZTBs=
github.com/digitalocean/godo v1.76.0/go.mod h1:GBmu8MkjZmNARE7IXRPmkbbnocNN8+uBm0xbEVw2LCs=
github.com/docker/cli v0.0.0-20200622130859-87db43814b48 h1:AC8qbhi/SjYf4iN2W3jSsofZGHWPjG8pjf5P143KUM8=
github.com/docker/cli v0.0.0-20200622130859-87db43814b48/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/docker v17.12.0-ce-rc1.0.20200531234253-77e06fda0c94+incompatible h1:PmGHHCZ43l6h8aZIi+Xa+z1SWe4dFImd5EK3TNp1jlo=
Expand Down
50 changes: 39 additions & 11 deletions integration/registry_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ var _ = suite("registry/create", func(t *testing.T, when spec.G, it spec.S) {
expect *require.Assertions
server *httptest.Server
expectedTierSlug string
reqRegion string // region provided in http create req
expectedRegion string // region in response
)

it.Before(func() {
Expand All @@ -43,10 +45,15 @@ var _ = suite("registry/create", func(t *testing.T, when spec.G, it spec.S) {
reqBody, err := ioutil.ReadAll(req.Body)
expect.NoError(err)

expectedJSON := fmt.Sprintf(registryCreateRequest, expectedTierSlug)
var expectedJSON string
if reqRegion == "" {
expectedJSON = fmt.Sprintf(registryCreateRequest, expectedTierSlug)
} else {
expectedJSON = fmt.Sprintf(registryCreateRequestWithRegion, expectedTierSlug, reqRegion)
}
expect.JSONEq(expectedJSON, string(reqBody))
w.WriteHeader(http.StatusCreated)
w.Write([]byte(registryCreateResponse))
w.Write([]byte(fmt.Sprintf(registryCreateResponse, expectedRegion)))
default:
dump, err := httputil.DumpRequest(req, true)
if err != nil {
Expand All @@ -67,11 +74,13 @@ var _ = suite("registry/create", func(t *testing.T, when spec.G, it spec.S) {
"my-registry",
)
expectedTierSlug = "basic"
reqRegion = ""
expectedRegion = "default"

output, err := cmd.CombinedOutput()
expect.NoError(err)

expect.Equal(strings.TrimSpace(registryGetOutput), strings.TrimSpace(string(output)))
expect.Equal(strings.TrimSpace(fmt.Sprintf(registryGetOutput, expectedRegion)), strings.TrimSpace(string(output)))
})

it("creates a registry with subscription tier specified", func() {
Expand All @@ -84,11 +93,32 @@ var _ = suite("registry/create", func(t *testing.T, when spec.G, it spec.S) {
"--subscription-tier", "starter",
)
expectedTierSlug = "starter"
reqRegion = ""
expectedRegion = "default"

output, err := cmd.CombinedOutput()
expect.NoError(err)

expect.Equal(strings.TrimSpace(fmt.Sprintf(registryGetOutput, expectedRegion)), strings.TrimSpace(string(output)))
})

it("creates a registry with region specified", func() {
cmd := exec.Command(builtBinaryPath,
"-t", "some-magic-token",
"-u", server.URL,
"registry",
"create",
"my-registry",
"--region", "r1",
)
expectedTierSlug = "basic"
reqRegion = "r1"
expectedRegion = "r1"

output, err := cmd.CombinedOutput()
expect.NoError(err)

expect.Equal(strings.TrimSpace(registryGetOutput), strings.TrimSpace(string(output)))
expect.Equal(strings.TrimSpace(fmt.Sprintf(registryGetOutput, expectedRegion)), strings.TrimSpace(string(output)))
})
})

Expand All @@ -99,20 +129,18 @@ const (
"subscription_tier_slug": "%s"
}
`
registryCreateRequestWithTier = `
registryCreateRequestWithRegion = `
{
"name": "my-registry",
"subscription_tier_slug": "basic"
"subscription_tier_slug": "%s",
"region": "%s"
}
`
registryCreateResponse = `
{
"registry": {
"name": "my-registry"
"name": "my-registry",
"region": "%s"
}
}`
registryCreateOutput = `
Name Endpoint
my-registry registry.digitalocean.com/my-registry
`
)
Loading

0 comments on commit 770b1fc

Please sign in to comment.