github.com/andresvia/terraform@v0.6.15-0.20160412045437-d51c75946785/builtin/providers/cloudstack/resource_cloudstack_loadbalancer_rule.go (about) 1 package cloudstack 2 3 import ( 4 "errors" 5 "fmt" 6 "log" 7 "strings" 8 9 "github.com/hashicorp/terraform/helper/schema" 10 "github.com/xanzy/go-cloudstack/cloudstack" 11 ) 12 13 func resourceCloudStackLoadBalancerRule() *schema.Resource { 14 return &schema.Resource{ 15 Create: resourceCloudStackLoadBalancerRuleCreate, 16 Read: resourceCloudStackLoadBalancerRuleRead, 17 Update: resourceCloudStackLoadBalancerRuleUpdate, 18 Delete: resourceCloudStackLoadBalancerRuleDelete, 19 20 Schema: map[string]*schema.Schema{ 21 "name": &schema.Schema{ 22 Type: schema.TypeString, 23 Required: true, 24 }, 25 26 "description": &schema.Schema{ 27 Type: schema.TypeString, 28 Optional: true, 29 Computed: true, 30 }, 31 32 "ip_address": &schema.Schema{ 33 Type: schema.TypeString, 34 Optional: true, 35 ForceNew: true, 36 ConflictsWith: []string{"ipaddress"}, 37 }, 38 39 "ipaddress": &schema.Schema{ 40 Type: schema.TypeString, 41 Optional: true, 42 ForceNew: true, 43 Deprecated: "Please use the `ip_address` field instead", 44 ConflictsWith: []string{"ip_address"}, 45 }, 46 47 "network": &schema.Schema{ 48 Type: schema.TypeString, 49 Optional: true, 50 ForceNew: true, 51 }, 52 53 "algorithm": &schema.Schema{ 54 Type: schema.TypeString, 55 Required: true, 56 }, 57 58 "private_port": &schema.Schema{ 59 Type: schema.TypeInt, 60 Required: true, 61 ForceNew: true, 62 }, 63 64 "public_port": &schema.Schema{ 65 Type: schema.TypeInt, 66 Required: true, 67 ForceNew: true, 68 }, 69 70 "members": &schema.Schema{ 71 Type: schema.TypeList, 72 Required: true, 73 ForceNew: true, 74 Elem: &schema.Schema{Type: schema.TypeString}, 75 }, 76 }, 77 } 78 } 79 80 func resourceCloudStackLoadBalancerRuleCreate(d *schema.ResourceData, meta interface{}) error { 81 cs := meta.(*cloudstack.CloudStackClient) 82 d.Partial(true) 83 84 // Create a new parameter struct 85 p := cs.LoadBalancer.NewCreateLoadBalancerRuleParams( 86 d.Get("algorithm").(string), 87 d.Get("name").(string), 88 d.Get("private_port").(int), 89 d.Get("public_port").(int), 90 ) 91 92 // Don't autocreate a firewall rule, use a resource if needed 93 p.SetOpenfirewall(false) 94 95 // Set the description 96 if description, ok := d.GetOk("description"); ok { 97 p.SetDescription(description.(string)) 98 } else { 99 p.SetDescription(d.Get("name").(string)) 100 } 101 102 // Retrieve the network and the ID 103 if network, ok := d.GetOk("network"); ok { 104 networkid, e := retrieveID(cs, "network", network.(string)) 105 if e != nil { 106 return e.Error() 107 } 108 109 // Set the default network ID 110 p.SetNetworkid(networkid) 111 } 112 113 ipaddress, ok := d.GetOk("ip_address") 114 if !ok { 115 ipaddress, ok = d.GetOk("ipaddress") 116 } 117 if !ok { 118 return errors.New("Either `ip_address` or [deprecated] `ipaddress` must be provided.") 119 } 120 121 // Retrieve the ipaddress ID 122 ipaddressid, e := retrieveID(cs, "ip_address", ipaddress.(string)) 123 if e != nil { 124 return e.Error() 125 } 126 p.SetPublicipid(ipaddressid) 127 128 // Create the load balancer rule 129 r, err := cs.LoadBalancer.CreateLoadBalancerRule(p) 130 if err != nil { 131 return err 132 } 133 134 // Set the load balancer rule ID and set partials 135 d.SetId(r.Id) 136 d.SetPartial("name") 137 d.SetPartial("description") 138 d.SetPartial("ip_address") 139 d.SetPartial("network") 140 d.SetPartial("algorithm") 141 d.SetPartial("private_port") 142 d.SetPartial("public_port") 143 144 // Create a new parameter struct 145 ap := cs.LoadBalancer.NewAssignToLoadBalancerRuleParams(r.Id) 146 147 var mbs []string 148 for _, id := range d.Get("members").([]interface{}) { 149 mbs = append(mbs, id.(string)) 150 } 151 152 ap.SetVirtualmachineids(mbs) 153 154 _, err = cs.LoadBalancer.AssignToLoadBalancerRule(ap) 155 if err != nil { 156 return err 157 } 158 159 d.SetPartial("members") 160 161 d.Partial(false) 162 return resourceCloudStackLoadBalancerRuleRead(d, meta) 163 } 164 165 func resourceCloudStackLoadBalancerRuleRead(d *schema.ResourceData, meta interface{}) error { 166 cs := meta.(*cloudstack.CloudStackClient) 167 168 // Get the load balancer details 169 lb, count, err := cs.LoadBalancer.GetLoadBalancerRuleByID(d.Id()) 170 if err != nil { 171 if count == 0 { 172 log.Printf("[DEBUG] Load balancer rule %s does no longer exist", d.Get("name").(string)) 173 d.SetId("") 174 return nil 175 } 176 177 return err 178 } 179 180 d.Set("algorithm", lb.Algorithm) 181 d.Set("public_port", lb.Publicport) 182 d.Set("private_port", lb.Privateport) 183 184 setValueOrID(d, "ip_address", lb.Publicip, lb.Publicipid) 185 186 // Only set network if user specified it to avoid spurious diffs 187 if _, ok := d.GetOk("network"); ok { 188 network, _, err := cs.Network.GetNetworkByID(lb.Networkid) 189 if err != nil { 190 return err 191 } 192 setValueOrID(d, "network", network.Name, lb.Networkid) 193 } 194 195 return nil 196 } 197 198 func resourceCloudStackLoadBalancerRuleUpdate(d *schema.ResourceData, meta interface{}) error { 199 cs := meta.(*cloudstack.CloudStackClient) 200 201 if d.HasChange("name") || d.HasChange("description") || d.HasChange("algorithm") { 202 name := d.Get("name").(string) 203 204 // Create new parameter struct 205 p := cs.LoadBalancer.NewUpdateLoadBalancerRuleParams(d.Id()) 206 207 if d.HasChange("name") { 208 log.Printf("[DEBUG] Name has changed for load balancer rule %s, starting update", name) 209 210 p.SetName(name) 211 } 212 213 if d.HasChange("description") { 214 log.Printf( 215 "[DEBUG] Description has changed for load balancer rule %s, starting update", name) 216 217 p.SetDescription(d.Get("description").(string)) 218 } 219 220 if d.HasChange("algorithm") { 221 algorithm := d.Get("algorithm").(string) 222 223 log.Printf( 224 "[DEBUG] Algorithm has changed to %s for load balancer rule %s, starting update", 225 algorithm, 226 name, 227 ) 228 229 // Set the new Algorithm 230 p.SetAlgorithm(algorithm) 231 } 232 233 _, err := cs.LoadBalancer.UpdateLoadBalancerRule(p) 234 if err != nil { 235 return fmt.Errorf( 236 "Error updating load balancer rule %s", name) 237 } 238 } 239 return resourceCloudStackLoadBalancerRuleRead(d, meta) 240 } 241 242 func resourceCloudStackLoadBalancerRuleDelete(d *schema.ResourceData, meta interface{}) error { 243 cs := meta.(*cloudstack.CloudStackClient) 244 245 // Create a new parameter struct 246 p := cs.LoadBalancer.NewDeleteLoadBalancerRuleParams(d.Id()) 247 248 log.Printf("[INFO] Deleting load balancer rule: %s", d.Get("name").(string)) 249 if _, err := cs.LoadBalancer.DeleteLoadBalancerRule(p); err != nil { 250 // This is a very poor way to be told the ID does no longer exist :( 251 if !strings.Contains(err.Error(), fmt.Sprintf( 252 "Invalid parameter id value=%s due to incorrect long value format, "+ 253 "or entity does not exist", d.Id())) { 254 return err 255 } 256 } 257 258 return nil 259 }