diff --git a/cloudflare/resource_cloudflare_access_policy.go b/cloudflare/resource_cloudflare_access_policy.go index 034a22adb8..6de95f6369 100644 --- a/cloudflare/resource_cloudflare_access_policy.go +++ b/cloudflare/resource_cloudflare_access_policy.go @@ -86,6 +86,17 @@ var policyOptionElement = &schema.Resource{ Type: schema.TypeString, }, }, + "service_token": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "any_valid_service_token": { + Type: schema.TypeBool, + Optional: true, + }, "everyone": { Type: schema.TypeBool, Optional: true, @@ -245,6 +256,11 @@ func buildAccessPolicyCondition(options map[string]interface{}) []interface{} { log.Printf("[DEBUG] values for everyone %s", values) policy = append(policy, cloudflare.AccessPolicyEveryone{}) } + } else if accessPolicyType == "any_valid_service_token" { + if values == true { + log.Printf("[DEBUG] values for any_valid_service_token %s", values) + policy = append(policy, cloudflare.AccessPolicyAnyValidServiceToken{}) + } } else { for _, value := range values.([]interface{}) { switch accessPolicyType { @@ -260,6 +276,10 @@ func buildAccessPolicyCondition(options map[string]interface{}) []interface{} { policy = append(policy, cloudflare.AccessPolicyIP{IP: struct { IP string `json:"ip"` }{IP: value.(string)}}) + case "service_token": + policy = append(policy, cloudflare.AccessPolicyServiceToken{ServiceToken: struct { + ID string `json:"token_id"` + }{ID: value.(string)}}) } } } diff --git a/cloudflare/resource_cloudflare_access_policy_test.go b/cloudflare/resource_cloudflare_access_policy_test.go new file mode 100644 index 0000000000..5f7643b59c --- /dev/null +++ b/cloudflare/resource_cloudflare_access_policy_test.go @@ -0,0 +1,131 @@ +package cloudflare + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func TestAccAccessPolicyServiceToken(t *testing.T) { + // Temporarily unset CLOUDFLARE_API_TOKEN if it is set as the Access + // service does not yet support the API tokens and it results in + // misleading state error messages. + if os.Getenv("CLOUDFLARE_API_TOKEN") != "" { + defer func(apiToken string) { + os.Setenv("CLOUDFLARE_API_TOKEN", apiToken) + }(os.Getenv("CLOUDFLARE_API_TOKEN")) + os.Setenv("CLOUDFLARE_API_TOKEN", "") + } + + rnd := generateRandomResourceName() + name := "cloudflare_access_policy." + rnd + zone := os.Getenv("CLOUDFLARE_DOMAIN") + zoneID := os.Getenv("CLOUDFLARE_ZONE_ID") + accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAccount(t) + }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccessPolicyServiceTokenConfig(rnd, zone, zoneID, accountID), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(name, "name", rnd), + resource.TestCheckResourceAttr(name, "zone_id", zoneID), + resource.TestCheckResourceAttr(name, "include.0.service_token.#", "1"), + ), + }, + }, + }) +} + +func TestAccAccessPolicyAnyServiceToken(t *testing.T) { + // Temporarily unset CLOUDFLARE_API_TOKEN if it is set as the Access + // service does not yet support the API tokens and it results in + // misleading state error messages. + if os.Getenv("CLOUDFLARE_API_TOKEN") != "" { + defer func(apiToken string) { + os.Setenv("CLOUDFLARE_API_TOKEN", apiToken) + }(os.Getenv("CLOUDFLARE_API_TOKEN")) + os.Setenv("CLOUDFLARE_API_TOKEN", "") + } + + rnd := generateRandomResourceName() + name := "cloudflare_access_policy." + rnd + zone := os.Getenv("CLOUDFLARE_DOMAIN") + zoneID := os.Getenv("CLOUDFLARE_ZONE_ID") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAccount(t) + }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccessPolicyAnyServiceTokenConfig(rnd, zone, zoneID), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(name, "name", rnd), + resource.TestCheckResourceAttr(name, "zone_id", zoneID), + resource.TestCheckResourceAttr(name, "include.0.any_valid_service_token", "true"), + ), + }, + }, + }) +} + +func testAccessPolicyServiceTokenConfig(resourceID, zone, zoneID, accountID string) string { + return fmt.Sprintf(` + resource "cloudflare_access_application" "%[1]s" { + name = "%[1]s" + zone_id = "%[3]s" + domain = "%[1]s.%[2]s" + } + + resource "cloudflare_access_service_token" "%[1]s" { + account_id = "%[4]s" + name = "%[1]s" + } + + resource "cloudflare_access_policy" "%[1]s" { + application_id = "${cloudflare_access_application.%[1]s.id}" + name = "%[1]s" + zone_id = "%[3]s" + decision = "non_identity" + precedence = "10" + + include { + service_token = ["${cloudflare_access_service_token.%[1]s.id}"] + } + } + + `, resourceID, zone, zoneID, accountID) +} + +func testAccessPolicyAnyServiceTokenConfig(resourceID, zone, zoneID string) string { + return fmt.Sprintf(` + resource "cloudflare_access_application" "%[1]s" { + name = "%[1]s" + zone_id = "%[3]s" + domain = "%[1]s.%[2]s" + } + + resource "cloudflare_access_policy" "%[1]s" { + application_id = "${cloudflare_access_application.%[1]s.id}" + name = "%[1]s" + zone_id = "%[3]s" + decision = "non_identity" + precedence = "10" + + include { + any_valid_service_token = true + } + } + + `, resourceID, zone, zoneID) +} diff --git a/website/docs/r/access_policy.html.markdown b/website/docs/r/access_policy.html.markdown index a34e4f61eb..6f1e3e6481 100644 --- a/website/docs/r/access_policy.html.markdown +++ b/website/docs/r/access_policy.html.markdown @@ -56,7 +56,7 @@ The following arguments are supported: * `zone_id` - (Required) The DNS zone to which the access rule should be added. * `decision` - (Required) Defines the action Access will take if the policy matches the user. - Allowed values: `allow`, `deny`, `bypass` + Allowed values: `allow`, `deny`, `non_identity`, `bypass` * `name` - (Required) Friendly name of the Access Application. * `precedence` - (Optional) The unique precedence for policies on a single application. Integer. * `require` - (Optional) A series of access conditions, see below for @@ -77,6 +77,10 @@ conditions which can be applied. The conditions are: `email = ["test@example.com"]` * `email_domain` - (Optional) A list of email domains. Example: `email_domain = ["example.com"]` +* `service_token` - (Optional) A list of service token ids. Example: + `service_token = cloudflare_access_service_token.demo.id` +* `any_valid_service_token` - (Optional) Boolean indicating if allow + all tokens to be granted. Example: `any_valid_service_token = true` * `everyone` - (Optional) Boolean indicating permitting access for all requests. Example: `everyone = true`