From daac631fb29bdcd1c7d7176c2c617a630d8e8d6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Hern=C3=A1ndez?= Date: Tue, 25 Oct 2022 19:32:19 +0200 Subject: [PATCH 1/9] add update api for registry modules --- mocks/registry_module_mocks.go | 15 +++++++++ registry_module.go | 50 +++++++++++++++++++++++++++++ registry_module_integration_test.go | 50 +++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) diff --git a/mocks/registry_module_mocks.go b/mocks/registry_module_mocks.go index 185e75f25..de9564551 100644 --- a/mocks/registry_module_mocks.go +++ b/mocks/registry_module_mocks.go @@ -152,6 +152,21 @@ func (mr *MockRegistryModulesMockRecorder) Read(ctx, moduleID interface{}) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockRegistryModules)(nil).Read), ctx, moduleID) } +// Update mocks base method. +func (m *MockRegistryModules) Update(ctx context.Context, moduleID tfe.RegistryModuleID, options tfe.RegistryModuleUpdateOptions) (*tfe.RegistryModule, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Update", ctx, moduleID, options) + ret0, _ := ret[0].(*tfe.RegistryModule) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Update indicates an expected call of Update. +func (mr *MockRegistryModulesMockRecorder) Update(ctx, moduleID, options interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockRegistryModules)(nil).Update), ctx, moduleID, options) +} + // Upload mocks base method. func (m *MockRegistryModules) Upload(ctx context.Context, rmv tfe.RegistryModuleVersion, path string) error { m.ctrl.T.Helper() diff --git a/registry_module.go b/registry_module.go index 464ed1810..bae9401aa 100644 --- a/registry_module.go +++ b/registry_module.go @@ -40,6 +40,9 @@ type RegistryModules interface { // Delete a specific registry module version DeleteVersion(ctx context.Context, moduleID RegistryModuleID, version string) error + // Update properties of a registry module + Update(ctx context.Context, moduleID RegistryModuleID, options RegistryModuleUpdateOptions) (*RegistryModule, 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. @@ -189,6 +192,18 @@ type RegistryModuleCreateWithVCSConnectionOptions struct { VCSRepo *RegistryModuleVCSRepoOptions `jsonapi:"attr,vcs-repo"` } +// RegistryModuleCreateVersionOptions is used when updating a registry module +type RegistryModuleUpdateOptions struct { + // Type is a public field utilized by JSON:API to + // set the resource type via the field tag. + // It is not a user-defined value and does not need to be set. + // https://jsonapi.org/format/#crud-updating + Type string `jsonapi:"primary,registry-modules"` + + // Optional: Flag to enable no-code provisioning for the whole module. + NoCode *bool `jsonapi:"attr,no-code,omitempty"` +} + type RegistryModuleVCSRepoOptions struct { Identifier *string `json:"identifier"` // Required OAuthTokenID *string `json:"oauth-token-id"` // Required @@ -265,6 +280,41 @@ func (r *registryModules) Create(ctx context.Context, organization string, optio return rm, nil } +func (r *registryModules) Update(ctx context.Context, moduleID RegistryModuleID, options RegistryModuleUpdateOptions) (*RegistryModule, error) { + if err := moduleID.valid(); err != nil { + return nil, err + } + + if moduleID.RegistryName == "" { + log.Println("[WARN] Support for using the RegistryModuleID without RegistryName is deprecated as of release 1.5.0 and may be removed in a future version. The preferred method is to include the RegistryName in RegistryModuleID.") + moduleID.RegistryName = PrivateRegistry + } + + if moduleID.RegistryName == PrivateRegistry && strings.TrimSpace(moduleID.Namespace) == "" { + log.Println("[WARN] Support for using the RegistryModuleID without Namespace is deprecated as of release 1.5.0 and may be removed in a future version. The preferred method is to include the Namespace in RegistryModuleID.") + moduleID.Namespace = moduleID.Organization + } + + org := url.QueryEscape(moduleID.Organization) + registryName := url.QueryEscape(string(moduleID.RegistryName)) + namespace := url.QueryEscape(moduleID.Namespace) + name := url.QueryEscape(moduleID.Name) + provider := url.QueryEscape(moduleID.Provider) + url := fmt.Sprintf("organizations/%s/registry-modules/%s/%s/%s/%s", org, registryName, namespace, name, provider) + + req, err := r.client.NewRequest(http.MethodPatch, url, &options) + if err != nil { + return nil, err + } + + rm := &RegistryModule{} + if err := req.Do(ctx, rm); err != nil { + return nil, err + } + + return rm, nil +} + // CreateVersion creates a new registry module version func (r *registryModules) CreateVersion(ctx context.Context, moduleID RegistryModuleID, options RegistryModuleCreateVersionOptions) (*RegistryModuleVersion, error) { if err := moduleID.valid(); err != nil { diff --git a/registry_module_integration_test.go b/registry_module_integration_test.go index fed3f6afd..20c34da46 100644 --- a/registry_module_integration_test.go +++ b/registry_module_integration_test.go @@ -231,6 +231,56 @@ func TestRegistryModulesCreate(t *testing.T) { }) } +func TestRegistryModuleUpdate(t *testing.T) { + skipIfBeta(t) + client := testClient(t) + ctx := context.Background() + + orgTest, orgTestCleanup := createOrganization(t, client) + defer orgTestCleanup() + + options := RegistryModuleCreateOptions{ + Name: String("vault"), + Provider: String("aws"), + RegistryName: PublicRegistry, + Namespace: "hashicorp", + } + rm, err := client.RegistryModules.Create(ctx, orgTest.Name, options) + require.NoError(t, err) + assert.NotEmpty(t, rm.ID) + + t.Run("enable no-code", func(t *testing.T) { + options := RegistryModuleUpdateOptions{ + NoCode: Bool(true), + } + rm, err := client.RegistryModules.Update(ctx, RegistryModuleID{ + Organization: orgTest.Name, + Name: "vault", + Provider: "aws", + Namespace: "hashicorp", + RegistryName: PublicRegistry, + }, options) + require.NoError(t, err) + assert.True(t, rm.NoCode) + }) + + t.Run("disable no-code", func(t *testing.T) { + options := RegistryModuleUpdateOptions{ + NoCode: Bool(false), + } + rm, err := client.RegistryModules.Update(ctx, RegistryModuleID{ + Organization: orgTest.Name, + Name: "vault", + Provider: "aws", + Namespace: "hashicorp", + RegistryName: PublicRegistry, + }, options) + require.NoError(t, err) + assert.False(t, rm.NoCode) + }) + +} + func TestRegistryModulesCreateVersion(t *testing.T) { skipIfNotCINode(t) From 9e91c72a0bacf56f5d785faf3568baa2ac54a239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Hern=C3=A1ndez?= Date: Tue, 25 Oct 2022 19:33:00 +0200 Subject: [PATCH 2/9] add no code properties to registry modules create --- registry_module.go | 4 ++++ registry_module_integration_test.go | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/registry_module.go b/registry_module.go index bae9401aa..2e28db5c9 100644 --- a/registry_module.go +++ b/registry_module.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "log" + "net/http" "net/url" "strings" ) @@ -107,6 +108,7 @@ type RegistryModule struct { Provider string `jsonapi:"attr,provider"` RegistryName RegistryName `jsonapi:"attr,registry-name"` Namespace string `jsonapi:"attr,namespace"` + NoCode bool `jsonapi:"attr,no-code"` Permissions *RegistryModulePermissions `jsonapi:"attr,permissions"` Status RegistryModuleStatus `jsonapi:"attr,status"` VCSRepo *VCSRepo `jsonapi:"attr,vcs-repo"` @@ -167,6 +169,8 @@ type RegistryModuleCreateOptions struct { RegistryName RegistryName `jsonapi:"attr,registry-name,omitempty"` // Optional: The namespace of this module. Required for public modules only. Namespace string `jsonapi:"attr,namespace,omitempty"` + // Optional: true if the module is enabled for no-code provisioning. + NoCode bool `jsonapi:"attr,no-code,omitempty"` } // RegistryModuleCreateVersionOptions is used when creating a registry module version diff --git a/registry_module_integration_test.go b/registry_module_integration_test.go index 20c34da46..508ec512a 100644 --- a/registry_module_integration_test.go +++ b/registry_module_integration_test.go @@ -144,6 +144,27 @@ func TestRegistryModulesCreate(t *testing.T) { assertRegistryModuleAttributes(t, rm) }) + + t.Run("with no-code attribute", func(t *testing.T) { + skipIfBeta(t) + options := RegistryModuleCreateOptions{ + Name: String("iam"), + Provider: String("aws"), + NoCode: true, + RegistryName: PrivateRegistry, + Namespace: "terraform-aws-modules", + } + rm, err := client.RegistryModules.Create(ctx, orgTest.Name, options) + require.NoError(t, err) + assert.NotEmpty(t, rm.ID) + assert.Equal(t, *options.Name, rm.Name) + assert.Equal(t, *options.Provider, rm.Provider) + assert.Equal(t, options.RegistryName, rm.RegistryName) + assert.Equal(t, options.Namespace, rm.Namespace) + assert.Equal(t, options.NoCode, rm.NoCode) + + assertRegistryModuleAttributes(t, rm) + }) }) t.Run("with invalid options", func(t *testing.T) { From d099f907a3bd7efc813f9cc652ac76fd2bf2ed26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Hern=C3=A1ndez?= Date: Wed, 26 Oct 2022 12:33:13 +0200 Subject: [PATCH 3/9] fix create module with no code attribute test --- registry_module_integration_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/registry_module_integration_test.go b/registry_module_integration_test.go index 508ec512a..18f8f3468 100644 --- a/registry_module_integration_test.go +++ b/registry_module_integration_test.go @@ -152,7 +152,6 @@ func TestRegistryModulesCreate(t *testing.T) { Provider: String("aws"), NoCode: true, RegistryName: PrivateRegistry, - Namespace: "terraform-aws-modules", } rm, err := client.RegistryModules.Create(ctx, orgTest.Name, options) require.NoError(t, err) @@ -160,7 +159,7 @@ func TestRegistryModulesCreate(t *testing.T) { assert.Equal(t, *options.Name, rm.Name) assert.Equal(t, *options.Provider, rm.Provider) assert.Equal(t, options.RegistryName, rm.RegistryName) - assert.Equal(t, options.Namespace, rm.Namespace) + assert.Equal(t, orgTest.Name, rm.Namespace) assert.Equal(t, options.NoCode, rm.NoCode) assertRegistryModuleAttributes(t, rm) From 1e612e9881a00a04ba84dba5dd83f025dbed78a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Hern=C3=A1ndez?= Date: Wed, 26 Oct 2022 12:33:23 +0200 Subject: [PATCH 4/9] add beta tags for the no code attributes --- registry_module.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/registry_module.go b/registry_module.go index 2e28db5c9..16d5a6d19 100644 --- a/registry_module.go +++ b/registry_module.go @@ -170,6 +170,7 @@ type RegistryModuleCreateOptions struct { // Optional: The namespace of this module. Required for public modules only. Namespace string `jsonapi:"attr,namespace,omitempty"` // Optional: true if the module is enabled for no-code provisioning. + // **Note: This field is still in BETA and subject to change.** NoCode bool `jsonapi:"attr,no-code,omitempty"` } @@ -205,6 +206,7 @@ type RegistryModuleUpdateOptions struct { Type string `jsonapi:"primary,registry-modules"` // Optional: Flag to enable no-code provisioning for the whole module. + // **Note: This field is still in BETA and subject to change.** NoCode *bool `jsonapi:"attr,no-code,omitempty"` } From f2ad9819aab708912211b3111f1792935e664f38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Hern=C3=A1ndez?= Date: Thu, 3 Nov 2022 14:17:59 +0100 Subject: [PATCH 5/9] Update registry_module.go Co-authored-by: UKEME BASSEY --- registry_module.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry_module.go b/registry_module.go index 16d5a6d19..3ebb41817 100644 --- a/registry_module.go +++ b/registry_module.go @@ -169,7 +169,7 @@ type RegistryModuleCreateOptions struct { RegistryName RegistryName `jsonapi:"attr,registry-name,omitempty"` // Optional: The namespace of this module. Required for public modules only. Namespace string `jsonapi:"attr,namespace,omitempty"` - // Optional: true if the module is enabled for no-code provisioning. + // Optional: If set to true the module is enabled for no-code provisioning. // **Note: This field is still in BETA and subject to change.** NoCode bool `jsonapi:"attr,no-code,omitempty"` } From 6bb5c5af1b3d0552ee5f97111a29057ef0689fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Hern=C3=A1ndez?= Date: Thu, 3 Nov 2022 14:53:56 +0100 Subject: [PATCH 6/9] add no-code module default value in create tests --- registry_module_integration_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/registry_module_integration_test.go b/registry_module_integration_test.go index 18f8f3468..7365e8c86 100644 --- a/registry_module_integration_test.go +++ b/registry_module_integration_test.go @@ -106,6 +106,7 @@ func TestRegistryModulesCreate(t *testing.T) { assert.Equal(t, *options.Provider, rm.Provider) assert.Equal(t, PrivateRegistry, rm.RegistryName) assert.Equal(t, orgTest.Name, rm.Namespace) + assert.False(t, rm.NoCode, "no-code module attribute should be false by default") assertRegistryModuleAttributes(t, rm) }) @@ -123,6 +124,7 @@ func TestRegistryModulesCreate(t *testing.T) { assert.Equal(t, *options.Provider, rm.Provider) assert.Equal(t, options.RegistryName, rm.RegistryName) assert.Equal(t, orgTest.Name, rm.Namespace) + assert.False(t, rm.NoCode, "no-code module attribute should be false by default") assertRegistryModuleAttributes(t, rm) }) @@ -141,6 +143,7 @@ func TestRegistryModulesCreate(t *testing.T) { assert.Equal(t, *options.Provider, rm.Provider) assert.Equal(t, options.RegistryName, rm.RegistryName) assert.Equal(t, options.Namespace, rm.Namespace) + assert.False(t, rm.NoCode, "no-code module attribute should be false by default") assertRegistryModuleAttributes(t, rm) }) From b1e5d0c784e8598f87ef5fb0d1aea06c2ee0e793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Hern=C3=A1ndez?= Date: Thu, 3 Nov 2022 17:52:59 +0100 Subject: [PATCH 7/9] add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 249057164..c3040fd9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Enhancements * Add OPA support to the Policy Set API's by @mrinalirao [#575](https://github.com/hashicorp/go-tfe/pull/575) +* Add support for enabling no-code provisioning in an existing or new `RegistryModule` by @miguelhrocha [#562](https://github.com/hashicorp/go-tfe/pull/562) # v1.12.0 From e0f218d20780224ce1aebac67687a6d8806ff67e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Hern=C3=A1ndez?= Date: Fri, 11 Nov 2022 15:01:18 +0100 Subject: [PATCH 8/9] Remove omitempty from RegistryModule's NoCode --- registry_module.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/registry_module.go b/registry_module.go index d02decefc..798a4a26b 100644 --- a/registry_module.go +++ b/registry_module.go @@ -171,7 +171,7 @@ type RegistryModuleCreateOptions struct { Namespace string `jsonapi:"attr,namespace,omitempty"` // Optional: If set to true the module is enabled for no-code provisioning. // **Note: This field is still in BETA and subject to change.** - NoCode bool `jsonapi:"attr,no-code,omitempty"` + NoCode bool `jsonapi:"attr,no-code"` } // RegistryModuleCreateVersionOptions is used when creating a registry module version @@ -207,7 +207,13 @@ type RegistryModuleUpdateOptions struct { // Optional: Flag to enable no-code provisioning for the whole module. // **Note: This field is still in BETA and subject to change.** - NoCode *bool `jsonapi:"attr,no-code,omitempty"` + + + + + + + *bool `jsonapi:"attr,no-code,omitempty"` } type RegistryModuleVCSRepoOptions struct { From 824b58b4b32f0a0d472000c1e8ca330066c9fe43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Hern=C3=A1ndez?= Date: Fri, 11 Nov 2022 15:05:49 +0100 Subject: [PATCH 9/9] Fix NoCode Update struct --- registry_module.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/registry_module.go b/registry_module.go index 798a4a26b..ee8698ff2 100644 --- a/registry_module.go +++ b/registry_module.go @@ -207,13 +207,7 @@ type RegistryModuleUpdateOptions struct { // Optional: Flag to enable no-code provisioning for the whole module. // **Note: This field is still in BETA and subject to change.** - - - - - - - *bool `jsonapi:"attr,no-code,omitempty"` + NoCode *bool `jsonapi:"attr,no-code,omitempty"` } type RegistryModuleVCSRepoOptions struct {