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