github.com/gabrielperezs/terraform@v0.7.0-rc2.0.20160715084931-f7da2612946f/builtin/providers/openstack/resource_openstack_networking_secgroup_rule_v2.go (about) 1 package openstack 2 3 import ( 4 "fmt" 5 "log" 6 "strings" 7 "time" 8 9 "github.com/hashicorp/terraform/helper/resource" 10 "github.com/hashicorp/terraform/helper/schema" 11 12 "github.com/rackspace/gophercloud" 13 "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/security/rules" 14 ) 15 16 func resourceNetworkingSecGroupRuleV2() *schema.Resource { 17 return &schema.Resource{ 18 Create: resourceNetworkingSecGroupRuleV2Create, 19 Read: resourceNetworkingSecGroupRuleV2Read, 20 Delete: resourceNetworkingSecGroupRuleV2Delete, 21 Importer: &schema.ResourceImporter{ 22 State: schema.ImportStatePassthrough, 23 }, 24 25 Schema: map[string]*schema.Schema{ 26 "region": &schema.Schema{ 27 Type: schema.TypeString, 28 Required: true, 29 ForceNew: true, 30 DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""), 31 }, 32 "direction": &schema.Schema{ 33 Type: schema.TypeString, 34 Required: true, 35 ForceNew: true, 36 }, 37 "ethertype": &schema.Schema{ 38 Type: schema.TypeString, 39 Required: true, 40 ForceNew: true, 41 }, 42 "port_range_min": &schema.Schema{ 43 Type: schema.TypeInt, 44 Optional: true, 45 ForceNew: true, 46 Computed: true, 47 }, 48 "port_range_max": &schema.Schema{ 49 Type: schema.TypeInt, 50 Optional: true, 51 ForceNew: true, 52 Computed: true, 53 }, 54 "protocol": &schema.Schema{ 55 Type: schema.TypeString, 56 Optional: true, 57 ForceNew: true, 58 Computed: true, 59 }, 60 "remote_group_id": &schema.Schema{ 61 Type: schema.TypeString, 62 Optional: true, 63 ForceNew: true, 64 Computed: true, 65 }, 66 "remote_ip_prefix": &schema.Schema{ 67 Type: schema.TypeString, 68 Optional: true, 69 ForceNew: true, 70 Computed: true, 71 StateFunc: func(v interface{}) string { 72 return strings.ToLower(v.(string)) 73 }, 74 }, 75 "security_group_id": &schema.Schema{ 76 Type: schema.TypeString, 77 Required: true, 78 ForceNew: true, 79 }, 80 "tenant_id": &schema.Schema{ 81 Type: schema.TypeString, 82 Optional: true, 83 ForceNew: true, 84 Computed: true, 85 }, 86 }, 87 } 88 } 89 90 func resourceNetworkingSecGroupRuleV2Create(d *schema.ResourceData, meta interface{}) error { 91 92 config := meta.(*Config) 93 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 94 if err != nil { 95 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 96 } 97 98 portRangeMin := d.Get("port_range_min").(int) 99 portRangeMax := d.Get("port_range_max").(int) 100 protocol := d.Get("protocol").(string) 101 102 if protocol == "" { 103 if portRangeMin != 0 || portRangeMax != 0 { 104 return fmt.Errorf("A protocol must be specified when using port_range_min and port_range_max") 105 } 106 } 107 108 opts := rules.CreateOpts{ 109 Direction: d.Get("direction").(string), 110 EtherType: d.Get("ethertype").(string), 111 SecGroupID: d.Get("security_group_id").(string), 112 PortRangeMin: d.Get("port_range_min").(int), 113 PortRangeMax: d.Get("port_range_max").(int), 114 Protocol: d.Get("protocol").(string), 115 RemoteGroupID: d.Get("remote_group_id").(string), 116 RemoteIPPrefix: d.Get("remote_ip_prefix").(string), 117 TenantID: d.Get("tenant_id").(string), 118 } 119 120 log.Printf("[DEBUG] Create OpenStack Neutron security group: %#v", opts) 121 122 security_group_rule, err := rules.Create(networkingClient, opts).Extract() 123 if err != nil { 124 return err 125 } 126 127 log.Printf("[DEBUG] OpenStack Neutron Security Group Rule created: %#v", security_group_rule) 128 129 d.SetId(security_group_rule.ID) 130 131 return resourceNetworkingSecGroupRuleV2Read(d, meta) 132 } 133 134 func resourceNetworkingSecGroupRuleV2Read(d *schema.ResourceData, meta interface{}) error { 135 log.Printf("[DEBUG] Retrieve information about security group rule: %s", d.Id()) 136 137 config := meta.(*Config) 138 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 139 if err != nil { 140 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 141 } 142 143 security_group_rule, err := rules.Get(networkingClient, d.Id()).Extract() 144 145 if err != nil { 146 return CheckDeleted(d, err, "OpenStack Security Group Rule") 147 } 148 149 d.Set("direction", security_group_rule.Direction) 150 d.Set("ethertype", security_group_rule.EtherType) 151 d.Set("protocol", security_group_rule.Protocol) 152 d.Set("port_range_min", security_group_rule.PortRangeMin) 153 d.Set("port_range_max", security_group_rule.PortRangeMax) 154 d.Set("remote_group_id", security_group_rule.RemoteGroupID) 155 d.Set("remote_ip_prefix", security_group_rule.RemoteIPPrefix) 156 d.Set("security_group_id", security_group_rule.SecGroupID) 157 d.Set("tenant_id", security_group_rule.TenantID) 158 return nil 159 } 160 161 func resourceNetworkingSecGroupRuleV2Delete(d *schema.ResourceData, meta interface{}) error { 162 log.Printf("[DEBUG] Destroy security group rule: %s", d.Id()) 163 164 config := meta.(*Config) 165 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 166 if err != nil { 167 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 168 } 169 170 stateConf := &resource.StateChangeConf{ 171 Pending: []string{"ACTIVE"}, 172 Target: []string{"DELETED"}, 173 Refresh: waitForSecGroupRuleDelete(networkingClient, d.Id()), 174 Timeout: 2 * time.Minute, 175 Delay: 5 * time.Second, 176 MinTimeout: 3 * time.Second, 177 } 178 179 _, err = stateConf.WaitForState() 180 if err != nil { 181 return fmt.Errorf("Error deleting OpenStack Neutron Security Group Rule: %s", err) 182 } 183 184 d.SetId("") 185 return err 186 } 187 188 func waitForSecGroupRuleDelete(networkingClient *gophercloud.ServiceClient, secGroupRuleId string) resource.StateRefreshFunc { 189 return func() (interface{}, string, error) { 190 log.Printf("[DEBUG] Attempting to delete OpenStack Security Group Rule %s.\n", secGroupRuleId) 191 192 r, err := rules.Get(networkingClient, secGroupRuleId).Extract() 193 if err != nil { 194 errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError) 195 if !ok { 196 return r, "ACTIVE", err 197 } 198 if errCode.Actual == 404 { 199 log.Printf("[DEBUG] Successfully deleted OpenStack Neutron Security Group Rule %s", secGroupRuleId) 200 return r, "DELETED", nil 201 } 202 } 203 204 err = rules.Delete(networkingClient, secGroupRuleId).ExtractErr() 205 if err != nil { 206 errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError) 207 if !ok { 208 return r, "ACTIVE", err 209 } 210 if errCode.Actual == 404 { 211 log.Printf("[DEBUG] Successfully deleted OpenStack Neutron Security Group Rule %s", secGroupRuleId) 212 return r, "DELETED", nil 213 } 214 } 215 216 log.Printf("[DEBUG] OpenStack Neutron Security Group Rule %s still active.\n", secGroupRuleId) 217 return r, "ACTIVE", nil 218 } 219 }