github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/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 "project": &schema.Schema{ 68 Type: schema.TypeString, 69 Optional: true, 70 Computed: true, 71 ForceNew: true, 72 }, 73 }, 74 } 75 } 76 77 func resourceCloudStackLoadBalancerRuleCreate(d *schema.ResourceData, meta interface{}) error { 78 cs := meta.(*cloudstack.CloudStackClient) 79 d.Partial(true) 80 81 // Create a new parameter struct 82 p := cs.LoadBalancer.NewCreateLoadBalancerRuleParams( 83 d.Get("algorithm").(string), 84 d.Get("name").(string), 85 d.Get("private_port").(int), 86 d.Get("public_port").(int), 87 ) 88 89 // Don't autocreate a firewall rule, use a resource if needed 90 p.SetOpenfirewall(false) 91 92 // Set the description 93 if description, ok := d.GetOk("description"); ok { 94 p.SetDescription(description.(string)) 95 } else { 96 p.SetDescription(d.Get("name").(string)) 97 } 98 99 if networkid, ok := d.GetOk("network_id"); ok { 100 // Set the network id 101 p.SetNetworkid(networkid.(string)) 102 } 103 104 // Set the ipaddress id 105 p.SetPublicipid(d.Get("ip_address_id").(string)) 106 107 // Create the load balancer rule 108 r, err := cs.LoadBalancer.CreateLoadBalancerRule(p) 109 if err != nil { 110 return err 111 } 112 113 // Set the load balancer rule ID and set partials 114 d.SetId(r.Id) 115 d.SetPartial("name") 116 d.SetPartial("description") 117 d.SetPartial("ip_address_id") 118 d.SetPartial("network_id") 119 d.SetPartial("algorithm") 120 d.SetPartial("private_port") 121 d.SetPartial("public_port") 122 123 // Create a new parameter struct 124 ap := cs.LoadBalancer.NewAssignToLoadBalancerRuleParams(r.Id) 125 126 var mbs []string 127 for _, id := range d.Get("member_ids").([]interface{}) { 128 mbs = append(mbs, id.(string)) 129 } 130 131 ap.SetVirtualmachineids(mbs) 132 133 _, err = cs.LoadBalancer.AssignToLoadBalancerRule(ap) 134 if err != nil { 135 return err 136 } 137 138 d.SetPartial("member_ids") 139 d.Partial(false) 140 141 return resourceCloudStackLoadBalancerRuleRead(d, meta) 142 } 143 144 func resourceCloudStackLoadBalancerRuleRead(d *schema.ResourceData, meta interface{}) error { 145 cs := meta.(*cloudstack.CloudStackClient) 146 147 // Get the load balancer details 148 lb, count, err := cs.LoadBalancer.GetLoadBalancerRuleByID( 149 d.Id(), 150 cloudstack.WithProject(d.Get("project").(string)), 151 ) 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 d.Set("ip_address_id", lb.Publicipid) 166 167 // Only set network if user specified it to avoid spurious diffs 168 if _, ok := d.GetOk("network_id"); ok { 169 d.Set("network_id", lb.Networkid) 170 } 171 172 setValueOrID(d, "project", lb.Project, lb.Projectid) 173 174 return nil 175 } 176 177 func resourceCloudStackLoadBalancerRuleUpdate(d *schema.ResourceData, meta interface{}) error { 178 cs := meta.(*cloudstack.CloudStackClient) 179 180 if d.HasChange("name") || d.HasChange("description") || d.HasChange("algorithm") { 181 name := d.Get("name").(string) 182 183 // Create new parameter struct 184 p := cs.LoadBalancer.NewUpdateLoadBalancerRuleParams(d.Id()) 185 186 if d.HasChange("name") { 187 log.Printf("[DEBUG] Name has changed for load balancer rule %s, starting update", name) 188 189 p.SetName(name) 190 } 191 192 if d.HasChange("description") { 193 log.Printf( 194 "[DEBUG] Description has changed for load balancer rule %s, starting update", name) 195 196 p.SetDescription(d.Get("description").(string)) 197 } 198 199 if d.HasChange("algorithm") { 200 algorithm := d.Get("algorithm").(string) 201 202 log.Printf( 203 "[DEBUG] Algorithm has changed to %s for load balancer rule %s, starting update", 204 algorithm, 205 name, 206 ) 207 208 // Set the new Algorithm 209 p.SetAlgorithm(algorithm) 210 } 211 212 _, err := cs.LoadBalancer.UpdateLoadBalancerRule(p) 213 if err != nil { 214 return fmt.Errorf( 215 "Error updating load balancer rule %s", name) 216 } 217 } 218 return resourceCloudStackLoadBalancerRuleRead(d, meta) 219 } 220 221 func resourceCloudStackLoadBalancerRuleDelete(d *schema.ResourceData, meta interface{}) error { 222 cs := meta.(*cloudstack.CloudStackClient) 223 224 // Create a new parameter struct 225 p := cs.LoadBalancer.NewDeleteLoadBalancerRuleParams(d.Id()) 226 227 log.Printf("[INFO] Deleting load balancer rule: %s", d.Get("name").(string)) 228 if _, err := cs.LoadBalancer.DeleteLoadBalancerRule(p); err != nil { 229 // This is a very poor way to be told the ID does no longer exist :( 230 if !strings.Contains(err.Error(), fmt.Sprintf( 231 "Invalid parameter id value=%s due to incorrect long value format, "+ 232 "or entity does not exist", d.Id())) { 233 return err 234 } 235 } 236 237 return nil 238 }