Skip to content

Commit 9c344ee

Browse files
authored
feat: add SN Cloud secrets support (#141)
1 parent c5cb7e7 commit 9c344ee

File tree

11 files changed

+927
-11
lines changed

11 files changed

+927
-11
lines changed

.github/workflows/acctest.yml

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# limitations under the License.
1414

1515
name: Tests
16-
on: [ pull_request ]
16+
on: [pull_request]
1717
jobs:
1818
acctest:
1919
name: Run acceptance tests
@@ -53,11 +53,19 @@ jobs:
5353
sudo mv terraform-provider-streamnative $HOME/.terraform.d/plugins/linux_amd64/
5454
echo "The terraform-provider-streamnative location:" `readlink -f $HOME/.terraform.d/plugins/linux_amd64/`
5555
56-
# - name: Setup tmate session
57-
# uses: mxschmitt/action-tmate@v3
56+
# - name: Setup tmate session
57+
# uses: mxschmitt/action-tmate@v3
5858

59-
- name: Run Acceptance Tests for the Provider
59+
- name: Ready the environment
6060
run: |
6161
echo $ACC_TEST_SERVICE_ACCOUNT > $HOME/service_account.json
62-
export KEY_FILE_PATH=$HOME/service_account.json
63-
make testacc
62+
63+
- name: Run Acceptance Tests for the Provider
64+
uses: nick-fields/retry@v2
65+
with:
66+
timeout_minutes: 120
67+
max_attempts: 3
68+
retry_on: error
69+
command: |
70+
export KEY_FILE_PATH=$HOME/service_account.json
71+
make testacc

cloud/data_source_secret.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright 2024 StreamNative, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package cloud
16+
17+
import (
18+
"context"
19+
"fmt"
20+
"strings"
21+
22+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
23+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
24+
apierrors "k8s.io/apimachinery/pkg/api/errors"
25+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26+
)
27+
28+
func dataSourceSecret() *schema.Resource {
29+
return &schema.Resource{
30+
ReadContext: dataSourceSecretRead,
31+
Importer: &schema.ResourceImporter{
32+
StateContext: func(
33+
ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
34+
parts := strings.Split(d.Id(), "/")
35+
if len(parts) != 2 {
36+
return nil, fmt.Errorf("invalid import id %q, expected <organization>/<name>", d.Id())
37+
}
38+
_ = d.Set("organization", parts[0])
39+
_ = d.Set("name", parts[1])
40+
if diags := dataSourceSecretRead(ctx, d, meta); diags.HasError() {
41+
return nil, fmt.Errorf("import %q: %s", d.Id(), diags[0].Summary)
42+
}
43+
return []*schema.ResourceData{d}, nil
44+
},
45+
},
46+
Schema: map[string]*schema.Schema{
47+
"organization": {
48+
Type: schema.TypeString,
49+
Required: true,
50+
Description: descriptions["organization"],
51+
ValidateFunc: validateNotBlank,
52+
},
53+
"name": {
54+
Type: schema.TypeString,
55+
Required: true,
56+
Description: descriptions["secret_name"],
57+
ValidateFunc: validateNotBlank,
58+
},
59+
"instance_name": {
60+
Type: schema.TypeString,
61+
Computed: true,
62+
Description: descriptions["instance_name"],
63+
},
64+
"location": {
65+
Type: schema.TypeString,
66+
Computed: true,
67+
Description: descriptions["location"],
68+
},
69+
"pool_member_name": {
70+
Type: schema.TypeString,
71+
Computed: true,
72+
Description: descriptions["pool_member_name"],
73+
},
74+
"type": {
75+
Type: schema.TypeString,
76+
Computed: true,
77+
Description: descriptions["secret_type"],
78+
},
79+
"data": {
80+
Type: schema.TypeMap,
81+
Computed: true,
82+
Sensitive: true,
83+
Description: descriptions["secret_data"],
84+
Elem: &schema.Schema{
85+
Type: schema.TypeString,
86+
},
87+
},
88+
},
89+
}
90+
}
91+
92+
func dataSourceSecretRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
93+
namespace := d.Get("organization").(string)
94+
name := d.Get("name").(string)
95+
96+
clientSet, err := getClientSet(getFactoryFromMeta(meta))
97+
if err != nil {
98+
return diag.FromErr(fmt.Errorf("ERROR_INIT_CLIENT_ON_READ_SECRET: %w", err))
99+
}
100+
101+
secret, err := clientSet.CloudV1alpha1().Secrets(namespace).Get(ctx, name, metav1.GetOptions{})
102+
if err != nil {
103+
if apierrors.IsNotFound(err) {
104+
d.SetId("")
105+
return nil
106+
}
107+
return diag.FromErr(fmt.Errorf("ERROR_READ_SECRET: %w", err))
108+
}
109+
110+
return setSecretState(d, secret)
111+
}

cloud/provider.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ func init() {
6565
"cluster_display_name": "The pulsar cluster display name",
6666
"admin": "Whether the service account is admin",
6767
"private_key_data": "The private key data",
68+
"secret_name": "The secret name",
69+
"secret_data": "The secret data map",
70+
"secret_string_data": "Write-only string data that will be stored encrypted by the API server",
71+
"secret_type": "The Kubernetes secret type",
6872
"availability-mode": "The availability mode, supporting 'zonal' and 'regional'",
6973
"pool_name": "The infrastructure pool name",
7074
"pool_namespace": "The infrastructure pool namespace",
@@ -249,6 +253,7 @@ func Provider() *schema.Provider {
249253
"streamnative_rolebinding": resourceRoleBinding(),
250254
"streamnative_volume": resourceVolume(),
251255
"streamnative_catalog": resourceCatalog(),
256+
"streamnative_secret": resourceSecret(),
252257
},
253258
DataSourcesMap: map[string]*schema.Resource{
254259
"streamnative_service_account": dataSourceServiceAccount(),
@@ -265,6 +270,7 @@ func Provider() *schema.Provider {
265270
"streamnative_rolebinding": dataSourceRoleBinding(),
266271
"streamnative_volume": dataSourceVolume(),
267272
"streamnative_catalog": dataSourceCatalog(),
273+
"streamnative_secret": dataSourceSecret(),
268274
},
269275
}
270276
provider.ConfigureContextFunc = func(_ context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {

cloud/resource_pulsar_cluster.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ func resourcePulsarCluster() *schema.Resource {
6767
return []*schema.ResourceData{d}, nil
6868
},
6969
},
70+
Timeouts: &schema.ResourceTimeout{
71+
// Pulsar clusters can take time to tear down; allow 30m to avoid spurious test failures.
72+
Delete: schema.DefaultTimeout(30 * time.Minute),
73+
},
7074
Schema: map[string]*schema.Schema{
7175
"organization": {
7276
Type: schema.TypeString,

0 commit comments

Comments
 (0)