Skip to content

Commit

Permalink
Unmarshal link members; Add Upload() for registry module version slugs (
Browse files Browse the repository at this point in the history
#221)

* Use latest hashicorp/jsonapi

Includes support for unmarshaling link members

* Add Upload() for registry module versions

Similar to configuration versions, with the slight modification that I
don't believe client users should care about piping the correct upload
link to Upload(), or it's little more than syntatic sugar for a simple
PUT request.

With this, just provide a newly created RMV to Upload() with a path to
your module files and away you go.
  • Loading branch information
chrisarcand authored May 18, 2021
1 parent db513c3 commit 0f08d6b
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 3 deletions.
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/hashicorp/go-retryablehttp v0.5.2
github.com/hashicorp/go-slug v0.4.1
github.com/hashicorp/go-uuid v1.0.1
github.com/hashicorp/jsonapi v0.0.0-20210420151930-edf82c9774bf
github.com/hashicorp/jsonapi v0.0.0-20210518035559-1e50d74c8db3
github.com/stretchr/testify v1.3.0
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
)
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ github.com/hashicorp/go-slug v0.4.1 h1:/jAo8dNuLgSImoLXaX7Od7QB4TfYCVPam+OpAt5bZ
github.com/hashicorp/go-slug v0.4.1/go.mod h1:I5tq5Lv0E2xcNXNkmx7BSfzi1PsJ2cNjs3cC3LwyhK8=
github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/jsonapi v0.0.0-20210420151930-edf82c9774bf h1:EsVVE/vPelkJ83dk/Y3CeMbH/yPR2S8bLzMtxUoMFGI=
github.com/hashicorp/jsonapi v0.0.0-20210420151930-edf82c9774bf/go.mod h1:Yog5+CPEM3c99L1CL2CFCYoSzgWm5vTU58idbRUaLik=
github.com/hashicorp/jsonapi v0.0.0-20210518035559-1e50d74c8db3 h1:mzwkutymYIXR5oQT9YnfbLuuw7LZmksiHKRPUTN5ijo=
github.com/hashicorp/jsonapi v0.0.0-20210518035559-1e50d74c8db3/go.mod h1:Yog5+CPEM3c99L1CL2CFCYoSzgWm5vTU58idbRUaLik=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down
44 changes: 44 additions & 0 deletions registry_module.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package tfe

import (
"bytes"
"context"
"errors"
"fmt"
"net/url"
"os"

slug "github.com/hashicorp/go-slug"
)

// Compile-time proof of interface implementation.
Expand Down Expand Up @@ -35,6 +39,11 @@ type RegistryModules interface {

// Delete a specific registry module version
DeleteVersion(ctx context.Context, organization string, name string, provider string, version string) error

// Upload Terraform configuration files for the provided registry module version. It
// requires a path to the configuration files on disk, which will be packaged by
// hashicorp/go-slug before being uploaded.
Upload(ctx context.Context, rmv RegistryModuleVersion, path string) error
}

// registryModules implements RegistryModules.
Expand Down Expand Up @@ -94,6 +103,41 @@ type RegistryModuleVersion struct {

// Relations
RegistryModule *RegistryModule `jsonapi:"relation,registry-module"`

// Links
Links map[string]interface{} `jsonapi:"links,omitempty"`
}

// Upload uploads Terraform configuration files for the provided registry module version. It
// requires a path to the configuration files on disk, which will be packaged by
// hashicorp/go-slug before being uploaded.
func (r *registryModules) Upload(ctx context.Context, rmv RegistryModuleVersion, path string) error {
uploadURL, ok := rmv.Links["upload"].(string)
if !ok {
return fmt.Errorf("Provided RegistryModuleVersion does not contain an upload link")
}

file, err := os.Stat(path)
if err != nil {
return err
}
if !file.Mode().IsDir() {
return ErrMissingDirectory
}

body := bytes.NewBuffer(nil)

_, err = slug.Pack(path, body, true)
if err != nil {
return err
}

req, err := r.client.newRequest("PUT", uploadURL, body)
if err != nil {
return err
}

return r.client.do(ctx, req, nil)
}

type RegistryModulePermissions struct {
Expand Down
43 changes: 43 additions & 0 deletions registry_module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ func TestRegistryModulesCreateVersion(t *testing.T) {
assert.NotEmpty(t, rmv.CreatedAt)
assert.NotEmpty(t, rmv.UpdatedAt)
})

t.Run("links are properly decoded", func(t *testing.T) {
assert.NotEmpty(t, rmv.Links["upload"])
assert.Contains(t, rmv.Links["upload"], "/object/")
})
})

t.Run("with invalid options", func(t *testing.T) {
Expand Down Expand Up @@ -529,6 +534,44 @@ func TestRegistryModulesDeleteVersion(t *testing.T) {
})
}

func TestRegistryModulesUpload(t *testing.T) {
client := testClient(t)
ctx := context.Background()

orgTest, orgTestCleanup := createOrganization(t, client)
defer orgTestCleanup()

rm, _ := createRegistryModule(t, client, orgTest)

optionsModuleVersion := RegistryModuleCreateVersionOptions{
Version: String("1.0.0"),
}
rmv, err := client.RegistryModules.CreateVersion(ctx, orgTest.Name, rm.Name, rm.Provider, optionsModuleVersion)
if err != nil {
t.Fatal(err)
}

t.Run("with valid upload URL", func(t *testing.T) {
err = client.RegistryModules.Upload(
ctx,
*rmv,
"test-fixtures/config-version",
)
require.NoError(t, err)
})

t.Run("with missing upload URL", func(t *testing.T) {
delete(rmv.Links, "upload")

err = client.RegistryModules.Upload(
ctx,
*rmv,
"test-fixtures/config-version",
)
assert.EqualError(t, err, "Provided RegistryModuleVersion does not contain an upload link")
})
}

func TestRegistryModule_Unmarshal(t *testing.T) {
data := map[string]interface{}{
"data": map[string]interface{}{
Expand Down

0 comments on commit 0f08d6b

Please sign in to comment.