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