-
Notifications
You must be signed in to change notification settings - Fork 631
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cloudflare worker secret resource #2628
Closed
Closed
Changes from all commits
Commits
Show all changes
46 commits
Select commit
Hold shift + click to select a range
2c94ecd
Initial commit - broken, just saving stuff.
helenatuominen 728ef4b
Pushing current code, work_secret implemented, problems with temp wor…
helenatuominen 83982d1
Still working on manual creation/destroy of workers
helenatuominen 12b0a8c
Completed worker manual create/delete outside of terraform plan in test.
helenatuominen a673e67
Updated to remove length check.
helenatuominen 364bd16
Update cloudflare/resource_cloudflare_worker_secret.go
helenatuominen 4af614c
reformat resource_cloudflare_worker_secret.go
patryk 0fb2d12
Committing prior to creation of test using Terraform plan for Worker
helenatuominen 3f6bbb7
Merge remote-tracking branch 'origin/master' into cloudflare_worker_s…
lboynton a658f8e
Fix some imports
lboynton dbb46ee
Merge branch 'cloudflare:master' into cloudflare_worker_secret
lboynton 2dd0cf4
Merge branch 'cloudflare:master' into cloudflare_worker_secret
lboynton ca7fc76
Add missing account ID to schema
lboynton d55a82c
Move schema to separate file
lboynton bac6515
Allow updating secret text
lboynton 0f58ac4
Add changelog entry
lboynton 9762adb
Add example
lboynton 4483bd6
fix tests a bit, but still broken
lboynton 2b62b6f
Tests passing :)
lboynton 8348c92
Make it possible to use cloudflare_worker_script and cloudflare_worke…
lboynton 7f5b5e4
attempt to fix tests again
lboynton cee170e
follow standards
lboynton 704777f
use updating logging pattern
lboynton eddea35
return read secret
lboynton 722220a
Merge branch 'master' into cloudflare_worker_secret
lboynton a261fca
improve importing
lboynton b596375
improve importing a bit more
lboynton c73dd00
Merge branch 'master' into cloudflare_worker_secret
lboynton c5f3460
Fix error message string interpolation
lboynton 1a972ad
wip on import test
lboynton da3d000
Delete import test as secret cannot be imported
lboynton 1157bea
Pass test if worker script does not exist
lboynton 8963723
Add import example
lboynton b82429e
fix import example
lboynton 4669c6e
fix formatting
lboynton 7212905
Don't create new contexts
lboynton 2e5fdb2
Merge branch 'master' into cloudflare_worker_secret
lboynton 1d94ae8
Revert "Delete import test as secret cannot be imported"
lboynton ee4ca83
Apply suggestions from code review
lboynton 42a1bf0
Reinstate import worker secret test
lboynton 375d00c
Merge remote-tracking branch 'lboynton/cloudflare_worker_secret' into…
lboynton 5946cef
Ignore missing secret_text in state from import test
lboynton 7371ec1
Merge remote-tracking branch 'origin/master' into cloudflare_worker_s…
lboynton d354617
formatting
lboynton 51069dc
Merge branch 'master' into cloudflare_worker_secret
lboynton 30a9c86
Merge branch 'master' into cloudflare_worker_secret
lboynton File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
```release-note:new-resource | ||
cloudflare_worker_secret | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
$ terraform import cloudflare_worker_secret.example <account_id>/<script_name>/<secret_name> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
resource "cloudflare_worker_secret" "my_secret" { | ||
account_id = "f037e56e89293a057740de681ac9abbe" | ||
name = "MY_EXAMPLE_SECRET_TEXT" | ||
script_name = "script_1" | ||
secret_text = "my_secret_value" | ||
} |
44 changes: 44 additions & 0 deletions
44
internal/sdkv2provider/import_cloudflare_worker_secret_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package sdkv2provider | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-testing/helper/resource" | ||
) | ||
|
||
func TestAccCloudflareWorkerSecret_Import(t *testing.T) { | ||
secretName := generateRandomResourceName() | ||
resourceName := "cloudflare_worker_secret." + secretName | ||
secretText := generateRandomResourceName() | ||
workerSecretTestScriptName = generateRandomResourceName() | ||
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID") | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { | ||
testAccPreCheck(t) | ||
testAccPreCheckAccount(t) | ||
}, | ||
ProviderFactories: providerFactories, | ||
CheckDestroy: testAccCheckCloudflareWorkerSecretDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccCheckCloudflareWorkerSecretWithWorkerScript(workerSecretTestScriptName, secretName, secretText, accountID), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckCloudflareWorkerSecretExists(workerSecretTestScriptName, secretName, accountID), | ||
), | ||
}, | ||
{ | ||
ResourceName: resourceName, | ||
ImportStateId: fmt.Sprintf("%s/%s/%s", accountID, workerSecretTestScriptName, secretName), | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
ImportStateVerifyIgnore: []string{"secret_text"}, | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckCloudflareWorkerSecretExists(workerSecretTestScriptName, secretName, accountID), | ||
), | ||
}, | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 116 additions & 0 deletions
116
internal/sdkv2provider/resource_cloudflare_workers_secret.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package sdkv2provider | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"github.com/MakeNowJust/heredoc/v2" | ||
cloudflare "github.com/cloudflare/cloudflare-go" | ||
"github.com/cloudflare/terraform-provider-cloudflare/internal/consts" | ||
"github.com/hashicorp/terraform-plugin-log/tflog" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/pkg/errors" | ||
"strings" | ||
) | ||
|
||
func resourceCloudflareWorkerSecret() *schema.Resource { | ||
return &schema.Resource{ | ||
Schema: resourceCloudflareWorkerSecretSchema(), | ||
CreateContext: resourceCloudflareWorkerSecretCreate, | ||
ReadContext: resourceCloudflareWorkerSecretRead, | ||
UpdateContext: resourceCloudflareWorkerSecretCreate, | ||
DeleteContext: resourceCloudflareWorkerSecretDelete, | ||
Importer: &schema.ResourceImporter{ | ||
StateContext: resourceCloudflareWorkerSecretImport, | ||
}, | ||
Description: heredoc.Doc("Provides a Cloudflare Worker secret resource."), | ||
} | ||
} | ||
|
||
func resourceCloudflareWorkerSecretRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
client := meta.(*cloudflare.API) | ||
accountID := d.Get(consts.AccountIDSchemaKey).(string) | ||
secrets, err := client.ListWorkersSecrets(ctx, cloudflare.AccountIdentifier(accountID), cloudflare.ListWorkersSecretsParams{ | ||
ScriptName: d.Get("script_name").(string), | ||
}) | ||
if err != nil { | ||
return diag.FromErr(errors.Wrap(err, fmt.Sprintf("Error listing worker secrets"))) | ||
} | ||
|
||
for _, secret := range secrets.Result { | ||
tflog.Info(ctx, fmt.Sprintf("Found secret %s", secret.Name)) | ||
if secret.Name == d.Get("name") { | ||
return nil | ||
} | ||
} | ||
|
||
return diag.Errorf(fmt.Sprintf("worker secret %s not found for script %s", d.Get("name"), d.Get("script_name"))) | ||
} | ||
|
||
func resourceCloudflareWorkerSecretCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
client := meta.(*cloudflare.API) | ||
accountID := d.Get(consts.AccountIDSchemaKey).(string) | ||
scriptName := d.Get("script_name").(string) | ||
name := d.Get("name").(string) | ||
secretText := d.Get("secret_text").(string) | ||
|
||
params := cloudflare.SetWorkersSecretParams{ | ||
Secret: &cloudflare.WorkersPutSecretRequest{ | ||
Name: name, | ||
Text: secretText, | ||
Type: cloudflare.WorkerSecretTextBindingType, | ||
}, | ||
ScriptName: scriptName, | ||
} | ||
|
||
_, err := client.SetWorkersSecret(ctx, cloudflare.AccountIdentifier(accountID), params) | ||
if err != nil { | ||
return diag.FromErr(errors.Wrap(err, "error creating worker secret")) | ||
} | ||
|
||
d.SetId(stringChecksum(fmt.Sprintf("%s/%s/%s", accountID, scriptName, name))) | ||
|
||
tflog.Info(ctx, fmt.Sprintf("Created Cloudflare Workers secret with ID: %s", d.Id())) | ||
|
||
return resourceCloudflareWorkerSecretRead(ctx, d, meta) | ||
} | ||
|
||
func resourceCloudflareWorkerSecretDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
client := meta.(*cloudflare.API) | ||
accountID := d.Get(consts.AccountIDSchemaKey).(string) | ||
scriptName := d.Get("script_name").(string) | ||
name := d.Get("name").(string) | ||
|
||
params := cloudflare.DeleteWorkersSecretParams{ | ||
SecretName: name, | ||
ScriptName: scriptName, | ||
} | ||
|
||
tflog.Info(ctx, fmt.Sprintf("Deleting Cloudflare Workers secret with id: %s", d.Id())) | ||
|
||
_, err := client.DeleteWorkersSecret(ctx, cloudflare.AccountIdentifier(accountID), params) | ||
if err != nil { | ||
return diag.FromErr(errors.Wrap(err, "error deleting worker secret")) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceCloudflareWorkerSecretImport(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { | ||
attributes := strings.SplitN(d.Id(), "/", 3) | ||
|
||
if len(attributes) != 3 { | ||
return []*schema.ResourceData{nil}, fmt.Errorf(`invalid id (%q) specified, should be in format "accountID/scriptName/secretName"`, d.Id()) | ||
} | ||
|
||
accountID, scriptName, secretName := attributes[0], attributes[1], attributes[2] | ||
|
||
d.SetId(stringChecksum(fmt.Sprintf("%s/%s/%s", accountID, scriptName, secretName))) | ||
d.Set("name", secretName) | ||
d.Set(consts.AccountIDSchemaKey, accountID) | ||
d.Set("script_name", scriptName) | ||
|
||
resourceCloudflareWorkerSecretRead(ctx, d, meta) | ||
|
||
return []*schema.ResourceData{d}, nil | ||
} |
104 changes: 104 additions & 0 deletions
104
internal/sdkv2provider/resource_cloudflare_workers_secret_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package sdkv2provider | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"testing" | ||
|
||
"github.com/cloudflare/cloudflare-go" | ||
"github.com/hashicorp/terraform-plugin-testing/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-testing/terraform" | ||
) | ||
|
||
const scriptContentForSecret = `addEventListener('fetch', event => {event.respondWith(new Response('test 1'))});` | ||
|
||
var workerSecretTestScriptName string | ||
|
||
func TestAccCloudflareWorkerSecret_Basic(t *testing.T) { | ||
t.Parallel() | ||
|
||
name := generateRandomResourceName() | ||
secretText := generateRandomResourceName() | ||
workerSecretTestScriptName = generateRandomResourceName() | ||
accountId := os.Getenv("CLOUDFLARE_ACCOUNT_ID") | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { | ||
testAccPreCheck(t) | ||
testAccPreCheckAccount(t) | ||
}, | ||
ProviderFactories: providerFactories, | ||
CheckDestroy: testAccCheckCloudflareWorkerSecretDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccCheckCloudflareWorkerSecretWithWorkerScript(workerSecretTestScriptName, name, secretText, accountId), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckCloudflareWorkerSecretExists(workerSecretTestScriptName, name, accountId), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckCloudflareWorkerSecretDestroy(s *terraform.State) error { | ||
accountId := os.Getenv("CLOUDFLARE_ACCOUNT_ID") | ||
|
||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "cloudflare_worker_secret" { | ||
continue | ||
} | ||
|
||
client := testAccProvider.Meta().(*cloudflare.API) | ||
params := cloudflare.ListWorkersSecretsParams{ | ||
ScriptName: rs.Primary.Attributes["script_name"], | ||
} | ||
|
||
secretResponse, err := client.ListWorkersSecrets(context.Background(), cloudflare.AccountIdentifier(accountId), params) | ||
|
||
if err == nil { | ||
return fmt.Errorf("worker secret with name %s still exists against Worker Script %s", secretResponse.Result[0].Name, params.ScriptName) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func testAccCheckCloudflareWorkerSecretWithWorkerScript(scriptName string, name string, secretText string, accountId string) string { | ||
return fmt.Sprintf(` | ||
resource "cloudflare_worker_script" "%[2]s" { | ||
account_id = "%[4]s" | ||
name = "%[1]s" | ||
content = "%[5]s" | ||
} | ||
|
||
resource "cloudflare_worker_secret" "%[2]s" { | ||
account_id = "%[4]s" | ||
script_name = cloudflare_worker_script.%[2]s.name | ||
name = "%[2]s" | ||
secret_text = "%[3]s" | ||
}`, scriptName, name, secretText, accountId, scriptContentForSecret) | ||
} | ||
|
||
func testAccCheckCloudflareWorkerSecretExists(scriptName string, name string, accountId string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
client := testAccProvider.Meta().(*cloudflare.API) | ||
params := cloudflare.ListWorkersSecretsParams{ | ||
ScriptName: scriptName, | ||
} | ||
|
||
secretResponse, err := client.ListWorkersSecrets(context.Background(), cloudflare.AccountIdentifier(accountId), params) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
for _, secret := range secretResponse.Result { | ||
if secret.Name == name { | ||
return nil | ||
} | ||
} | ||
|
||
return fmt.Errorf("worker secret with name %s not found against Worker Script %s", name, scriptName) | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
internal/sdkv2provider/schema_cloudflare_workers_secret.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package sdkv2provider | ||
|
||
import ( | ||
"github.com/cloudflare/terraform-provider-cloudflare/internal/consts" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
) | ||
|
||
func resourceCloudflareWorkerSecretSchema() map[string]*schema.Schema { | ||
return map[string]*schema.Schema{ | ||
consts.AccountIDSchemaKey: { | ||
Description: consts.AccountIDSchemaDescription, | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"script_name": { | ||
Type: schema.TypeString, | ||
ForceNew: true, | ||
Required: true, | ||
Description: "The name of the Worker script to associate the secret with.", | ||
}, | ||
"name": { | ||
Type: schema.TypeString, | ||
ForceNew: true, | ||
Required: true, | ||
Description: "The name of the Worker secret.", | ||
}, | ||
"secret_text": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Sensitive: true, | ||
Description: "The text of the Worker secret, this cannot be read back after creation and is stored encrypted .", | ||
}, | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should include a
ImportState
assertion here too (which would have caught your incorrectImport
ID above).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added back a separate import secret test to be consistent with the other tests. This is currently failing with:
This is because the Cloudflare API doesn't let you read back the secret text as it's encrypted. I'm not sure how to reconcile this to make the tests pass?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got the tests to pass by ignoring state verification for that field