github.com/recobe182/terraform@v0.8.5-0.20170117231232-49ab22a935b7/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 }, 48 "tenant_id": &schema.Schema{ 49 Type: schema.TypeString, 50 Optional: true, 51 ForceNew: true, 52 Computed: true, 53 }, 54 "rules": &schema.Schema{ 55 Type: schema.TypeList, 56 Optional: true, 57 Elem: &schema.Schema{Type: schema.TypeString}, 58 }, 59 "value_specs": &schema.Schema{ 60 Type: schema.TypeMap, 61 Optional: true, 62 ForceNew: true, 63 }, 64 }, 65 } 66 } 67 68 func resourceFWPolicyV1Create(d *schema.ResourceData, meta interface{}) error { 69 config := meta.(*Config) 70 networkingClient, err := config.networkingV2Client(GetRegion(d)) 71 if err != nil { 72 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 73 } 74 75 v := d.Get("rules").([]interface{}) 76 77 log.Printf("[DEBUG] Rules found : %#v", v) 78 log.Printf("[DEBUG] Rules count : %d", len(v)) 79 80 rules := make([]string, len(v)) 81 for i, v := range v { 82 rules[i] = v.(string) 83 } 84 85 audited := d.Get("audited").(bool) 86 87 opts := PolicyCreateOpts{ 88 policies.CreateOpts{ 89 Name: d.Get("name").(string), 90 Description: d.Get("description").(string), 91 Audited: &audited, 92 TenantID: d.Get("tenant_id").(string), 93 Rules: rules, 94 }, 95 MapValueSpecs(d), 96 } 97 98 if r, ok := d.GetOk("shared"); ok { 99 shared := r.(bool) 100 opts.Shared = &shared 101 } 102 103 log.Printf("[DEBUG] Create firewall policy: %#v", opts) 104 105 policy, err := policies.Create(networkingClient, opts).Extract() 106 if err != nil { 107 return err 108 } 109 110 log.Printf("[DEBUG] Firewall policy created: %#v", policy) 111 112 d.SetId(policy.ID) 113 114 return resourceFWPolicyV1Read(d, meta) 115 } 116 117 func resourceFWPolicyV1Read(d *schema.ResourceData, meta interface{}) error { 118 log.Printf("[DEBUG] Retrieve information about firewall policy: %s", d.Id()) 119 120 config := meta.(*Config) 121 networkingClient, err := config.networkingV2Client(GetRegion(d)) 122 if err != nil { 123 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 124 } 125 126 policy, err := policies.Get(networkingClient, d.Id()).Extract() 127 if err != nil { 128 return CheckDeleted(d, err, "FW policy") 129 } 130 131 log.Printf("[DEBUG] Read OpenStack Firewall Policy %s: %#v", d.Id(), policy) 132 133 d.Set("name", policy.Name) 134 d.Set("description", policy.Description) 135 d.Set("shared", policy.Shared) 136 d.Set("audited", policy.Audited) 137 d.Set("tenant_id", policy.TenantID) 138 d.Set("rules", policy.Rules) 139 d.Set("region", GetRegion(d)) 140 141 return nil 142 } 143 144 func resourceFWPolicyV1Update(d *schema.ResourceData, meta interface{}) error { 145 config := meta.(*Config) 146 networkingClient, err := config.networkingV2Client(GetRegion(d)) 147 if err != nil { 148 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 149 } 150 151 opts := policies.UpdateOpts{} 152 153 if d.HasChange("name") { 154 opts.Name = d.Get("name").(string) 155 } 156 157 if d.HasChange("description") { 158 opts.Description = d.Get("description").(string) 159 } 160 161 if d.HasChange("rules") { 162 v := d.Get("rules").([]interface{}) 163 164 log.Printf("[DEBUG] Rules found : %#v", v) 165 log.Printf("[DEBUG] Rules count : %d", len(v)) 166 167 rules := make([]string, len(v)) 168 for i, v := range v { 169 rules[i] = v.(string) 170 } 171 opts.Rules = rules 172 } 173 174 log.Printf("[DEBUG] Updating firewall policy with id %s: %#v", d.Id(), opts) 175 176 err = policies.Update(networkingClient, d.Id(), opts).Err 177 if err != nil { 178 return err 179 } 180 181 return resourceFWPolicyV1Read(d, meta) 182 } 183 184 func resourceFWPolicyV1Delete(d *schema.ResourceData, meta interface{}) error { 185 log.Printf("[DEBUG] Destroy firewall policy: %s", d.Id()) 186 187 config := meta.(*Config) 188 networkingClient, err := config.networkingV2Client(GetRegion(d)) 189 if err != nil { 190 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 191 } 192 193 stateConf := &resource.StateChangeConf{ 194 Pending: []string{"ACTIVE"}, 195 Target: []string{"DELETED"}, 196 Refresh: waitForFirewallPolicyDeletion(networkingClient, d.Id()), 197 Timeout: 120 * time.Second, 198 Delay: 0, 199 MinTimeout: 2 * time.Second, 200 } 201 202 if _, err = stateConf.WaitForState(); err != nil { 203 return err 204 } 205 206 return nil 207 } 208 209 func waitForFirewallPolicyDeletion(networkingClient *gophercloud.ServiceClient, id string) resource.StateRefreshFunc { 210 return func() (interface{}, string, error) { 211 err := policies.Delete(networkingClient, id).Err 212 if err == nil { 213 return "", "DELETED", nil 214 } 215 216 if errCode, ok := err.(gophercloud.ErrUnexpectedResponseCode); ok { 217 if errCode.Actual == 409 { 218 // This error usually means that the policy is attached 219 // to a firewall. At this point, the firewall is probably 220 // being delete. So, we retry a few times. 221 return nil, "ACTIVE", nil 222 } 223 } 224 225 return nil, "ACTIVE", err 226 } 227 }