Skip to content

Commit 38b1295

Browse files
Added support for data source google_secret_manager_secrets (#9099) (#16182)
* Added support for data source google_secret_manager_secrets * Updated the description for filter field [upstream:0dd0ab0a6068edbf09a96529a05eb39d4d94c9b9] Signed-off-by: Modular Magician <[email protected]>
1 parent f0f0ae1 commit 38b1295

File tree

5 files changed

+529
-0
lines changed

5 files changed

+529
-0
lines changed

.changelog/9099.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:new-datasource
2+
`google_secret_manager_secrets`
3+
```

google/provider/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,7 @@ func DatasourceMapWithErrors() (map[string]*schema.Resource, error) {
870870
"google_pubsub_subscription": pubsub.DataSourceGooglePubsubSubscription(),
871871
"google_pubsub_topic": pubsub.DataSourceGooglePubsubTopic(),
872872
"google_secret_manager_secret": secretmanager.DataSourceSecretManagerSecret(),
873+
"google_secret_manager_secrets": secretmanager.DataSourceSecretManagerSecrets(),
873874
"google_secret_manager_secret_version": secretmanager.DataSourceSecretManagerSecretVersion(),
874875
"google_secret_manager_secret_version_access": secretmanager.DataSourceSecretManagerSecretVersionAccess(),
875876
"google_service_account": resourcemanager.DataSourceGoogleServiceAccount(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
package secretmanager
4+
5+
import (
6+
"fmt"
7+
"strings"
8+
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
10+
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
11+
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
12+
)
13+
14+
func DataSourceSecretManagerSecrets() *schema.Resource {
15+
16+
dsSchema := tpgresource.DatasourceSchemaFromResourceSchema(ResourceSecretManagerSecret().Schema)
17+
18+
return &schema.Resource{
19+
Read: dataSourceSecretManagerSecretsRead,
20+
Schema: map[string]*schema.Schema{
21+
"project": {
22+
Type: schema.TypeString,
23+
Optional: true,
24+
Computed: true,
25+
},
26+
"filter": {
27+
Type: schema.TypeString,
28+
Description: `Filter string, adhering to the rules in List-operation filtering (https://cloud.google.com/secret-manager/docs/filtering).
29+
List only secrets matching the filter. If filter is empty, all secrets are listed.`,
30+
Optional: true,
31+
},
32+
"secrets": {
33+
Type: schema.TypeList,
34+
Computed: true,
35+
Elem: &schema.Resource{
36+
Schema: dsSchema,
37+
},
38+
},
39+
},
40+
}
41+
}
42+
43+
func dataSourceSecretManagerSecretsRead(d *schema.ResourceData, meta interface{}) error {
44+
config := meta.(*transport_tpg.Config)
45+
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
46+
if err != nil {
47+
return err
48+
}
49+
50+
url, err := tpgresource.ReplaceVars(d, config, "{{SecretManagerBasePath}}projects/{{project}}/secrets")
51+
if err != nil {
52+
return err
53+
}
54+
55+
filter, has_filter := d.GetOk("filter")
56+
57+
if has_filter {
58+
url, err = transport_tpg.AddQueryParams(url, map[string]string{"filter": filter.(string)})
59+
if err != nil {
60+
return err
61+
}
62+
}
63+
64+
billingProject := ""
65+
66+
project, err := tpgresource.GetProject(d, config)
67+
if err != nil {
68+
return fmt.Errorf("Error fetching project for Secret: %s", err)
69+
}
70+
billingProject = project
71+
72+
// err == nil indicates that the billing_project value was found
73+
if bp, err := tpgresource.GetBillingProject(d, config); err == nil {
74+
billingProject = bp
75+
}
76+
77+
// To handle the pagination locally
78+
allSecrets := make([]interface{}, 0)
79+
token := ""
80+
for paginate := true; paginate; {
81+
if token != "" {
82+
url, err = transport_tpg.AddQueryParams(url, map[string]string{"pageToken": token})
83+
if err != nil {
84+
return err
85+
}
86+
}
87+
secrets, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
88+
Config: config,
89+
Method: "GET",
90+
Project: billingProject,
91+
RawURL: url,
92+
UserAgent: userAgent,
93+
})
94+
if err != nil {
95+
return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("SecretManagerSecrets %q", d.Id()))
96+
}
97+
secretsInterface := secrets["secrets"]
98+
if secretsInterface == nil {
99+
break
100+
}
101+
allSecrets = append(allSecrets, secretsInterface.([]interface{})...)
102+
tokenInterface := secrets["nextPageToken"]
103+
if tokenInterface == nil {
104+
paginate = false
105+
} else {
106+
paginate = true
107+
token = tokenInterface.(string)
108+
}
109+
}
110+
111+
if err := d.Set("secrets", flattenSecretManagerSecretsSecrets(allSecrets, d, config)); err != nil {
112+
return fmt.Errorf("error setting secrets: %s", err)
113+
}
114+
115+
if err := d.Set("project", project); err != nil {
116+
return fmt.Errorf("error setting project: %s", err)
117+
}
118+
119+
if err := d.Set("filter", filter); err != nil {
120+
return fmt.Errorf("error setting filter: %s", err)
121+
}
122+
123+
// Store the ID now
124+
id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/secrets")
125+
if err != nil {
126+
return fmt.Errorf("Error constructing id: %s", err)
127+
}
128+
if has_filter {
129+
id += "/filter=" + filter.(string)
130+
}
131+
d.SetId(id)
132+
133+
return nil
134+
}
135+
136+
func flattenSecretManagerSecretsSecrets(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
137+
if v == nil {
138+
return v
139+
}
140+
l := v.([]interface{})
141+
transformed := make([]interface{}, 0, len(l))
142+
for _, raw := range l {
143+
original := raw.(map[string]interface{})
144+
if len(original) < 1 {
145+
// Do not include empty json objects coming back from the api
146+
continue
147+
}
148+
transformed = append(transformed, map[string]interface{}{
149+
"replication": flattenSecretManagerSecretReplication(original["replication"], d, config),
150+
"annotations": flattenSecretManagerSecretAnnotations(original["annotations"], d, config),
151+
"expire_time": flattenSecretManagerSecretExpireTime(original["expireTime"], d, config),
152+
"labels": flattenSecretManagerSecretLabels(original["labels"], d, config),
153+
"rotation": flattenSecretManagerSecretRotation(original["rotation"], d, config),
154+
"topics": flattenSecretManagerSecretTopics(original["topics"], d, config),
155+
"version_aliases": flattenSecretManagerSecretVersionAliases(original["versionAliases"], d, config),
156+
"create_time": flattenSecretManagerSecretCreateTime(original["createTime"], d, config),
157+
"name": flattenSecretManagerSecretName(original["name"], d, config),
158+
"project": getDataFromName(original["name"], 1),
159+
"secret_id": getDataFromName(original["name"], 3),
160+
})
161+
}
162+
return transformed
163+
}
164+
165+
func getDataFromName(v interface{}, part int) string {
166+
name := v.(string)
167+
split := strings.Split(name, "/")
168+
return split[part]
169+
}

0 commit comments

Comments
 (0)