Skip to content

Commit ad0a35f

Browse files
committed
working secret resource with tests
Signed-off-by: Will Arroyo <warroyo7199008@gmail.com>
1 parent 4a303a9 commit ad0a35f

File tree

6 files changed

+127
-53
lines changed

6 files changed

+127
-53
lines changed

internal/resources/kubernetessecret/data_source_secret.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,14 @@ func dataSourceSecretRead(ctx context.Context, d *schema.ResourceData, m interfa
7979
d.SetId(secretDataFromServer.UID)
8080

8181
var password string
82+
var opaqueData map[string]interface{}
8283

83-
if _, ok := d.GetOk(spec.SpecKey); ok {
84+
if _, ok := d.GetOk(helper.GetFirstElementOf(spec.SpecKey, spec.DockerConfigjsonKey, spec.PasswordKey)); ok {
8485
password, _ = (d.Get(helper.GetFirstElementOf(spec.SpecKey, spec.DockerConfigjsonKey, spec.PasswordKey))).(string)
8586
}
87+
if opData, ok := d.GetOk(helper.GetFirstElementOf(spec.SpecKey, spec.OpaqueKey)); ok && opData != nil {
88+
opaqueData = opData.(map[string]interface{})
89+
}
8690

8791
if d.Get(ExportKey).(bool) {
8892
if secretDataFromServer.secretExportErr != nil || secretDataFromServer.secretExportRespNil {
@@ -121,13 +125,13 @@ func dataSourceSecretRead(ctx context.Context, d *schema.ResourceData, m interfa
121125

122126
switch scopedFullnameData.Scope {
123127
case commonscope.ClusterScope:
124-
flattenedSpec = spec.FlattenSpecForClusterScope(ctx, secretDataFromServer.atomicSpec, password)
128+
flattenedSpec = spec.FlattenSpecForClusterScope(secretDataFromServer.atomicSpec, password, opaqueData)
125129
flattenedStatus = status.FlattenStatusForClusterScope(secretDataFromServer.clusterScopeStatus)
126130
case commonscope.ClusterGroupScope:
127131
clusterGroupScopeSpec := &secretclustergroupmodel.VmwareTanzuManageV1alpha1ClustergroupNamespaceSecretSpec{
128132
AtomicSpec: secretDataFromServer.atomicSpec,
129133
}
130-
flattenedSpec = spec.FlattenSpecForClusterGroupScope(ctx, clusterGroupScopeSpec, password)
134+
flattenedSpec = spec.FlattenSpecForClusterGroupScope(clusterGroupScopeSpec, password, opaqueData)
131135
flattenedStatus = status.FlattenStatusForClusterGroupScope(secretDataFromServer.clusterGroupScopeStatus)
132136
}
133137

internal/resources/kubernetessecret/resource_secret.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func ResourceSecret() *schema.Resource {
4141
Schema: getResourceSchema(),
4242
CustomizeDiff: customdiff.All(
4343
schema.CustomizeDiffFunc(commonscope.ValidateScope(scope.ScopesAllowed[:])),
44+
spec.ValidateInput,
4445
),
4546
}
4647
}
@@ -138,7 +139,7 @@ func resourceSecretCreate(ctx context.Context, d *schema.ResourceData, m interfa
138139
Secret: &clustersecretmodel.VmwareTanzuManageV1alpha1ClusterNamespaceSecret{
139140
FullName: scopedFullnameData.FullnameCluster,
140141
Meta: meta,
141-
Spec: spec.ConstructSpecForClusterScope(ctx, d),
142+
Spec: spec.ConstructSpecForClusterScope(d),
142143
},
143144
}
144145

@@ -155,7 +156,7 @@ func resourceSecretCreate(ctx context.Context, d *schema.ResourceData, m interfa
155156
Secret: &clustergroupsecretmodel.VmwareTanzuManageV1alpha1ClustergroupNamespaceSecretSecret{
156157
FullName: scopedFullnameData.FullnameClusterGroup,
157158
Meta: meta,
158-
Spec: spec.ConstructSpecForClusterGroupScope(ctx, d),
159+
Spec: spec.ConstructSpecForClusterGroupScope(d),
159160
},
160161
}
161162

@@ -349,9 +350,9 @@ func updateCheckForSpec(ctx context.Context, d *schema.ResourceData, atomicSpec
349350

350351
switch scope {
351352
case commonscope.ClusterScope:
352-
secretSpec = spec.ConstructSpecForClusterScope(ctx, d)
353+
secretSpec = spec.ConstructSpecForClusterScope(d)
353354
case commonscope.ClusterGroupScope:
354-
clusterGroupScopeSpec := spec.ConstructSpecForClusterGroupScope(ctx, d)
355+
clusterGroupScopeSpec := spec.ConstructSpecForClusterGroupScope(d)
355356
secretSpec = clusterGroupScopeSpec.AtomicSpec
356357
}
357358

internal/resources/kubernetessecret/spec/cluster_group_scope.go

+4-6
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@ SPDX-License-Identifier: MPL-2.0
66
package spec
77

88
import (
9-
"context"
10-
119
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1210

1311
secertclustergroupmodel "github.com/vmware/terraform-provider-tanzu-mission-control/internal/models/kubernetessecret/clustergroup"
1412
)
1513

16-
func ConstructSpecForClusterGroupScope(ctx context.Context, d *schema.ResourceData) (spec *secertclustergroupmodel.VmwareTanzuManageV1alpha1ClustergroupNamespaceSecretSpec) {
14+
func ConstructSpecForClusterGroupScope(d *schema.ResourceData) (spec *secertclustergroupmodel.VmwareTanzuManageV1alpha1ClustergroupNamespaceSecretSpec) {
1715
value, ok := d.GetOk(SpecKey)
1816
if !ok {
1917
return spec
@@ -26,15 +24,15 @@ func ConstructSpecForClusterGroupScope(ctx context.Context, d *schema.ResourceDa
2624
}
2725

2826
spec = &secertclustergroupmodel.VmwareTanzuManageV1alpha1ClustergroupNamespaceSecretSpec{}
29-
spec.AtomicSpec = ConstructSpecForClusterScope(ctx, d)
27+
spec.AtomicSpec = ConstructSpecForClusterScope(d)
3028

3129
return spec
3230
}
3331

34-
func FlattenSpecForClusterGroupScope(ctx context.Context, spec *secertclustergroupmodel.VmwareTanzuManageV1alpha1ClustergroupNamespaceSecretSpec, password string) (data []interface{}) {
32+
func FlattenSpecForClusterGroupScope(spec *secertclustergroupmodel.VmwareTanzuManageV1alpha1ClustergroupNamespaceSecretSpec, password string, opaqueData map[string]interface{}) (data []interface{}) {
3533
if spec == nil || spec.AtomicSpec == nil {
3634
return data
3735
}
3836

39-
return FlattenSpecForClusterScope(ctx, spec.AtomicSpec, password)
37+
return FlattenSpecForClusterScope(spec.AtomicSpec, password, opaqueData)
4038
}

internal/resources/kubernetessecret/spec/cluster_scope.go

+17-33
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,18 @@ SPDX-License-Identifier: MPL-2.0
66
package spec
77

88
import (
9-
"context"
109
"encoding/base64"
1110
"encoding/json"
1211
"fmt"
1312

14-
"github.com/hashicorp/terraform-plugin-log/tflog"
15-
1613
"github.com/go-openapi/strfmt"
1714
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1815
"github.com/vmware/terraform-provider-tanzu-mission-control/internal/resources/common"
1916

2017
secretmodel "github.com/vmware/terraform-provider-tanzu-mission-control/internal/models/kubernetessecret/cluster"
2118
)
2219

23-
func ConstructSpecForClusterScope(ctx context.Context, d *schema.ResourceData) (spec *secretmodel.VmwareTanzuManageV1alpha1ClusterNamespaceSecretSpec) {
20+
func ConstructSpecForClusterScope(d *schema.ResourceData) (spec *secretmodel.VmwareTanzuManageV1alpha1ClusterNamespaceSecretSpec) {
2421
spec = &secretmodel.VmwareTanzuManageV1alpha1ClusterNamespaceSecretSpec{}
2522

2623
value, ok := d.GetOk(SpecKey)
@@ -68,25 +65,21 @@ func ConstructSpecForClusterScope(ctx context.Context, d *schema.ResourceData) (
6865
}
6966

7067
if v, ok := specData[OpaqueKey]; ok {
71-
tflog.Info(ctx, "MAde it to opaque")
7268

7369
opaqueData := common.GetTypeStringMapData(v.(map[string]interface{}))
7470
if len(opaqueData) != 0 {
7571
spec.SecretType = secretmodel.NewVmwareTanzuManageV1alpha1ClusterNamespaceSecretType(secretmodel.VmwareTanzuManageV1alpha1ClusterNamespaceSecretTypeSECRETTYPEOPAQUE)
76-
tflog.Info(ctx, fmt.Sprintf("testing %v", opaqueData))
7772

78-
encodedData := getEncodedOpaqueData(ctx, opaqueData)
79-
tflog.Info(ctx, fmt.Sprintf("%v", encodedData))
73+
encodedData := getEncodedOpaqueData(opaqueData)
8074
spec.Data = encodedData
8175
}
8276

8377
}
8478

85-
tflog.Info(ctx, "returning")
8679
return spec
8780
}
8881

89-
func FlattenSpecForClusterScope(ctx context.Context, spec *secretmodel.VmwareTanzuManageV1alpha1ClusterNamespaceSecretSpec, pass string) (data []interface{}) {
82+
func FlattenSpecForClusterScope(spec *secretmodel.VmwareTanzuManageV1alpha1ClusterNamespaceSecretSpec, pass string, opaqueData map[string]interface{}) (data []interface{}) {
9083
if spec == nil {
9184
return data
9285
}
@@ -126,15 +119,8 @@ func FlattenSpecForClusterScope(ctx context.Context, spec *secretmodel.VmwareTan
126119
}
127120

128121
if *spec.SecretType == *secretmodel.NewVmwareTanzuManageV1alpha1ClusterNamespaceSecretType(secretmodel.VmwareTanzuManageV1alpha1ClusterNamespaceSecretTypeSECRETTYPEOPAQUE) {
129-
tflog.Info(ctx, "secret type opaque")
130-
secretData := spec.Data
131-
decodedData, err := getDecodedOpaqueData(secretData)
132-
if err != nil {
133-
return data
134-
}
135-
tflog.Info(ctx, fmt.Sprintf("%v", decodedData))
136122

137-
flattenSpecData[OpaqueKey] = []interface{}{decodedData}
123+
flattenSpecData[OpaqueKey] = opaqueData
138124
}
139125

140126
return []interface{}{flattenSpecData}
@@ -169,27 +155,25 @@ func getDecodedSpecData(data strfmt.Base64) (*dockerConfigJSON, error) {
169155
return dockerConfigJSON, nil
170156
}
171157

172-
func getEncodedOpaqueData(ctx context.Context, data map[string]string) map[string]strfmt.Base64 {
158+
func getEncodedOpaqueData(data map[string]string) map[string]strfmt.Base64 {
173159
encoded := make(map[string]strfmt.Base64)
174160

175161
for k, v := range data {
176-
tflog.Info(ctx, v)
177162
encoded[k] = strfmt.Base64(v)
178-
tflog.Info(ctx, string(encoded[k]))
179163
}
180164

181165
return encoded
182166
}
183167

184-
func getDecodedOpaqueData(data map[string]strfmt.Base64) (map[string]string, error) {
185-
decoded := make(map[string]string)
186-
for k, v := range data {
187-
decodedValue, err := base64.StdEncoding.DecodeString(v.String())
188-
if err != nil {
189-
return nil, err
190-
}
191-
decoded[k] = string(decodedValue)
192-
}
193-
194-
return decoded, nil
195-
}
168+
// func getDecodedOpaqueData(data map[string]strfmt.Base64) (map[string]string, error) {
169+
// decoded := make(map[string]string)
170+
// for k, v := range data {
171+
// decodedValue, err := base64.StdEncoding.DecodeString(v.String())
172+
// if err != nil {
173+
// return nil, err
174+
// }
175+
// decoded[k] = string(decodedValue)
176+
// }
177+
178+
// return decoded, nil
179+
// }

internal/resources/kubernetessecret/spec/spec.go

+52-3
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,15 @@ SPDX-License-Identifier: MPL-2.0
66
package spec
77

88
import (
9+
"context"
10+
"fmt"
11+
"strings"
12+
913
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1014
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1115

1216
"github.com/vmware/terraform-provider-tanzu-mission-control/internal/helper"
17+
"github.com/vmware/terraform-provider-tanzu-mission-control/internal/resources/gitrepository/spec"
1318
)
1419

1520
const (
@@ -38,11 +43,14 @@ var SecretSpec = &schema.Schema{
3843
Type: schema.TypeMap,
3944
Description: "SecretType definition - SECRET_TYPE_OPAQUE, Kubernetes secrets type.",
4045
Optional: true,
41-
Elem: &schema.Schema{Type: schema.TypeString},
46+
Sensitive: true,
47+
48+
Elem: &schema.Schema{Type: schema.TypeString},
4249
},
4350
DockerConfigjsonKey: {
44-
Type: schema.TypeList,
45-
Optional: true,
51+
Type: schema.TypeList,
52+
Optional: true,
53+
4654
Description: "SecretType definition - SECRET_TYPE_DOCKERCONFIGJSON, Kubernetes secrets type.",
4755
Elem: &schema.Resource{
4856
Schema: map[string]*schema.Schema{
@@ -97,3 +105,44 @@ func HasSpecChanged(d *schema.ResourceData) bool {
97105

98106
return updateRequired
99107
}
108+
109+
func ValidateInput(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error {
110+
value, ok := diff.GetOk(spec.SpecKey)
111+
if !ok {
112+
return fmt.Errorf("spec: %v is not valid: minimum one valid spec block is required", value)
113+
}
114+
115+
data, _ := value.([]interface{})
116+
117+
specData := data[0].(map[string]interface{})
118+
secretTypes := []string{
119+
OpaqueKey,
120+
DockerConfigjsonKey,
121+
}
122+
secretTypesFound := make([]string, 0)
123+
124+
for _, secret := range secretTypes {
125+
if secretData, ok := specData[secret]; ok {
126+
if secret == OpaqueKey {
127+
converted := secretData.(map[string]interface{})
128+
if len(converted) != 0 {
129+
secretTypesFound = append(secretTypesFound, secret)
130+
}
131+
}
132+
if secret == DockerConfigjsonKey {
133+
converted := secretData.([]interface{})
134+
if len(converted) != 0 {
135+
secretTypesFound = append(secretTypesFound, secret)
136+
}
137+
}
138+
139+
}
140+
}
141+
142+
if len(secretTypesFound) == 0 {
143+
return fmt.Errorf("no valid spec block found: minimum one valid secret block is required among: %v", strings.Join(secretTypes[:], `, `))
144+
} else if len(secretTypesFound) > 1 {
145+
return fmt.Errorf("found secret blocks: %v are not valid: maximum one valid secret block is allowed", strings.Join(secretTypesFound, `, `))
146+
}
147+
return nil
148+
}

internal/resources/kubernetessecret/spec/spec_flatten_test.go

+42-4
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func TestFlattenClusterScopeSpec(t *testing.T) {
2929
expected: nil,
3030
},
3131
{
32-
description: "normal scenario with all values under spec",
32+
description: "registry secret test",
3333
input: &secretclustermodel.VmwareTanzuManageV1alpha1ClusterNamespaceSecretSpec{
3434
SecretType: secretclustermodel.NewVmwareTanzuManageV1alpha1ClusterNamespaceSecretType(secretclustermodel.VmwareTanzuManageV1alpha1ClusterNamespaceSecretTypeSECRETTYPEDOCKERCONFIGJSON),
3535
Data: map[string]strfmt.Base64{
@@ -48,12 +48,30 @@ func TestFlattenClusterScopeSpec(t *testing.T) {
4848
},
4949
},
5050
},
51+
{
52+
description: "opaque secret test",
53+
input: &secretclustermodel.VmwareTanzuManageV1alpha1ClusterNamespaceSecretSpec{
54+
SecretType: secretclustermodel.NewVmwareTanzuManageV1alpha1ClusterNamespaceSecretType(secretclustermodel.VmwareTanzuManageV1alpha1ClusterNamespaceSecretTypeSECRETTYPEOPAQUE),
55+
Data: map[string]strfmt.Base64{
56+
"username": []byte(`myuser`),
57+
"password": []byte(`somelongpassword`),
58+
},
59+
},
60+
expected: []interface{}{
61+
map[string]interface{}{
62+
OpaqueKey: map[string]interface{}{
63+
"username": "myuser",
64+
"password": "somelongpassword",
65+
},
66+
},
67+
},
68+
},
5169
}
5270

5371
for _, each := range cases {
5472
test := each
5573
t.Run(test.description, func(t *testing.T) {
56-
actual := FlattenSpecForClusterScope(test.input, "somepassword")
74+
actual := FlattenSpecForClusterScope(test.input, "somepassword", map[string]interface{}{"username": "myuser", "password": "somelongpassword"})
5775
require.Equal(t, test.expected, actual)
5876
})
5977
}
@@ -73,7 +91,7 @@ func TestFlattenClusterGroupScopeSpec(t *testing.T) {
7391
expected: nil,
7492
},
7593
{
76-
description: "normal scenario with all values under spec",
94+
description: "normal scenario for registry secret with all values under spec",
7795
input: &secretclustergroupmodel.VmwareTanzuManageV1alpha1ClustergroupNamespaceSecretSpec{
7896
AtomicSpec: &secretclustermodel.VmwareTanzuManageV1alpha1ClusterNamespaceSecretSpec{
7997
SecretType: secretclustermodel.NewVmwareTanzuManageV1alpha1ClusterNamespaceSecretType(secretclustermodel.VmwareTanzuManageV1alpha1ClusterNamespaceSecretTypeSECRETTYPEDOCKERCONFIGJSON),
@@ -94,12 +112,32 @@ func TestFlattenClusterGroupScopeSpec(t *testing.T) {
94112
},
95113
},
96114
},
115+
{
116+
description: "normal scenario for opaque secret with all values under spec",
117+
input: &secretclustergroupmodel.VmwareTanzuManageV1alpha1ClustergroupNamespaceSecretSpec{
118+
AtomicSpec: &secretclustermodel.VmwareTanzuManageV1alpha1ClusterNamespaceSecretSpec{
119+
SecretType: secretclustermodel.NewVmwareTanzuManageV1alpha1ClusterNamespaceSecretType(secretclustermodel.VmwareTanzuManageV1alpha1ClusterNamespaceSecretTypeSECRETTYPEOPAQUE),
120+
Data: map[string]strfmt.Base64{
121+
"username": []byte(`myuser`),
122+
"password": []byte(`somelongpassword`),
123+
},
124+
},
125+
},
126+
expected: []interface{}{
127+
map[string]interface{}{
128+
OpaqueKey: map[string]interface{}{
129+
"username": "myuser",
130+
"password": "somelongpassword",
131+
},
132+
},
133+
},
134+
},
97135
}
98136

99137
for _, each := range cases {
100138
test := each
101139
t.Run(test.description, func(t *testing.T) {
102-
actual := FlattenSpecForClusterGroupScope(test.input, "somepassword")
140+
actual := FlattenSpecForClusterGroupScope(test.input, "somepassword", map[string]interface{}{"username": "myuser", "password": "somelongpassword"})
103141
require.Equal(t, test.expected, actual)
104142
})
105143
}

0 commit comments

Comments
 (0)