Skip to content

Commit ece4899

Browse files
committed
add support for UPLOAD, CREATE, FETCH in ephemeral resource
1 parent 0da5fb9 commit ece4899

File tree

2 files changed

+191
-121
lines changed

2 files changed

+191
-121
lines changed

mmv1/third_party/terraform/services/resourcemanager/ephemeral_google_service_account_key.go

Lines changed: 121 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,14 @@
11
// Copyright (c) HashiCorp, Inc.
22
// SPDX-License-Identifier: MPL-2.0
3-
// ----------------------------------------------------------------------------
4-
//
5-
// *** AUTO GENERATED CODE *** Type: Handwritten ***
6-
//
7-
// ----------------------------------------------------------------------------
8-
//
9-
// This code is generated by Magic Modules using the following:
10-
//
11-
// Source file: https://github.com/GoogleCloudPlatform/magic-modules/tree/main/mmv1/third_party/terraform/services/resourcemanager/ephemeral_google_service_account_key.go
12-
//
13-
// DO NOT EDIT this file directly. Any changes made to this file will be
14-
// overwritten during the next generation cycle.
15-
//
16-
// ----------------------------------------------------------------------------
173
package resourcemanager
184

195
import (
206
"context"
7+
"encoding/json"
218
"fmt"
9+
"log"
2210
"regexp"
23-
24-
sdkSchema "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
11+
"time"
2512

2613
"github.com/hashicorp/terraform-plugin-framework-validators/ephemeralvalidator"
2714
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
@@ -51,23 +38,24 @@ func (p *googleEphemeralServiceAccountKey) Metadata(ctx context.Context, req eph
5138
}
5239

5340
type ephemeralServiceAccountKeyModel struct {
41+
FetchKey types.Bool `tfsdk:"fetch_key"`
5442
ServiceAccountId types.String `tfsdk:"service_account_id"`
5543
Name types.String `tfsdk:"name"`
5644
PublicKeyType types.String `tfsdk:"public_key_type"`
5745
KeyAlgorithm types.String `tfsdk:"key_algorithm"`
58-
PublicKey types.String `tfsdk:"public_key"`
46+
PublicKeyData types.String `tfsdk:"public_key_data"`
5947
PrivateKey types.String `tfsdk:"private_key"`
6048
PrivateKeyType types.String `tfsdk:"private_key_type"`
6149
}
6250

6351
func (p *googleEphemeralServiceAccountKey) ConfigValidators(ctx context.Context) []ephemeral.ConfigValidator {
6452
return []ephemeral.ConfigValidator{
6553
ephemeralvalidator.Conflicting(
66-
path.MatchRoot("public_key"),
54+
path.MatchRoot("public_key_data"),
6755
path.MatchRoot("private_key_type"),
6856
),
6957
ephemeralvalidator.Conflicting(
70-
path.MatchRoot("public_key"),
58+
path.MatchRoot("public_key_data"),
7159
path.MatchRoot("key_algorithm"),
7260
),
7361
ephemeralvalidator.AtLeastOneOf(
@@ -88,6 +76,7 @@ func (p *googleEphemeralServiceAccountKey) Schema(ctx context.Context, req ephem
8876
"name": schema.StringAttribute{
8977
Description: "The name of the service account key. This must have format `projects/{PROJECT_ID}/serviceAccounts/{ACCOUNT}/keys/{KEYID}`, where `{ACCOUNT}` is the email address or unique id of the service account.",
9078
Optional: true,
79+
Computed: true,
9180
Validators: []validator.String{
9281
stringvalidator.RegexMatches(
9382
regexp.MustCompile(verify.ServiceAccountKeyNameRegex),
@@ -97,6 +86,7 @@ func (p *googleEphemeralServiceAccountKey) Schema(ctx context.Context, req ephem
9786
"public_key_type": schema.StringAttribute{
9887
Description: "The output format of the public key requested. TYPE_X509_PEM_FILE is the default output format.",
9988
Optional: true,
89+
Computed: true,
10090
Validators: []validator.String{
10191
stringvalidator.OneOf(
10292
"TYPE_X509_PEM_FILE",
@@ -109,18 +99,23 @@ func (p *googleEphemeralServiceAccountKey) Schema(ctx context.Context, req ephem
10999
Optional: true,
110100
Computed: true,
111101
},
112-
"public_key": schema.StringAttribute{
102+
"public_key_data": schema.StringAttribute{
113103
Description: "The public key, base64 encoded.",
114104
Optional: true,
115-
Computed: true,
116105
},
117106
"private_key": schema.StringAttribute{
118107
Description: "The private key, base64 encoded.",
119108
Optional: true,
109+
Computed: true,
120110
},
121111
"private_key_type": schema.StringAttribute{
122112
Description: "The type of the private key.",
123113
Optional: true,
114+
Computed: true,
115+
},
116+
"fetch_key": schema.BoolAttribute{
117+
Description: "Whether to fetch the public key.",
118+
Optional: true,
124119
},
125120
},
126121
}
@@ -143,100 +138,150 @@ func (p *googleEphemeralServiceAccountKey) Configure(ctx context.Context, req ep
143138
p.providerConfig = pd
144139
}
145140

141+
type ServiceAccountKeyPrivateData struct {
142+
Name string `json:"name"`
143+
FetchedKey bool `json:"fetched_key"`
144+
}
145+
146+
var createdServiceAccountKey bool
147+
146148
func (p *googleEphemeralServiceAccountKey) Open(ctx context.Context, req ephemeral.OpenRequest, resp *ephemeral.OpenResponse) {
147-
var data ephemeralServiceAccountKeyModel
149+
var data = ephemeralServiceAccountKeyModel{}
148150
var err error
149151
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
150152
if resp.Diagnostics.HasError() {
151153
return
152154
}
153-
154-
var serviceAccountName string
155+
var serviceAccountKey *iam.ServiceAccountKey
156+
var saName string
155157
if data.ServiceAccountId.ValueString() != "" {
156-
d := &sdkSchema.ResourceData{}
157-
serviceAccountName, err = tpgresource.ServiceAccountFQN(
158-
data.ServiceAccountId.ValueString(),
159-
d,
160-
p.providerConfig,
161-
)
158+
saName = data.ServiceAccountId.ValueString()
162159
} else {
163-
serviceAccountName = data.Name.ValueString()
160+
saName = data.Name.ValueString()
164161
}
165-
publicKeyType := data.PublicKeyType.ValueString()
166-
if publicKeyType == "" {
162+
163+
var publicKeyType string
164+
if data.PublicKeyType.ValueString() == "" {
167165
publicKeyType = "TYPE_X509_PEM_FILE"
166+
} else {
167+
publicKeyType = data.PublicKeyType.ValueString()
168+
}
169+
170+
saName, err = tpgresource.ServiceAccountFQN(saName, nil, p.providerConfig)
171+
if err != nil {
172+
resp.Diagnostics.AddError(
173+
"Error getting service account name",
174+
fmt.Sprintf("Error getting service account name: %s", err),
175+
)
176+
return
168177
}
169-
var createdSak *iam.ServiceAccountKey
170-
if data.PublicKey.ValueString() != "" {
171-
ru := &iam.UploadServiceAccountKeyRequest{
172-
PublicKeyData: data.PublicKey.ValueString(),
178+
179+
createdServiceAccountKey = false
180+
if !data.FetchKey.ValueBool() {
181+
if data.PublicKeyData.ValueString() != "" {
182+
ru := &iam.UploadServiceAccountKeyRequest{
183+
PublicKeyData: data.PublicKeyData.ValueString(),
184+
}
185+
serviceAccountKey, err = p.providerConfig.NewIamClient(p.providerConfig.UserAgent).Projects.ServiceAccounts.Keys.Upload(saName, ru).Do()
186+
if err != nil {
187+
resp.Diagnostics.AddError(
188+
"Error creating service account key [Upload]",
189+
fmt.Sprintf("%s: %s", saName, err),
190+
)
191+
return
192+
}
193+
createdServiceAccountKey = true
194+
} else {
195+
var keyAlgorithm, privateKeyType string
196+
if data.PrivateKeyType.ValueString() == "" {
197+
privateKeyType = "TYPE_GOOGLE_CREDENTIALS_FILE"
198+
} else {
199+
privateKeyType = data.PrivateKeyType.ValueString()
200+
}
201+
if data.KeyAlgorithm.ValueString() == "" {
202+
keyAlgorithm = "KEY_ALG_RSA_2048"
203+
} else {
204+
keyAlgorithm = data.KeyAlgorithm.ValueString()
205+
}
206+
rc := &iam.CreateServiceAccountKeyRequest{
207+
KeyAlgorithm: keyAlgorithm,
208+
PrivateKeyType: privateKeyType,
209+
}
210+
serviceAccountKey, err = p.providerConfig.NewIamClient(p.providerConfig.UserAgent).Projects.ServiceAccounts.Keys.Create(saName, rc).Do()
211+
if err != nil {
212+
resp.Diagnostics.AddError(
213+
"Error creating service account key [Create]",
214+
fmt.Sprintf("%s: %s", saName, err),
215+
)
216+
return
217+
}
218+
createdServiceAccountKey = true
173219
}
174-
createdSak, err = p.providerConfig.NewIamClient(p.providerConfig.UserAgent).Projects.ServiceAccounts.Keys.Upload(serviceAccountName, ru).Do()
220+
221+
log.Printf("[DEBUG] Retrieving Service Account Key %q\n", serviceAccountKey.Name)
222+
err = ServiceAccountKeyWaitTime(p.providerConfig.NewIamClient(p.providerConfig.UserAgent).Projects.ServiceAccounts.Keys, serviceAccountKey.Name, publicKeyType, "Retrieving Service account key", 4*time.Minute)
175223
if err != nil {
176224
resp.Diagnostics.AddError(
177-
"Error creating service account key",
178-
fmt.Sprintf("Error creating service account key: %s", err),
225+
"Error retrieving Service Account Key",
226+
fmt.Sprintf("Error retrieving Service Account Key %q: %s", serviceAccountKey.Name, err),
179227
)
180228
return
181229
}
182-
} else if data.KeyAlgorithm.ValueString() != "" && data.PrivateKeyType.ValueString() != "" {
183-
rc := &iam.CreateServiceAccountKeyRequest{
184-
KeyAlgorithm: data.KeyAlgorithm.ValueString(),
185-
PrivateKeyType: data.PrivateKeyType.ValueString(),
186-
}
230+
231+
marshalledName, _ := json.Marshal(ServiceAccountKeyPrivateData{Name: serviceAccountKey.Name})
232+
233+
resp.Private.SetKey(ctx, "name", marshalledName)
234+
235+
data.Name = types.StringValue(serviceAccountKey.Name)
236+
data.KeyAlgorithm = types.StringValue(serviceAccountKey.KeyAlgorithm)
237+
data.PrivateKey = types.StringValue(serviceAccountKey.PrivateKeyData)
238+
data.PrivateKeyType = types.StringValue(serviceAccountKey.PrivateKeyType)
239+
}
240+
data.PublicKeyType = types.StringValue(publicKeyType)
241+
if serviceAccountKey != nil {
242+
log.Printf("[DEBUG] Retrieving Service Account Key %q\n", serviceAccountKey.Name)
243+
err = ServiceAccountKeyWaitTime(p.providerConfig.NewIamClient(p.providerConfig.UserAgent).Projects.ServiceAccounts.Keys, serviceAccountKey.Name, publicKeyType, "Retrieving Service account key", 4*time.Minute)
187244
if err != nil {
188245
resp.Diagnostics.AddError(
189-
"Error getting service account name",
190-
fmt.Sprintf("Error getting service account name: %s", err),
246+
"Error retrieving Service Account Key",
247+
fmt.Sprintf("Error retrieving Service Account Key %q: %s", serviceAccountKey.Name, err),
191248
)
192249
return
193250
}
194-
createdSak, err = p.providerConfig.NewIamClient(p.providerConfig.UserAgent).Projects.ServiceAccounts.Keys.Create(serviceAccountName, rc).Do()
251+
} else {
252+
err = ServiceAccountKeyWaitTime(p.providerConfig.NewIamClient(p.providerConfig.UserAgent).Projects.ServiceAccounts.Keys, saName, publicKeyType, "Retrieving Service account key", 4*time.Minute)
195253
if err != nil {
196254
resp.Diagnostics.AddError(
197-
"Error creating service account key",
198-
fmt.Sprintf("Error creating service account key: %s", err),
255+
"Error retrieving Service Account Key",
256+
fmt.Sprintf("Error retrieving Service Account Key %q: %s", saName, err),
199257
)
200258
return
201259
}
202260
}
203-
keyName := data.Name.ValueString()
204-
getSak, err := p.providerConfig.NewIamClient(p.providerConfig.UserAgent).Projects.ServiceAccounts.Keys.Get(serviceAccountName).PublicKeyType(publicKeyType).Do()
205-
if err != nil {
206-
resp.Diagnostics.AddError(
207-
"Error retrieving Service Account Key",
208-
fmt.Sprintf("Error retrieving Service Account Key %q: %s", keyName, err),
209-
)
210-
return
211-
}
212-
213-
data.Name = types.StringValue(getSak.Name)
214-
data.KeyAlgorithm = types.StringValue(getSak.KeyAlgorithm)
215-
data.PublicKey = types.StringValue(getSak.PublicKeyData)
216-
data.PublicKeyType = types.StringValue(publicKeyType)
217-
if createdSak != nil {
218-
data.PrivateKey = types.StringValue(createdSak.PrivateKeyData)
219-
data.PrivateKeyType = types.StringValue(createdSak.PrivateKeyType)
220-
}
221261

222262
resp.Diagnostics.Append(resp.Result.Set(ctx, &data)...)
223263
}
224264

225265
func (p *googleEphemeralServiceAccountKey) Close(ctx context.Context, req ephemeral.CloseRequest, resp *ephemeral.CloseResponse) {
226-
serviceAccountKeyName, err := req.Private.GetKey(ctx, "name")
227-
fmt.Printf("[DEBUG] Deleting Service Account Key %q\n", serviceAccountKeyName)
228-
if err != nil {
266+
if !createdServiceAccountKey {
267+
return
268+
}
269+
dataBytes, diags := req.Private.GetKey(ctx, "name")
270+
if diags.HasError() {
229271
resp.Diagnostics.AddError(
230-
"Error getting private key",
231-
fmt.Sprintf("Error getting private key: %s", err),
272+
"Error getting name data",
273+
fmt.Sprintf("Error getting name data: %s", diags.Errors()),
232274
)
233275
return
234276
}
235-
deletion, _ := p.providerConfig.NewIamClient(p.providerConfig.UserAgent).Projects.ServiceAccounts.Keys.Delete(string(serviceAccountKeyName)).Do()
236-
if deletion != nil {
277+
var data ServiceAccountKeyPrivateData
278+
json.Unmarshal(dataBytes, &data)
279+
log.Printf("[DEBUG] Deleting Service Account Key %q\n", data.Name)
280+
_, err := p.providerConfig.NewIamClient(p.providerConfig.UserAgent).Projects.ServiceAccounts.Keys.Delete(data.Name).Do()
281+
if err != nil {
237282
resp.Diagnostics.AddError(
238283
"Error deleting Service Account Key",
239-
fmt.Sprintf("Error deleting Service Account Key %q: %s", string(serviceAccountKeyName), err),
284+
fmt.Sprintf("Error deleting Service Account Key %q: %s", data.Name, err.Error()),
240285
)
241286
return
242287
}

0 commit comments

Comments
 (0)