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