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