From ea1b00200f6904f38862602cf33fe4ef32ff0a18 Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Fri, 26 Oct 2018 16:18:03 +1100 Subject: [PATCH] Make `cloudflare_access_rule` importable for all rule types There are currently three different levels of firewall access rules: - `user`: Applied to a personal account - `zone`: Applied to an account but restricted to a single zone - `account`: Applied to all sites within an account Prior to this commit, importing was only available for the user type which made it unusable for organisations or users with multiple zones that they wanted to manage. As a result of this change, the import identifier has changed. It now requires: - `accessRuleType`: Either `account`, `zone` or `user` (`user is pretty much a noop`) - `accessRuleIdentifier`: The ID of the access rule type you intend to use (`zone.id` or `account.id`). - `identifierValue`: The access rule ID from the API. Included here is an update to the documentation for the provider website for the new identifier values and import usage. Fixes #118 --- cloudflare/resource_cloudflare_access_rule.go | 35 +++++++++++++++++-- website/docs/r/access_rule.html.markdown | 11 ++++-- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/cloudflare/resource_cloudflare_access_rule.go b/cloudflare/resource_cloudflare_access_rule.go index d304dca567..35143e7d6a 100644 --- a/cloudflare/resource_cloudflare_access_rule.go +++ b/cloudflare/resource_cloudflare_access_rule.go @@ -17,7 +17,7 @@ func resourceCloudflareAccessRule() *schema.Resource { Update: resourceCloudflareAccessRuleUpdate, Delete: resourceCloudflareAccessRuleDelete, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + State: resourceCloudflareAccessRuleImport, }, Schema: map[string]*schema.Schema{ @@ -133,6 +133,7 @@ func resourceCloudflareAccessRuleRead(d *schema.ResourceData, meta interface{}) if client.OrganizationID != "" { accessRuleResponse, err = client.OrganizationAccessRule(client.OrganizationID, d.Id()) } else { + accessRuleResponse, err = client.UserAccessRule(d.Id()) } } else { @@ -144,7 +145,7 @@ func resourceCloudflareAccessRuleRead(d *schema.ResourceData, meta interface{}) if err != nil { if strings.Contains(err.Error(), "HTTP status 404") { - log.Printf("[INFO] Page Rule %s no longer exists", d.Id()) + log.Printf("[INFO] Access Rule %s no longer exists", d.Id()) d.SetId("") return nil } @@ -229,6 +230,36 @@ func resourceCloudflareAccessRuleDelete(d *schema.ResourceData, meta interface{} return nil } +func resourceCloudflareAccessRuleImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + client := meta.(*cloudflare.API) + attributes := strings.Split(d.Id(), "/") + + var ( + accessRuleType string + accessRuleTypeIdentifier string + accessRuleID string + ) + + if len(attributes) != 3 { + return nil, fmt.Errorf("invalid id (\"%s\") specified, should be in format \"accessRuleType/accessRuleTypeIdentifier/identiferValue\"", d.Id()) + } + + accessRuleType, accessRuleTypeIdentifier, accessRuleID = attributes[0], attributes[1], attributes[2] + + d.SetId(accessRuleID) + + switch accessRuleType { + case "account": + client.OrganizationID = accessRuleTypeIdentifier + case "zone": + d.Set("zone_id", accessRuleTypeIdentifier) + } + + resourceCloudflareAccessRuleRead(d, meta) + + return []*schema.ResourceData{d}, nil +} + func configurationDiffSuppress(k, old, new string, d *schema.ResourceData) bool { switch { case d.Get("configuration.target") == "country" && diff --git a/website/docs/r/access_rule.html.markdown b/website/docs/r/access_rule.html.markdown index 7f5aaed5ea..f5fb05a9b7 100644 --- a/website/docs/r/access_rule.html.markdown +++ b/website/docs/r/access_rule.html.markdown @@ -81,12 +81,17 @@ The following attributes are exported: ## Import -Records can be imported using a composite ID formed of zone name and record ID, e.g. +Records can be imported using a composite ID formed of access rule type, +access rule type identifier and identifer value, e.g. ``` -$ terraform import cloudflare_access_rule.default d41d8cd98f00b204e9800998ecf8427e +$ terraform import cloudflare_access_rule.default zone/cb029e245cfdd66dc8d2e570d5dd3322/d41d8cd98f00b204e9800998ecf8427e ``` where: -* `d41d8cd98f00b204e9800998ecf8427e` - access rule ID as returned by [API](https://api.cloudflare.com/#user-level-firewall-access-rule-list-access-rules) +* `zone` - access rule type (`account`, `zone` or `user`) +* `cb029e245cfdd66dc8d2e570d5dd3322` - access rule type ID (i.e the zone ID + or account ID you wish to target) +* `d41d8cd98f00b204e9800998ecf8427e` - access rule ID as returned by + respective API endpoint for the type you are attempting to import.