github.com/anuaimi/terraform@v0.6.4-0.20150904235404-2bf9aec61da8/builtin/providers/azure/resource_azure_security_group_rule.go (about) 1 package azure 2 3 import ( 4 "fmt" 5 "log" 6 7 "github.com/Azure/azure-sdk-for-go/management" 8 netsecgroup "github.com/Azure/azure-sdk-for-go/management/networksecuritygroup" 9 "github.com/hashicorp/terraform/helper/schema" 10 ) 11 12 // resourceAzureSecurityGroupRule returns the *schema.Resource for 13 // a network security group rule on Azure. 14 func resourceAzureSecurityGroupRule() *schema.Resource { 15 return &schema.Resource{ 16 Create: resourceAzureSecurityGroupRuleCreate, 17 Read: resourceAzureSecurityGroupRuleRead, 18 Update: resourceAzureSecurityGroupRuleUpdate, 19 Delete: resourceAzureSecurityGroupRuleDelete, 20 21 Schema: map[string]*schema.Schema{ 22 "name": &schema.Schema{ 23 Type: schema.TypeString, 24 Required: true, 25 ForceNew: true, 26 Description: parameterDescriptions["name"], 27 }, 28 "security_group_names": &schema.Schema{ 29 Type: schema.TypeSet, 30 Required: true, 31 ForceNew: true, 32 Description: parameterDescriptions["netsecgroup_secgroup_names"], 33 Elem: &schema.Schema{ 34 Type: schema.TypeString, 35 }, 36 Set: schema.HashString, 37 }, 38 "type": &schema.Schema{ 39 Type: schema.TypeString, 40 Required: true, 41 Description: parameterDescriptions["netsecgroup_type"], 42 }, 43 "priority": &schema.Schema{ 44 Type: schema.TypeInt, 45 Required: true, 46 Description: parameterDescriptions["netsecgroup_priority"], 47 }, 48 "action": &schema.Schema{ 49 Type: schema.TypeString, 50 Required: true, 51 Description: parameterDescriptions["netsecgroup_action"], 52 }, 53 "source_address_prefix": &schema.Schema{ 54 Type: schema.TypeString, 55 Required: true, 56 Description: parameterDescriptions["netsecgroup_src_addr_prefix"], 57 }, 58 "source_port_range": &schema.Schema{ 59 Type: schema.TypeString, 60 Required: true, 61 Description: parameterDescriptions["netsecgroup_src_port_range"], 62 }, 63 "destination_address_prefix": &schema.Schema{ 64 Type: schema.TypeString, 65 Required: true, 66 Description: parameterDescriptions["netsecgroup_dest_addr_prefix"], 67 }, 68 "destination_port_range": &schema.Schema{ 69 Type: schema.TypeString, 70 Required: true, 71 Description: parameterDescriptions["netsecgroup_dest_port_range"], 72 }, 73 "protocol": &schema.Schema{ 74 Type: schema.TypeString, 75 Required: true, 76 Description: parameterDescriptions["netsecgroup_protocol"], 77 }, 78 }, 79 } 80 } 81 82 // resourceAzureSecurityGroupRuleCreate does all the necessary API calls to 83 // create a new network security group rule on Azure. 84 func resourceAzureSecurityGroupRuleCreate(d *schema.ResourceData, meta interface{}) error { 85 azureClient := meta.(*Client) 86 mgmtClient := azureClient.mgmtClient 87 secGroupClient := azureClient.secGroupClient 88 89 // create and configure the RuleResponse: 90 name := d.Get("name").(string) 91 rule := netsecgroup.RuleRequest{ 92 Name: name, 93 Type: netsecgroup.RuleType(d.Get("type").(string)), 94 Priority: d.Get("priority").(int), 95 Action: netsecgroup.RuleAction(d.Get("action").(string)), 96 SourceAddressPrefix: d.Get("source_address_prefix").(string), 97 SourcePortRange: d.Get("source_port_range").(string), 98 DestinationAddressPrefix: d.Get("destination_address_prefix").(string), 99 DestinationPortRange: d.Get("destination_port_range").(string), 100 Protocol: netsecgroup.RuleProtocol(d.Get("protocol").(string)), 101 } 102 103 // apply the rule to all the necessary network security groups: 104 secGroups := d.Get("security_group_names").(*schema.Set).List() 105 for _, sg := range secGroups { 106 secGroup := sg.(string) 107 108 // send the create request to Azure: 109 log.Printf("[INFO] Sending Azure security group rule addition request for security group %q.", secGroup) 110 reqID, err := secGroupClient.SetNetworkSecurityGroupRule( 111 secGroup, 112 rule, 113 ) 114 if err != nil { 115 return fmt.Errorf("Error sending Azure network security group rule creation request for security group %q: %s", secGroup, err) 116 } 117 err = mgmtClient.WaitForOperation(reqID, nil) 118 if err != nil { 119 return fmt.Errorf("Error creating Azure network security group rule for security group %q: %s", secGroup, err) 120 } 121 } 122 123 d.SetId(name) 124 return nil 125 } 126 127 // resourceAzureSecurityGroupRuleRead does all the necessary API calls to 128 // read the state of a network security group ruke off Azure. 129 func resourceAzureSecurityGroupRuleRead(d *schema.ResourceData, meta interface{}) error { 130 azureClient := meta.(*Client) 131 secGroupClient := azureClient.secGroupClient 132 133 var found bool 134 name := d.Get("name").(string) 135 136 secGroups := d.Get("security_group_names").(*schema.Set).List() 137 remaining := schema.NewSet(schema.HashString, nil) 138 139 // for each of our security groups; check for our rule: 140 for _, sg := range secGroups { 141 secGroupName := sg.(string) 142 143 // get info on the network security group and check its rules for this one: 144 log.Printf("[INFO] Sending Azure network security group rule query for security group %s.", secGroupName) 145 secgroup, err := secGroupClient.GetNetworkSecurityGroup(secGroupName) 146 if err != nil { 147 if !management.IsResourceNotFoundError(err) { 148 return fmt.Errorf("Error issuing network security group rules query for security group %q: %s", secGroupName, err) 149 } else { 150 // it meants that the network security group this rule belonged to has 151 // been deleted; so we skip this iteration: 152 continue 153 } 154 } 155 156 // find our security rule: 157 for _, rule := range secgroup.Rules { 158 if rule.Name == name { 159 // note the fact that this rule still apllies to this security group: 160 found = true 161 remaining.Add(secGroupName) 162 163 break 164 } 165 } 166 } 167 168 // check to see if there is any security group still having this rule: 169 if !found { 170 d.SetId("") 171 return nil 172 } 173 174 // now; we must update the set of security groups still having this rule: 175 d.Set("security_group_names", remaining) 176 return nil 177 } 178 179 // resourceAzureSecurityGroupRuleUpdate does all the necessary API calls to 180 // update the state of a network security group rule off Azure. 181 func resourceAzureSecurityGroupRuleUpdate(d *schema.ResourceData, meta interface{}) error { 182 azureClient := meta.(*Client) 183 mgmtClient := azureClient.mgmtClient 184 secGroupClient := azureClient.secGroupClient 185 186 var found bool 187 name := d.Get("name").(string) 188 newRule := netsecgroup.RuleRequest{ 189 Name: d.Get("name").(string), 190 Type: netsecgroup.RuleType(d.Get("type").(string)), 191 Priority: d.Get("priority").(int), 192 Action: netsecgroup.RuleAction(d.Get("action").(string)), 193 SourceAddressPrefix: d.Get("source_address_prefix").(string), 194 SourcePortRange: d.Get("source_port_range").(string), 195 DestinationAddressPrefix: d.Get("destination_address_prefix").(string), 196 DestinationPortRange: d.Get("destination_port_range").(string), 197 Protocol: netsecgroup.RuleProtocol(d.Get("protocol").(string)), 198 } 199 200 // iterate over all the security groups that should have this rule and 201 // update it per security group: 202 remaining := schema.NewSet(schema.HashString, nil) 203 secGroupNames := d.Get("security_group_names").(*schema.Set).List() 204 for _, sg := range secGroupNames { 205 secGroupName := sg.(string) 206 207 // get info on the network security group and check its rules for this one: 208 log.Printf("[INFO] Sending Azure network security group rule query for security group %q.", secGroupName) 209 secgroup, err := secGroupClient.GetNetworkSecurityGroup(secGroupName) 210 if err != nil { 211 if !management.IsResourceNotFoundError(err) { 212 return fmt.Errorf("Error issuing network security group rules query: %s", err) 213 } else { 214 // it meants that the network security group this rule belonged to has 215 // been deleted; so we skip this iteration: 216 continue 217 } 218 } 219 220 // try and find our security group rule: 221 for _, rule := range secgroup.Rules { 222 if rule.Name == name { 223 // note the fact that this rule still applies to this security group: 224 found = true 225 remaining.Add(secGroupName) 226 227 // and go ahead and update it: 228 log.Printf("[INFO] Sending Azure network security group rule update request for security group %q.", secGroupName) 229 reqID, err := secGroupClient.SetNetworkSecurityGroupRule( 230 secGroupName, 231 newRule, 232 ) 233 if err != nil { 234 return fmt.Errorf("Error sending Azure network security group rule update request for security group %q: %s", secGroupName, err) 235 } 236 err = mgmtClient.WaitForOperation(reqID, nil) 237 if err != nil { 238 return fmt.Errorf("Error updating Azure network security group rule for security group %q: %s", secGroupName, err) 239 } 240 241 break 242 } 243 } 244 } 245 246 // check to see if there is any security group still having this rule: 247 if !found { 248 d.SetId("") 249 return nil 250 } 251 252 // here; we must update the set of security groups still having this rule: 253 d.Set("security_group_names", remaining) 254 255 return nil 256 } 257 258 // resourceAzureSecurityGroupRuleDelete does all the necessary API calls to 259 // delete a network security group rule off Azure. 260 func resourceAzureSecurityGroupRuleDelete(d *schema.ResourceData, meta interface{}) error { 261 azureClient := meta.(*Client) 262 mgmtClient := azureClient.mgmtClient 263 secGroupClient := azureClient.secGroupClient 264 265 name := d.Get("name").(string) 266 secGroupNames := d.Get("security_group_names").(*schema.Set).List() 267 for _, sg := range secGroupNames { 268 secGroupName := sg.(string) 269 270 // get info on the network security group and search for our rule: 271 log.Printf("[INFO] Sending network security group rule query for security group %q.", secGroupName) 272 secgroup, err := secGroupClient.GetNetworkSecurityGroup(secGroupName) 273 if err != nil { 274 if management.IsResourceNotFoundError(err) { 275 // it means that this network security group this rule belonged to has 276 // been deleted; so we need not do anything more here: 277 continue 278 } else { 279 return fmt.Errorf("Error issuing Azure network security group rules query for security group %q: %s", secGroupName, err) 280 } 281 } 282 283 // check if the rule has been deleted in the meantime: 284 for _, rule := range secgroup.Rules { 285 if rule.Name == name { 286 // if not; we shall issue the delete: 287 reqID, err := secGroupClient.DeleteNetworkSecurityGroupRule(secGroupName, name) 288 if err != nil { 289 return fmt.Errorf("Error sending network security group rule delete request to Azure: %s", err) 290 } 291 err = mgmtClient.WaitForOperation(reqID, nil) 292 if err != nil { 293 return fmt.Errorf("Error deleting network security group rule off Azure: %s", err) 294 } 295 } 296 break 297 } 298 } 299 300 return nil 301 }