Skip to content

Commit 118476d

Browse files
authored
Added write-only fields for webhook and added tests (#742)
1 parent fe4b40c commit 118476d

File tree

3 files changed

+75
-2
lines changed

3 files changed

+75
-2
lines changed

docs/resources/webhook.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,14 @@ resource "spacelift_webhook" "webhook" {
2828

2929
### Optional
3030

31+
> **NOTE**: [Write-only arguments](https://developer.hashicorp.com/terraform/language/resources/ephemeral#write-only-arguments) are supported in Terraform 1.11 and later.
32+
3133
- `enabled` (Boolean) enables or disables sending webhooks. Defaults to `true`.
3234
- `module_id` (String) ID of the module which triggers the webhooks
3335
- `retry_on_failure` (Boolean) whether to retry the webhook in case of failure. Defaults to `false`.
34-
- `secret` (String, Sensitive) secret used to sign each POST request so you're able to verify that the request comes from us. Defaults to an empty value. Note that once it's created, it will be just an empty string in the state due to security reasons.
36+
- `secret` (String, Sensitive, Deprecated) secret used to sign each POST request so you're able to verify that the request comes from us. Defaults to an empty value. Note that once it's created, it will be just an empty string in the state due to security reasons.
37+
- `secret_wo` (String, Sensitive, [Write-only](https://developer.hashicorp.com/terraform/language/resources/ephemeral#write-only-arguments)) `secret_wo` used to sign each POST request so you're able to verify that the request comes from us. Defaults to an empty value. The secret_wo is not stored in the state. Modify secret_wo_version to trigger an update. This field requires Terraform/OpenTofu 1.11+.
38+
- `secret_wo_version` (String) Used together with secret_wo to trigger an update to the secret. Increment this value when an update to secret_wo is required. This field requires Terraform/OpenTofu 1.11+.
3539
- `stack_id` (String) ID of the stack which triggers the webhooks
3640

3741
### Read-Only

spacelift/resource_webhook.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,28 @@ func resourceWebhook() *schema.Resource {
7878
Sensitive: true,
7979
ForceNew: true,
8080
Default: "",
81+
Deprecated: "`secret` is deprecated. Please use secret_wo in combination with secret_wo_version",
8182
DiffSuppressFunc: ignoreOnceCreated,
83+
ConflictsWith: []string{"secret_wo", "secret_wo_version"},
8284
},
85+
"secret_wo": {
86+
Type: schema.TypeString,
87+
Description: "`secret_wo` used to sign each POST request so you're able to verify that the request comes from us. Defaults to an empty value. The secret_wo is not stored in the state. Modify secret_wo_version to trigger an update. This field requires Terraform/OpenTofu 1.11+.",
88+
Sensitive: true,
89+
Optional: true,
90+
WriteOnly: true,
91+
ConflictsWith: []string{"secret"},
92+
RequiredWith: []string{"secret_wo_version"},
93+
},
94+
"secret_wo_version": {
95+
Type: schema.TypeString,
96+
Description: "Used together with secret_wo to trigger an update to the secret. Increment this value when an update to secret_wo is required. This field requires Terraform/OpenTofu 1.11+.",
97+
Optional: true,
98+
ForceNew: true,
99+
ConflictsWith: []string{"secret"},
100+
RequiredWith: []string{"secret_wo"},
101+
},
102+
83103
"stack_id": {
84104
Type: schema.TypeString,
85105
Description: "ID of the stack which triggers the webhooks",
@@ -96,6 +116,11 @@ func resourceWebhook() *schema.Resource {
96116
}
97117

98118
func resourceWebhookCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
119+
secret, diags := internal.ExtractWriteOnlyField("secret", "secret_wo", "secret_wo_version", d)
120+
if diags != nil {
121+
return diags
122+
}
123+
99124
var mutation struct {
100125
WebhooksIntegration struct {
101126
ID string `graphql:"id"`
@@ -106,7 +131,7 @@ func resourceWebhookCreate(ctx context.Context, d *schema.ResourceData, meta int
106131
input := structs.WebhooksIntegrationInput{
107132
Enabled: graphql.Boolean(d.Get("enabled").(bool)),
108133
Endpoint: graphql.String(d.Get("endpoint").(string)),
109-
Secret: graphql.String(d.Get("secret").(string)),
134+
Secret: graphql.String(secret),
110135
}
111136

112137
if retryOnFailure, ok := d.GetOk("retry_on_failure"); ok {

spacelift/resource_webhook_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,48 @@ func TestWebhookResource(t *testing.T) {
9090
},
9191
})
9292
})
93+
94+
t.Run("with a stack and write-only values", func(t *testing.T) {
95+
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
96+
97+
config := func(endpoint string) string {
98+
return fmt.Sprintf(`
99+
resource "spacelift_stack" "test" {
100+
branch = "master"
101+
repository = "demo"
102+
name = "Test stack %s"
103+
}
104+
105+
resource "spacelift_webhook" "test" {
106+
stack_id = spacelift_stack.test.id
107+
endpoint = "%s"
108+
secret_wo = "very-very-secret"
109+
secret_wo_version = 1
110+
retry_on_failure = false
111+
}
112+
`, randomID, endpoint)
113+
}
114+
115+
testSteps(t, []resource.TestStep{
116+
{
117+
Config: config("https://bacon.org"),
118+
Check: Resource(
119+
resourceName,
120+
Attribute("id", IsNotEmpty()),
121+
Attribute("endpoint", Equals("https://bacon.org")),
122+
),
123+
},
124+
{
125+
ResourceName: resourceName,
126+
ImportState: true,
127+
ImportStateIdPrefix: fmt.Sprintf("stack/test-stack-%s/", randomID),
128+
ImportStateVerify: true,
129+
ImportStateVerifyIgnore: []string{"secret", "secret_wo_version"},
130+
},
131+
{
132+
Config: config("https://cabbage.org"),
133+
Check: Resource(resourceName, Attribute("endpoint", Equals("https://cabbage.org"))),
134+
},
135+
})
136+
})
93137
}

0 commit comments

Comments
 (0)