github.com/pmcatominey/terraform@v0.7.0-rc2.0.20160708105029-1401a52a5cc5/builtin/providers/cloudstack/resource_cloudstack_loadbalancer_rule.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 "ip_address_id": &schema.Schema{ 32 Type: schema.TypeString, 33 Required: true, 34 ForceNew: true, 35 }, 36 37 "network_id": &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 "member_ids": &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 if networkid, ok := d.GetOk("network_id"); ok { 93 // Set the network id 94 p.SetNetworkid(networkid.(string)) 95 } 96 97 // Set the ipaddress id 98 p.SetPublicipid(d.Get("ip_address_id").(string)) 99 100 // Create the load balancer rule 101 r, err := cs.LoadBalancer.CreateLoadBalancerRule(p) 102 if err != nil { 103 return err 104 } 105 106 // Set the load balancer rule ID and set partials 107 d.SetId(r.Id) 108 d.SetPartial("name") 109 d.SetPartial("description") 110 d.SetPartial("ip_address_id") 111 d.SetPartial("network_id") 112 d.SetPartial("algorithm") 113 d.SetPartial("private_port") 114 d.SetPartial("public_port") 115 116 // Create a new parameter struct 117 ap := cs.LoadBalancer.NewAssignToLoadBalancerRuleParams(r.Id) 118 119 var mbs []string 120 for _, id := range d.Get("member_ids").([]interface{}) { 121 mbs = append(mbs, id.(string)) 122 } 123 124 ap.SetVirtualmachineids(mbs) 125 126 _, err = cs.LoadBalancer.AssignToLoadBalancerRule(ap) 127 if err != nil { 128 return err 129 } 130 131 d.SetPartial("member_ids") 132 d.Partial(false) 133 134 return resourceCloudStackLoadBalancerRuleRead(d, meta) 135 } 136 137 func resourceCloudStackLoadBalancerRuleRead(d *schema.ResourceData, meta interface{}) error { 138 cs := meta.(*cloudstack.CloudStackClient) 139 140 // Get the load balancer details 141 lb, count, err := cs.LoadBalancer.GetLoadBalancerRuleByID(d.Id()) 142 if err != nil { 143 if count == 0 { 144 log.Printf("[DEBUG] Load balancer rule %s does no longer exist", d.Get("name").(string)) 145 d.SetId("") 146 return nil 147 } 148 149 return err 150 } 151 152 d.Set("algorithm", lb.Algorithm) 153 d.Set("public_port", lb.Publicport) 154 d.Set("private_port", lb.Privateport) 155 d.Set("ip_address_id", lb.Publicipid) 156 157 // Only set network if user specified it to avoid spurious diffs 158 if _, ok := d.GetOk("network_id"); ok { 159 d.Set("network_id", lb.Networkid) 160 } 161 162 return nil 163 } 164 165 func resourceCloudStackLoadBalancerRuleUpdate(d *schema.ResourceData, meta interface{}) error { 166 cs := meta.(*cloudstack.CloudStackClient) 167 168 if d.HasChange("name") || d.HasChange("description") || d.HasChange("algorithm") { 169 name := d.Get("name").(string) 170 171 // Create new parameter struct 172 p := cs.LoadBalancer.NewUpdateLoadBalancerRuleParams(d.Id()) 173 174 if d.HasChange("name") { 175 log.Printf("[DEBUG] Name has changed for load balancer rule %s, starting update", name) 176 177 p.SetName(name) 178 } 179 180 if d.HasChange("description") { 181 log.Printf( 182 "[DEBUG] Description has changed for load balancer rule %s, starting update", name) 183 184 p.SetDescription(d.Get("description").(string)) 185 } 186 187 if d.HasChange("algorithm") { 188 algorithm := d.Get("algorithm").(string) 189 190 log.Printf( 191 "[DEBUG] Algorithm has changed to %s for load balancer rule %s, starting update", 192 algorithm, 193 name, 194 ) 195 196 // Set the new Algorithm 197 p.SetAlgorithm(algorithm) 198 } 199 200 _, err := cs.LoadBalancer.UpdateLoadBalancerRule(p) 201 if err != nil { 202 return fmt.Errorf( 203 "Error updating load balancer rule %s", name) 204 } 205 } 206 return resourceCloudStackLoadBalancerRuleRead(d, meta) 207 } 208 209 func resourceCloudStackLoadBalancerRuleDelete(d *schema.ResourceData, meta interface{}) error { 210 cs := meta.(*cloudstack.CloudStackClient) 211 212 // Create a new parameter struct 213 p := cs.LoadBalancer.NewDeleteLoadBalancerRuleParams(d.Id()) 214 215 log.Printf("[INFO] Deleting load balancer rule: %s", d.Get("name").(string)) 216 if _, err := cs.LoadBalancer.DeleteLoadBalancerRule(p); err != nil { 217 // This is a very poor way to be told the ID does no longer exist :( 218 if !strings.Contains(err.Error(), fmt.Sprintf( 219 "Invalid parameter id value=%s due to incorrect long value format, "+ 220 "or entity does not exist", d.Id())) { 221 return err 222 } 223 } 224 225 return nil 226 }