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