Skip to content

Commit 161070d

Browse files
VAULT-43852 Added write-only field and updated related files for keytab and removed unwanted tests
1 parent 3de065b commit 161070d

8 files changed

Lines changed: 87 additions & 128 deletions

internal/consts/consts.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,7 @@ const (
815815
FieldBindPassWOVersion = "bindpass_wo_version"
816816
FieldKeytab = "keytab"
817817
FieldKeytabWO = "keytab_wo"
818+
FieldKeytabWOVersion = "keytab_wo_version"
818819
FieldClientTLSKeyWO = "client_tls_key_wo"
819820
FieldClientTLSKeyWOVersion = "client_tls_key_wo_version"
820821
FieldClientTLSCertWO = "client_tls_cert_wo"

internal/vault/auth/kerberos/kerberos_config_resource.go

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ type kerberosAuthBackendConfigModel struct {
5151
base.BaseModel
5252
Mount types.String `tfsdk:"mount"`
5353
KeytabWO types.String `tfsdk:"keytab_wo"`
54+
KeytabWOVersion types.Int64 `tfsdk:"keytab_wo_version"`
5455
ServiceAccount types.String `tfsdk:"service_account"`
5556
RemoveInstanceName types.Bool `tfsdk:"remove_instance_name"`
5657
AddGroupAliases types.Bool `tfsdk:"add_group_aliases"`
@@ -89,6 +90,10 @@ func (r *kerberosAuthBackendConfigResource) Schema(_ context.Context, _ resource
8990
Sensitive: true,
9091
Description: "Base64-encoded keytab file content (write-only). Must contain an entry matching service_account.",
9192
},
93+
consts.FieldKeytabWOVersion: schema.Int64Attribute{
94+
Required: true,
95+
Description: "Version identifier for keytab updates. Increment this value to trigger a keytab update.",
96+
},
9297
consts.FieldServiceAccount: schema.StringAttribute{
9398
Required: true,
9499
Description: "The Kerberos service account associated with the keytab entry (e.g., 'vault_svc').",
@@ -108,53 +113,57 @@ func (r *kerberosAuthBackendConfigResource) Schema(_ context.Context, _ resource
108113
}
109114

110115
func (r *kerberosAuthBackendConfigResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
116+
var plan kerberosAuthBackendConfigModel
111117
var config kerberosAuthBackendConfigModel
112118

119+
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
113120
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
114121
if resp.Diagnostics.HasError() {
115122
return
116123
}
117124

118-
resp.Diagnostics.Append(r.writeConfig(ctx, &config)...)
125+
resp.Diagnostics.Append(r.writeConfig(ctx, &plan, &config)...)
119126
if resp.Diagnostics.HasError() {
120127
return
121128
}
122129

123-
resp.Diagnostics.Append(resp.State.Set(ctx, &config)...)
130+
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
124131
}
125132

126133
func (r *kerberosAuthBackendConfigResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
134+
var plan kerberosAuthBackendConfigModel
127135
var config kerberosAuthBackendConfigModel
128136

137+
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
129138
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
130139
if resp.Diagnostics.HasError() {
131140
return
132141
}
133142

134-
resp.Diagnostics.Append(r.writeConfig(ctx, &config)...)
143+
resp.Diagnostics.Append(r.writeConfig(ctx, &plan, &config)...)
135144
if resp.Diagnostics.HasError() {
136145
return
137146
}
138147

139-
resp.Diagnostics.Append(resp.State.Set(ctx, &config)...)
148+
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
140149
}
141150

142151
// writeConfig is a reusable helper that writes configuration to Vault and reads it back.
143152
// Used by both Create and Update operations.
144-
func (r *kerberosAuthBackendConfigResource) writeConfig(ctx context.Context, config *kerberosAuthBackendConfigModel) diag.Diagnostics {
153+
func (r *kerberosAuthBackendConfigResource) writeConfig(ctx context.Context, plan *kerberosAuthBackendConfigModel, config *kerberosAuthBackendConfigModel) diag.Diagnostics {
145154
var diags diag.Diagnostics
146155

147-
vaultClient, err := client.GetClient(ctx, r.Meta(), config.Namespace.ValueString())
156+
vaultClient, err := client.GetClient(ctx, r.Meta(), plan.Namespace.ValueString())
148157
if err != nil {
149158
diags.AddError(errutil.ClientConfigureErr(err))
150159
return diags
151160
}
152161

153-
mount := strings.Trim(config.Mount.ValueString(), "/")
162+
mount := strings.Trim(plan.Mount.ValueString(), "/")
154163
configPath := r.configPath(mount)
155164

156165
// Build the API request
157-
vaultRequest, apiDiags := r.getApiModel(config)
166+
vaultRequest, apiDiags := r.getApiModel(plan, config)
158167
diags.Append(apiDiags...)
159168
if diags.HasError() {
160169
return diags
@@ -173,15 +182,15 @@ func (r *kerberosAuthBackendConfigResource) writeConfig(ctx context.Context, con
173182
tflog.Info(ctx, fmt.Sprintf("Kerberos auth backend config successfully written to '%s'", configPath))
174183

175184
// Read back the configuration
176-
found, readDiags := r.read(ctx, config)
185+
found, readDiags := r.read(ctx, plan)
177186
diags.Append(readDiags...)
178187
if diags.HasError() {
179188
return diags
180189
}
181190
if !found {
182191
diags.AddError(
183192
"Error reading back Kerberos auth backend config after write",
184-
fmt.Sprintf("Config at '%s' was not found after successful write", r.configPath(strings.Trim(config.Mount.ValueString(), "/"))),
193+
fmt.Sprintf("Config at '%s' was not found after successful write", r.configPath(strings.Trim(plan.Mount.ValueString(), "/"))),
185194
)
186195
return diags
187196
}
@@ -318,14 +327,14 @@ func (r *kerberosAuthBackendConfigResource) mountFromPath(path string) (string,
318327
}
319328

320329
// getApiModel builds the Vault API request map from the Terraform data model.
321-
func (r *kerberosAuthBackendConfigResource) getApiModel(config *kerberosAuthBackendConfigModel) (map[string]any, diag.Diagnostics) {
330+
func (r *kerberosAuthBackendConfigResource) getApiModel(plan *kerberosAuthBackendConfigModel, config *kerberosAuthBackendConfigModel) (map[string]any, diag.Diagnostics) {
322331
var diags diag.Diagnostics
323332

324333
vaultRequest := map[string]any{
325334
consts.FieldKeytab: config.KeytabWO.ValueString(),
326-
consts.FieldServiceAccount: config.ServiceAccount.ValueString(),
327-
consts.FieldRemoveInstanceName: config.RemoveInstanceName.ValueBool(),
328-
consts.FieldAddGroupAliases: config.AddGroupAliases.ValueBool(),
335+
consts.FieldServiceAccount: plan.ServiceAccount.ValueString(),
336+
consts.FieldRemoveInstanceName: plan.RemoveInstanceName.ValueBool(),
337+
consts.FieldAddGroupAliases: plan.AddGroupAliases.ValueBool(),
329338
}
330339

331340
return vaultRequest, diags

internal/vault/auth/kerberos/kerberos_config_resource_test.go

Lines changed: 25 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ func TestAccKerberosAuthBackendConfig_basic(t *testing.T) {
4646
ImportStateId: fmt.Sprintf("auth/%s/config", path),
4747
ImportStateVerify: true,
4848
ImportStateVerifyIdentifierAttribute: consts.FieldMount,
49+
ImportStateVerifyIgnore: []string{consts.FieldKeytabWOVersion},
4950
},
5051
},
5152
})
@@ -87,6 +88,7 @@ func TestAccKerberosAuthBackendConfig_update(t *testing.T) {
8788
ImportStateId: fmt.Sprintf("auth/%s/config", path),
8889
ImportStateVerify: true,
8990
ImportStateVerifyIdentifierAttribute: consts.FieldMount,
91+
ImportStateVerifyIgnore: []string{consts.FieldKeytabWOVersion},
9092
},
9193
},
9294
})
@@ -131,28 +133,6 @@ func TestAccKerberosAuthBackendConfig_updateAndReplacement(t *testing.T) {
131133
})
132134
}
133135

134-
// TestAccKerberosAuthBackendConfig_defaultCheck tests to check default values
135-
func TestAccKerberosAuthBackendConfig_defaultCheck(t *testing.T) {
136-
serviceAccount := "vault/localhost@EXAMPLE.COM"
137-
138-
resource.Test(t, resource.TestCase{
139-
PreCheck: func() { acctestutil.TestAccPreCheck(t) },
140-
ProtoV5ProviderFactories: providertest.ProtoV5ProviderFactories,
141-
Steps: []resource.TestStep{
142-
{
143-
Config: testAccKerberosAuthBackendConfigConfig_defaultValues(serviceAccount),
144-
Check: resource.ComposeTestCheckFunc(
145-
resource.TestCheckResourceAttr("vault_kerberos_auth_backend_config.config", consts.FieldMount, "kerberos"),
146-
resource.TestCheckResourceAttr("vault_kerberos_auth_backend_config.config", consts.FieldServiceAccount, serviceAccount),
147-
resource.TestCheckNoResourceAttr("vault_kerberos_auth_backend_config.config", consts.FieldKeytabWO),
148-
resource.TestCheckNoResourceAttr("vault_kerberos_auth_backend_config.config", consts.FieldRemoveInstanceName),
149-
resource.TestCheckNoResourceAttr("vault_kerberos_auth_backend_config.config", consts.FieldAddGroupAliases),
150-
),
151-
},
152-
},
153-
})
154-
}
155-
156136
// TestAccKerberosAuthBackendConfig_validationErrors tests various validation errors
157137
func TestAccKerberosAuthBackendConfig_validationErrors(t *testing.T) {
158138
path := acctest.RandomWithPrefix("kerberos")
@@ -162,16 +142,6 @@ func TestAccKerberosAuthBackendConfig_validationErrors(t *testing.T) {
162142
PreCheck: func() { acctestutil.TestAccPreCheck(t) },
163143
ProtoV5ProviderFactories: providertest.ProtoV5ProviderFactories,
164144
Steps: []resource.TestStep{
165-
// Test missing keytab
166-
{
167-
Config: testAccKerberosAuthBackendConfigConfig_missingKeytab(path, serviceAccount),
168-
ExpectError: regexp.MustCompile(`(attribute|argument) "keytab_wo" is required`),
169-
},
170-
// Test missing service account
171-
{
172-
Config: testAccKerberosAuthBackendConfigConfig_missingServiceAccount(path),
173-
ExpectError: regexp.MustCompile(`(attribute|argument) "service_account" is required`),
174-
},
175145
// Test empty service account - empty string passes Terraform validation but fails at Vault API
176146
{
177147
Config: testAccKerberosAuthBackendConfigConfig_emptyServiceAccount(path),
@@ -269,6 +239,7 @@ func TestAccKerberosAuthBackendConfig_namespace(t *testing.T) {
269239
ImportStateId: fmt.Sprintf("auth/%s/config", path),
270240
ImportStateVerify: true,
271241
ImportStateVerifyIdentifierAttribute: consts.FieldMount,
242+
ImportStateVerifyIgnore: []string{consts.FieldKeytabWOVersion},
272243
},
273244
{
274245
// Cleanup step needed for the import step above
@@ -282,36 +253,6 @@ func TestAccKerberosAuthBackendConfig_namespace(t *testing.T) {
282253
})
283254
}
284255

285-
// Configuration templates for negative tests
286-
287-
func testAccKerberosAuthBackendConfigConfig_missingKeytab(path, serviceAccount string) string {
288-
return fmt.Sprintf(`
289-
resource "vault_auth_backend" "kerberos" {
290-
type = "kerberos"
291-
path = %q
292-
}
293-
294-
resource "vault_kerberos_auth_backend_config" "config" {
295-
mount = vault_auth_backend.kerberos.path
296-
service_account = %q
297-
}
298-
`, path, serviceAccount)
299-
}
300-
301-
func testAccKerberosAuthBackendConfigConfig_missingServiceAccount(path string) string {
302-
return fmt.Sprintf(`
303-
resource "vault_auth_backend" "kerberos" {
304-
type = "kerberos"
305-
path = %q
306-
}
307-
308-
resource "vault_kerberos_auth_backend_config" "config" {
309-
mount = vault_auth_backend.kerberos.path
310-
keytab_wo = %q
311-
}
312-
`, path, testKeytab)
313-
}
314-
315256
func testAccKerberosAuthBackendConfigConfig_emptyServiceAccount(path string) string {
316257
return fmt.Sprintf(`
317258
resource "vault_auth_backend" "kerberos" {
@@ -320,9 +261,10 @@ resource "vault_auth_backend" "kerberos" {
320261
}
321262
322263
resource "vault_kerberos_auth_backend_config" "config" {
323-
mount = vault_auth_backend.kerberos.path
324-
keytab_wo = %q
325-
service_account = ""
264+
mount = vault_auth_backend.kerberos.path
265+
keytab_wo = %q
266+
keytab_wo_version = 1
267+
service_account = ""
326268
}
327269
`, path, testKeytab)
328270
}
@@ -335,9 +277,10 @@ resource "vault_auth_backend" "kerberos" {
335277
}
336278
337279
resource "vault_kerberos_auth_backend_config" "config" {
338-
mount = vault_auth_backend.kerberos.path
339-
keytab_wo = ""
340-
service_account = %q
280+
mount = vault_auth_backend.kerberos.path
281+
keytab_wo = ""
282+
keytab_wo_version = 1
283+
service_account = %q
341284
}
342285
`, path, serviceAccount)
343286
}
@@ -352,9 +295,10 @@ resource "vault_auth_backend" "kerberos" {
352295
}
353296
354297
resource "vault_kerberos_auth_backend_config" "config" {
355-
mount = vault_auth_backend.kerberos.path
356-
keytab_wo = %q
357-
service_account = %q
298+
mount = vault_auth_backend.kerberos.path
299+
keytab_wo = %q
300+
keytab_wo_version = 1
301+
service_account = %q
358302
}
359303
`, path, testKeytab, serviceAccount)
360304
}
@@ -369,6 +313,7 @@ resource "vault_auth_backend" "kerberos" {
369313
resource "vault_kerberos_auth_backend_config" "config" {
370314
mount = vault_auth_backend.kerberos.path
371315
keytab_wo = %q
316+
keytab_wo_version = 1
372317
service_account = %q
373318
remove_instance_name = %t
374319
add_group_aliases = %t
@@ -384,27 +329,14 @@ resource "vault_auth_backend" "kerberos" {
384329
}
385330
386331
resource "vault_kerberos_auth_backend_config" "config" {
387-
mount = vault_auth_backend.kerberos.path
388-
keytab_wo = %q
389-
service_account = %q
332+
mount = vault_auth_backend.kerberos.path
333+
keytab_wo = %q
334+
keytab_wo_version = 2
335+
service_account = %q
390336
}
391337
`, path, keytab, serviceAccount)
392338
}
393339

394-
func testAccKerberosAuthBackendConfigConfig_defaultValues(serviceAccount string) string {
395-
return fmt.Sprintf(`
396-
resource "vault_auth_backend" "kerberos" {
397-
type = "kerberos"
398-
}
399-
400-
resource "vault_kerberos_auth_backend_config" "config" {
401-
mount = vault_auth_backend.kerberos.path
402-
keytab_wo = %q
403-
service_account = %q
404-
}
405-
`, testKeytab, serviceAccount)
406-
}
407-
408340
func testAccKerberosAuthBackendConfigConfig_namespace(namespace, path, serviceAccount string) string {
409341
return fmt.Sprintf(`
410342
resource "vault_namespace" "test" {
@@ -418,10 +350,11 @@ resource "vault_auth_backend" "kerberos" {
418350
}
419351
420352
resource "vault_kerberos_auth_backend_config" "config" {
421-
namespace = vault_namespace.test.path
422-
mount = vault_auth_backend.kerberos.path
423-
keytab_wo = %q
424-
service_account = %q
353+
namespace = vault_namespace.test.path
354+
mount = vault_auth_backend.kerberos.path
355+
keytab_wo = %q
356+
keytab_wo_version = 1
357+
service_account = %q
425358
}
426359
`, namespace, path, testKeytab, serviceAccount)
427360
}

internal/vault/auth/kerberos/kerberos_login_ephemeral_resource_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ resource "vault_auth_backend" "kerberos" {
168168
resource "vault_kerberos_auth_backend_config" "config" {
169169
mount = vault_auth_backend.kerberos.path
170170
keytab_wo = "%s"
171+
keytab_wo_version = 1
171172
service_account = "%s"
172173
}
173174
@@ -270,6 +271,7 @@ resource "vault_auth_backend" "kerberos" {
270271
resource "vault_kerberos_auth_backend_config" "config" {
271272
mount = vault_auth_backend.kerberos.path
272273
keytab_wo = "%s"
274+
keytab_wo_version = 1
273275
service_account = "%s"
274276
}
275277
@@ -402,6 +404,7 @@ resource "vault_kerberos_auth_backend_config" "config" {
402404
namespace = vault_namespace.test.path
403405
mount = vault_auth_backend.kerberos.path
404406
keytab_wo = "%s"
407+
keytab_wo_version = 1
405408
service_account = "%s"
406409
}
407410
@@ -486,6 +489,7 @@ resource "vault_auth_backend" "kerberos" {
486489
resource "vault_kerberos_auth_backend_config" "config" {
487490
mount = vault_auth_backend.kerberos.path
488491
keytab_wo = "%s"
492+
keytab_wo_version = 1
489493
service_account = "%s"
490494
}
491495
@@ -569,6 +573,7 @@ resource "vault_auth_backend" "kerberos" {
569573
resource "vault_kerberos_auth_backend_config" "config" {
570574
mount = vault_auth_backend.kerberos.path
571575
keytab_wo = "%s"
576+
keytab_wo_version = 1
572577
service_account = "%s"
573578
}
574579

0 commit comments

Comments
 (0)