github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/builtin/providers/vcd/resource_vcd_firewall_rules.go (about) 1 package vcd 2 3 import ( 4 "fmt" 5 "github.com/hashicorp/terraform/helper/schema" 6 types "github.com/hmrc/vmware-govcd/types/v56" 7 "log" 8 "strings" 9 ) 10 11 func resourceVcdFirewallRules() *schema.Resource { 12 return &schema.Resource{ 13 Create: resourceVcdFirewallRulesCreate, 14 Delete: resourceFirewallRulesDelete, 15 Read: resourceFirewallRulesRead, 16 17 Schema: map[string]*schema.Schema{ 18 "edge_gateway": &schema.Schema{ 19 Type: schema.TypeString, 20 Required: true, 21 ForceNew: true, 22 }, 23 24 "default_action": &schema.Schema{ 25 Type: schema.TypeString, 26 Required: true, 27 ForceNew: true, 28 }, 29 30 "rule": &schema.Schema{ 31 Type: schema.TypeList, 32 Optional: true, 33 ForceNew: true, 34 Elem: &schema.Resource{ 35 Schema: map[string]*schema.Schema{ 36 "id": &schema.Schema{ 37 Type: schema.TypeString, 38 Optional: true, 39 Computed: true, 40 }, 41 42 "description": &schema.Schema{ 43 Type: schema.TypeString, 44 Required: true, 45 }, 46 47 "policy": &schema.Schema{ 48 Type: schema.TypeString, 49 Required: true, 50 }, 51 52 "protocol": &schema.Schema{ 53 Type: schema.TypeString, 54 Required: true, 55 }, 56 57 "destination_port": &schema.Schema{ 58 Type: schema.TypeString, 59 Required: true, 60 }, 61 62 "destination_ip": &schema.Schema{ 63 Type: schema.TypeString, 64 Required: true, 65 }, 66 67 "source_port": &schema.Schema{ 68 Type: schema.TypeString, 69 Required: true, 70 }, 71 72 "source_ip": &schema.Schema{ 73 Type: schema.TypeString, 74 Required: true, 75 }, 76 }, 77 }, 78 }, 79 }, 80 } 81 } 82 83 func resourceVcdFirewallRulesCreate(d *schema.ResourceData, meta interface{}) error { 84 vcdClient := meta.(*VCDClient) 85 vcdClient.Mutex.Lock() 86 defer vcdClient.Mutex.Unlock() 87 88 edgeGateway, err := vcdClient.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string)) 89 if err != nil { 90 return fmt.Errorf("Unable to find edge gateway: %s", err) 91 } 92 93 err = retryCall(vcdClient.MaxRetryTimeout, func() error { 94 edgeGateway.Refresh() 95 firewallRules, _ := expandFirewallRules(d, edgeGateway.EdgeGateway) 96 task, err := edgeGateway.CreateFirewallRules(d.Get("default_action").(string), firewallRules) 97 if err != nil { 98 log.Printf("[INFO] Error setting firewall rules: %s", err) 99 return fmt.Errorf("Error setting firewall rules: %#v", err) 100 } 101 102 return task.WaitTaskCompletion() 103 }) 104 if err != nil { 105 return fmt.Errorf("Error completing tasks: %#v", err) 106 } 107 108 d.SetId(d.Get("edge_gateway").(string)) 109 110 return resourceFirewallRulesRead(d, meta) 111 } 112 113 func resourceFirewallRulesDelete(d *schema.ResourceData, meta interface{}) error { 114 vcdClient := meta.(*VCDClient) 115 vcdClient.Mutex.Lock() 116 defer vcdClient.Mutex.Unlock() 117 118 edgeGateway, err := vcdClient.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string)) 119 120 firewallRules := deleteFirewallRules(d, edgeGateway.EdgeGateway) 121 defaultAction := edgeGateway.EdgeGateway.Configuration.EdgeGatewayServiceConfiguration.FirewallService.DefaultAction 122 task, err := edgeGateway.CreateFirewallRules(defaultAction, firewallRules) 123 if err != nil { 124 return fmt.Errorf("Error deleting firewall rules: %#v", err) 125 } 126 127 err = task.WaitTaskCompletion() 128 if err != nil { 129 return fmt.Errorf("Error completing tasks: %#v", err) 130 } 131 132 return nil 133 } 134 135 func resourceFirewallRulesRead(d *schema.ResourceData, meta interface{}) error { 136 vcdClient := meta.(*VCDClient) 137 138 edgeGateway, err := vcdClient.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string)) 139 if err != nil { 140 return fmt.Errorf("Error finding edge gateway: %#v", err) 141 } 142 ruleList := d.Get("rule").([]interface{}) 143 firewallRules := *edgeGateway.EdgeGateway.Configuration.EdgeGatewayServiceConfiguration.FirewallService 144 rulesCount := d.Get("rule.#").(int) 145 for i := 0; i < rulesCount; i++ { 146 prefix := fmt.Sprintf("rule.%d", i) 147 if d.Get(prefix+".id").(string) == "" { 148 log.Printf("[INFO] Rule %d has no id. Searching...", i) 149 ruleid, err := matchFirewallRule(d, prefix, firewallRules.FirewallRule) 150 if err == nil { 151 currentRule := ruleList[i].(map[string]interface{}) 152 currentRule["id"] = ruleid 153 ruleList[i] = currentRule 154 } 155 } 156 } 157 d.Set("rule", ruleList) 158 d.Set("default_action", firewallRules.DefaultAction) 159 160 return nil 161 } 162 163 func deleteFirewallRules(d *schema.ResourceData, gateway *types.EdgeGateway) []*types.FirewallRule { 164 firewallRules := gateway.Configuration.EdgeGatewayServiceConfiguration.FirewallService.FirewallRule 165 rulesCount := d.Get("rule.#").(int) 166 fwrules := make([]*types.FirewallRule, 0, len(firewallRules)-rulesCount) 167 168 for _, f := range firewallRules { 169 keep := true 170 for i := 0; i < rulesCount; i++ { 171 if d.Get(fmt.Sprintf("rule.%d.id", i)).(string) != f.ID { 172 continue 173 } 174 keep = false 175 } 176 if keep { 177 fwrules = append(fwrules, f) 178 } 179 } 180 return fwrules 181 } 182 183 func matchFirewallRule(d *schema.ResourceData, prefix string, rules []*types.FirewallRule) (string, error) { 184 185 for _, m := range rules { 186 if d.Get(prefix+".description").(string) == m.Description && 187 d.Get(prefix+".policy").(string) == m.Policy && 188 strings.ToLower(d.Get(prefix+".protocol").(string)) == getProtocol(*m.Protocols) && 189 strings.ToLower(d.Get(prefix+".destination_port").(string)) == getPortString(m.Port) && 190 strings.ToLower(d.Get(prefix+".destination_ip").(string)) == strings.ToLower(m.DestinationIP) && 191 strings.ToLower(d.Get(prefix+".source_port").(string)) == getPortString(m.SourcePort) && 192 strings.ToLower(d.Get(prefix+".source_ip").(string)) == strings.ToLower(m.SourceIP) { 193 return m.ID, nil 194 } 195 } 196 return "", fmt.Errorf("Unable to find rule") 197 }