github.com/minamijoyo/terraform@v0.7.8-0.20161029001309-18b3736ba44b/builtin/providers/openstack/resource_openstack_fw_policy_v1.go (about) 1 package openstack 2 3 import ( 4 "fmt" 5 "log" 6 "time" 7 8 "github.com/gophercloud/gophercloud" 9 "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/fwaas/policies" 10 "github.com/hashicorp/terraform/helper/resource" 11 "github.com/hashicorp/terraform/helper/schema" 12 ) 13 14 func resourceFWPolicyV1() *schema.Resource { 15 return &schema.Resource{ 16 Create: resourceFWPolicyV1Create, 17 Read: resourceFWPolicyV1Read, 18 Update: resourceFWPolicyV1Update, 19 Delete: resourceFWPolicyV1Delete, 20 Importer: &schema.ResourceImporter{ 21 State: schema.ImportStatePassthrough, 22 }, 23 24 Schema: map[string]*schema.Schema{ 25 "region": &schema.Schema{ 26 Type: schema.TypeString, 27 Required: true, 28 ForceNew: true, 29 DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""), 30 }, 31 "name": &schema.Schema{ 32 Type: schema.TypeString, 33 Optional: true, 34 }, 35 "description": &schema.Schema{ 36 Type: schema.TypeString, 37 Optional: true, 38 }, 39 "audited": &schema.Schema{ 40 Type: schema.TypeBool, 41 Optional: true, 42 Default: false, 43 }, 44 "shared": &schema.Schema{ 45 Type: schema.TypeBool, 46 Optional: true, 47 Default: false, 48 }, 49 "tenant_id": &schema.Schema{ 50 Type: schema.TypeString, 51 Optional: true, 52 ForceNew: true, 53 Computed: true, 54 }, 55 "rules": &schema.Schema{ 56 Type: schema.TypeList, 57 Optional: true, 58 Elem: &schema.Schema{Type: schema.TypeString}, 59 }, 60 }, 61 } 62 } 63 64 func resourceFWPolicyV1Create(d *schema.ResourceData, meta interface{}) error { 65 config := meta.(*Config) 66 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 67 if err != nil { 68 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 69 } 70 71 v := d.Get("rules").([]interface{}) 72 73 log.Printf("[DEBUG] Rules found : %#v", v) 74 log.Printf("[DEBUG] Rules count : %d", len(v)) 75 76 rules := make([]string, len(v)) 77 for i, v := range v { 78 rules[i] = v.(string) 79 } 80 81 audited := d.Get("audited").(bool) 82 shared := d.Get("shared").(bool) 83 84 opts := policies.CreateOpts{ 85 Name: d.Get("name").(string), 86 Description: d.Get("description").(string), 87 Audited: &audited, 88 Shared: &shared, 89 TenantID: d.Get("tenant_id").(string), 90 Rules: rules, 91 } 92 93 log.Printf("[DEBUG] Create firewall policy: %#v", opts) 94 95 policy, err := policies.Create(networkingClient, opts).Extract() 96 if err != nil { 97 return err 98 } 99 100 log.Printf("[DEBUG] Firewall policy created: %#v", policy) 101 102 d.SetId(policy.ID) 103 104 return resourceFWPolicyV1Read(d, meta) 105 } 106 107 func resourceFWPolicyV1Read(d *schema.ResourceData, meta interface{}) error { 108 log.Printf("[DEBUG] Retrieve information about firewall policy: %s", d.Id()) 109 110 config := meta.(*Config) 111 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 112 if err != nil { 113 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 114 } 115 116 policy, err := policies.Get(networkingClient, d.Id()).Extract() 117 if err != nil { 118 return CheckDeleted(d, err, "FW policy") 119 } 120 121 log.Printf("[DEBUG] Read OpenStack Firewall Policy %s: %#v", d.Id(), policy) 122 123 d.Set("name", policy.Name) 124 d.Set("description", policy.Description) 125 d.Set("shared", policy.Shared) 126 d.Set("audited", policy.Audited) 127 d.Set("tenant_id", policy.TenantID) 128 d.Set("rules", policy.Rules) 129 return nil 130 } 131 132 func resourceFWPolicyV1Update(d *schema.ResourceData, meta interface{}) error { 133 config := meta.(*Config) 134 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 135 if err != nil { 136 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 137 } 138 139 opts := policies.UpdateOpts{} 140 141 if d.HasChange("name") { 142 opts.Name = d.Get("name").(string) 143 } 144 145 if d.HasChange("description") { 146 opts.Description = d.Get("description").(string) 147 } 148 149 if d.HasChange("rules") { 150 v := d.Get("rules").([]interface{}) 151 152 log.Printf("[DEBUG] Rules found : %#v", v) 153 log.Printf("[DEBUG] Rules count : %d", len(v)) 154 155 rules := make([]string, len(v)) 156 for i, v := range v { 157 rules[i] = v.(string) 158 } 159 opts.Rules = rules 160 } 161 162 log.Printf("[DEBUG] Updating firewall policy with id %s: %#v", d.Id(), opts) 163 164 err = policies.Update(networkingClient, d.Id(), opts).Err 165 if err != nil { 166 return err 167 } 168 169 return resourceFWPolicyV1Read(d, meta) 170 } 171 172 func resourceFWPolicyV1Delete(d *schema.ResourceData, meta interface{}) error { 173 log.Printf("[DEBUG] Destroy firewall policy: %s", d.Id()) 174 175 config := meta.(*Config) 176 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 177 if err != nil { 178 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 179 } 180 181 stateConf := &resource.StateChangeConf{ 182 Pending: []string{"ACTIVE"}, 183 Target: []string{"DELETED"}, 184 Refresh: waitForFirewallPolicyDeletion(networkingClient, d.Id()), 185 Timeout: 120 * time.Second, 186 Delay: 0, 187 MinTimeout: 2 * time.Second, 188 } 189 190 if _, err = stateConf.WaitForState(); err != nil { 191 return err 192 } 193 194 return nil 195 } 196 197 func waitForFirewallPolicyDeletion(networkingClient *gophercloud.ServiceClient, id string) resource.StateRefreshFunc { 198 return func() (interface{}, string, error) { 199 err := policies.Delete(networkingClient, id).Err 200 if err == nil { 201 return "", "DELETED", nil 202 } 203 204 if errCode, ok := err.(gophercloud.ErrUnexpectedResponseCode); ok { 205 if errCode.Actual == 409 { 206 // This error usually means that the policy is attached 207 // to a firewall. At this point, the firewall is probably 208 // being delete. So, we retry a few times. 209 return nil, "ACTIVE", nil 210 } 211 } 212 213 return nil, "ACTIVE", err 214 } 215 }