Skip to content
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

resource/cloudflare_worker_cron_trigger: Add initial support #926

Merged
merged 1 commit into from
Feb 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cloudflare/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ func Provider() terraform.ResourceProvider {
"cloudflare_waf_package": resourceCloudflareWAFPackage(),
"cloudflare_waf_rule": resourceCloudflareWAFRule(),
"cloudflare_waf_override": resourceCloudflareWAFOverride(),
"cloudflare_worker_cron_trigger": resourceCloudflareWorkerCronTrigger(),
"cloudflare_worker_route": resourceCloudflareWorkerRoute(),
"cloudflare_worker_script": resourceCloudflareWorkerScript(),
"cloudflare_workers_kv": resourceCloudflareWorkerKV(),
Expand Down
109 changes: 109 additions & 0 deletions cloudflare/resource_cloudflare_worker_cron_trigger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package cloudflare

import (
"context"
"fmt"

"github.com/cloudflare/cloudflare-go"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func resourceCloudflareWorkerCronTrigger() *schema.Resource {
return &schema.Resource{
Create: resourceCloudflareWorkerCronTriggerUpdate,
Read: resourceCloudflareWorkerCronTriggerRead,
Update: resourceCloudflareWorkerCronTriggerUpdate,
Delete: resourceCloudflareWorkerCronTriggerDelete,
Importer: &schema.ResourceImporter{
State: resourceCloudflareWorkerCronTriggerImport,
},

Schema: map[string]*schema.Schema{
"script_name": {
Type: schema.TypeString,
Required: true,
},
"schedules": {
Type: schema.TypeSet,
Required: true,
MinItems: 1,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
}
}

// resourceCloudflareWorkerCronTriggerUpdate is used for creation and updates of
// Worker Cron Triggers as the remote API endpoint is shared uses HTTP PUT.
func resourceCloudflareWorkerCronTriggerUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*cloudflare.API)

scriptName := d.Get("script_name").(string)

_, err := client.UpdateWorkerCronTriggers(context.Background(), scriptName, transformSchemaToWorkerCronTriggerStruct(d))
if err != nil {
return fmt.Errorf("failed to update Worker Cron Trigger: %s", err)
}

d.SetId(stringChecksum(scriptName))

return nil
}

func resourceCloudflareWorkerCronTriggerRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*cloudflare.API)
scriptName := d.Get("script_name").(string)

s, err := client.ListWorkerCronTriggers(context.Background(), scriptName)
if err != nil {
return fmt.Errorf("failed to read Worker Cron Trigger: %s", err)
}

if err := d.Set("schedules", transformWorkerCronTriggerStructToSet(s)); err != nil {
return fmt.Errorf("failed to set schedules attribute: %s", err)
}

return nil
}

func resourceCloudflareWorkerCronTriggerDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*cloudflare.API)
scriptName := d.Get("script_name").(string)

client.UpdateWorkerCronTriggers(context.Background(), scriptName, []cloudflare.WorkerCronTrigger{})

d.SetId("")

return nil
}

func resourceCloudflareWorkerCronTriggerImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
d.SetId(stringChecksum(d.Id()))

resourceCloudflareWorkerCronTriggerRead(d, meta)

return []*schema.ResourceData{d}, nil
}

func transformWorkerCronTriggerStructToSet(triggers []cloudflare.WorkerCronTrigger) *schema.Set {
returnSet := schema.NewSet(schema.HashString, []interface{}{})

for _, trigger := range triggers {
returnSet.Add(trigger.Cron)
}

return returnSet
}

func transformSchemaToWorkerCronTriggerStruct(d *schema.ResourceData) []cloudflare.WorkerCronTrigger {
triggers := []cloudflare.WorkerCronTrigger{}
schedules := d.Get("schedules").(*schema.Set).List()

for _, schedule := range schedules {
triggers = append(triggers, cloudflare.WorkerCronTrigger{Cron: schedule.(string)})
}

return triggers
}
46 changes: 46 additions & 0 deletions cloudflare/resource_cloudflare_worker_cron_trigger_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package cloudflare

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
)

func TestAccCloudflareWorkerCronTriggerBasic(t *testing.T) {
rnd := generateRandomResourceName()
name := fmt.Sprintf("cloudflare_worker_cron_trigger.%s", rnd)

resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccessAccPreCheck(t)
},
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccCloudflareWorkerCronTriggerConfigBasic(rnd),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(name, "script_name", rnd),
resource.TestCheckResourceAttr(name, "schedules.#", "2"),
),
},
},
})
}

func testAccCloudflareWorkerCronTriggerConfigBasic(rnd string) string {
return fmt.Sprintf(`
resource "cloudflare_worker_script" "%[1]s" {
name = "%[1]s"
content = "addEventListener('fetch', event => {event.respondWith(new Response('test'))});"
}

resource "cloudflare_worker_cron_trigger" "%[1]s" {
script_name = cloudflare_worker_script.%[1]s.name
schedules = [
"*/5 * * * *", # every 5 minutes
"10 7 * * mon-fri", # 7:10am every weekday
]
}
`, rnd)
}
3 changes: 3 additions & 0 deletions website/cloudflare.erb
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@
<li<%= sidebar_current("docs-cloudflare-resource-waf-rule") %>>
<a href="/docs/providers/cloudflare/r/waf_rule.html">cloudflare_waf_rule</a>
</li>
<li<%= sidebar_current("docs-cloudflare-resource-worker-cron-trigger") %>>
<a href="/docs/providers/cloudflare/r/worker_cron_trigger.html">cloudflare_worker_cron_trigger</a>
</li>
<li<%= sidebar_current("docs-cloudflare-resource-worker-route") %>>
<a href="/docs/providers/cloudflare/r/worker_route.html">cloudflare_worker_route</a>
</li>
Expand Down
56 changes: 56 additions & 0 deletions website/docs/r/worker_cron_trigger.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
layout: "cloudflare"
page_title: "Cloudflare: cloudflare_worker_cron_trigger"
sidebar_current: "docs-cloudflare-resource-worker-cron-trigger"
description: |-
Provides a Cloudflare Worker Cron Trigger resource.
---

# cloudflare_worker_cron_trigger

Worker Cron Triggers allow users to map a cron expression to a Worker script
using a `ScheduledEvent` listener that enables Workers to be executed on a
schedule. Worker Cron Triggers are ideal for running periodic jobs for
maintenance or calling third-party APIs to collect up-to-date data.

## Example Usage

```hcl
resource "cloudflare_worker_script" "example_script" {
name = "example-script"
content = file("path/to/my.js")
}

resource "cloudflare_worker_cron_trigger" "example_trigger" {
script_name = cloudflare_worker_script.example_script.name
schedules = [
"*/5 * * * *", # every 5 minutes
"10 7 * * mon-fri", # 7:10am every weekday
]
}
```

## Argument Reference

The following arguments are supported:


* `script_name` - (Required) Worker script to target for the schedules
* `schedules` - (Required) List of cron expressions to execute the Worker Script

## Attributes Reference

The following additional attributes are exported:

* `id` - md5 checksum of the script name
* `script_name` - Name of the Worker Script being targeted
* `schedules` - List of cron expressions in use

## Import

Worker Cron Triggers can be imported using the script name of the Worker they
are targeting.

```
$ terraform import cloudflare_worker_cron_trigger.example my-script
```