Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Differential updates for outscale_load_balancer_vms #55

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 119 additions & 19 deletions outscale/resource_outscale_load_balancer_vms.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ func resourceOutscaleOAPILBUAttachment() *schema.Resource {
return &schema.Resource{
Create: resourceOutscaleOAPILBUAttachmentCreate,
Read: resourceOutscaleOAPILBUAttachmentRead,
Update: resourceOutscaleOAPILBUAttachmentUpdate,
Delete: resourceOutscaleOAPILBUAttachmentDelete,

Schema: map[string]*schema.Schema{
Expand All @@ -27,8 +28,7 @@ func resourceOutscaleOAPILBUAttachment() *schema.Resource {
},

"backend_vm_ids": {
Type: schema.TypeList,
ForceNew: true,
Type: schema.TypeSet,
Required: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
Expand All @@ -50,9 +50,8 @@ func resourceOutscaleOAPILBUAttachmentCreate(d *schema.ResourceData, meta interf
return fmt.Errorf("please provide the required attributes load_balancer_name and backend_vm_id")
}

m := i.([]interface{})
a := make([]string, len(m))
for k, v := range m {
a := make([]string, i.(*schema.Set).Len())
for k, v := range i.(*schema.Set).List() {
a[k] = v.(string)
}

Expand Down Expand Up @@ -89,40 +88,141 @@ func resourceOutscaleOAPILBUAttachmentCreate(d *schema.ResourceData, meta interf

func resourceOutscaleOAPILBUAttachmentRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*OutscaleClient).OSCAPI
found := false
e := d.Get("load_balancer_name").(string)
lb, _, err := readResourceLb(conn, e)
expected := d.Get("backend_vm_ids").([]interface{})
expected := d.Get("backend_vm_ids").(*schema.Set)

if err != nil {
return err
}

all_backends := schema.Set{F: expected.F}
for _, v := range *lb.BackendVmIds {
for k1 := range expected {
sid := expected[k1].(string)
if sid == v {
d.Set("backend_vm_ids", expected)
found = true
}
}
all_backends.Add(v)
}

if !found {
log.Printf("[WARN] i %s not found in lbu attachments", expected)
managed := all_backends.Intersection(expected)
d.Set("backend_vm_ids", managed)

if managed.Len() == 0 {
log.Printf("[WARN] not expected attachments found in LBU %e", e)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure %e can be used to print out string variable value

log.Printf("[WARN] lbu current attachments are %#v", all_backends)
log.Printf("[WARN] we would manage only these attachments %#v", expected)
log.Printf("[WARN] no managed attachments are present.")
d.SetId("")
}

return nil
}

func resourceOutscaleOAPILBUDiffBackendVmIds(oldBackends *schema.Set, newBackends *schema.Set) (*schema.Set, *schema.Set) {

// Strange, but if you insist...
if newBackends == nil {
if oldBackends != nil {
return nil, oldBackends
}
return nil, nil
}
// Start by supposing that we create everything and remove nothing.
create := schema.CopySet(newBackends)
remove := schema.NewSet(create.F, []interface{}{})

for _, backend := range oldBackends.List() {
// When old set contains backends not in the new set,
// they are to be removed.
if !create.Contains(backend) {
remove.Add(backend)
} else {
create.Remove(backend)
}
}

return create, remove
}

func resourceOutscaleOAPILBUAttachmentUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*OutscaleClient).OSCAPI
lbu_name := d.Get("load_balancer_name").(string)
var err error

if !d.HasChange("backend_vm_ids") {
return nil
}

oldBackends, newBackends := d.GetChange("backend_vm_ids")
create, remove := resourceOutscaleOAPILBUDiffBackendVmIds(oldBackends.(*schema.Set), newBackends.(*schema.Set))

if create != nil && create.Len() > 0 {
// Convert the Set to a string list
createStrings := make([]string, 0, create.Len())
for _, val := range create.List() {
createStrings = append(createStrings, val.(string))
}
// Make the Register request
err = resource.Retry(5*time.Minute, func() *resource.RetryError {
_, _, err = conn.LoadBalancerApi.
RegisterVmsInLoadBalancer(context.Background()).
RegisterVmsInLoadBalancerRequest(
oscgo.RegisterVmsInLoadBalancerRequest{
LoadBalancerName: lbu_name,
BackendVmIds: createStrings,
}).
Execute()
if err != nil {
if strings.Contains(fmt.Sprint(err), "Throttling") {
return resource.RetryableError(
fmt.Errorf("[WARN] Error, retrying: %s", err))
}
return resource.NonRetryableError(err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please use utils.CheckThrottling(err) function for Throttling checking ?

}
return nil
})
if err != nil {
return fmt.Errorf("Failure registering new backend_vm_ids with LBU: %s", err)
}
}
if remove != nil && remove.Len() > 0 {
// Convert the Set to a string list
removeStrings := make([]string, 0, remove.Len())
for _, val := range remove.List() {
removeStrings = append(removeStrings, val.(string))
}

// Make the Deregister request
err = resource.Retry(5*time.Minute, func() *resource.RetryError {
_, _, err := conn.LoadBalancerApi.
DeregisterVmsInLoadBalancer(context.Background()).
DeregisterVmsInLoadBalancerRequest(
oscgo.DeregisterVmsInLoadBalancerRequest{
LoadBalancerName: lbu_name,
BackendVmIds: removeStrings,
}).
Execute()
if err != nil {
if strings.Contains(fmt.Sprint(err), "Throttling") {
return resource.RetryableError(
fmt.Errorf("[WARN] Error, retrying: %s", err))
}
return resource.NonRetryableError(err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

}
return nil
})
if err != nil {
return fmt.Errorf("Failure deregistering old backend_vm_ids from LBU: %s", err)
}
}
return resourceOutscaleOAPILBUAttachmentRead(d, meta)
}

func resourceOutscaleOAPILBUAttachmentDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*OutscaleClient).OSCAPI
e := d.Get("load_balancer_name").(string)
i := d.Get("backend_vm_ids").([]interface{})
i := d.Get("backend_vm_ids").(*schema.Set)

lb := make([]string, len(i))
lb := make([]string, i.Len())

for k, v := range i {
for k, v := range i.List() {
lb[k] = v.(string)
}

Expand Down