From 28543694de6333696f07e1008153a6c0d2811983 Mon Sep 17 00:00:00 2001 From: Sander van Harmelen Date: Tue, 12 Jul 2016 20:23:10 +0200 Subject: [PATCH] =?UTF-8?q?Fix=20refresing=20an=20IP=20when=20it=E2=80=99s?= =?UTF-8?q?=20no=20longer=20associated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resource_cloudstack_instance.go | 50 ++++++++++--------- .../resource_cloudstack_port_forward.go | 17 +++++++ 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/builtin/providers/cloudstack/resource_cloudstack_instance.go b/builtin/providers/cloudstack/resource_cloudstack_instance.go index ef19c9848..6939f05df 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_instance.go +++ b/builtin/providers/cloudstack/resource_cloudstack_instance.go @@ -252,9 +252,12 @@ func resourceCloudStackInstanceCreate(d *schema.ResourceData, meta interface{}) p.SetKeypair(keypair.(string)) } - if ud, err := getUserData(d, cs); err != nil { - return err - } else if len(ud) > 0 { + if userData, ok := d.GetOk("user_data"); ok { + ud, err := getUserData(userData.(string), cs.HTTPGETOnly) + if err != nil { + return err + } + p.SetUserdata(ud) } @@ -438,6 +441,7 @@ func resourceCloudStackInstanceUpdate(d *schema.ResourceData, meta interface{}) d.SetPartial("service_offering") } + // Check if the affinity group IDs have changed and if so, update the IDs if d.HasChange("affinity_group_ids") { p := cs.AffinityGroup.NewUpdateVMAffinityGroupParams(d.Id()) groups := []string{} @@ -451,6 +455,7 @@ func resourceCloudStackInstanceUpdate(d *schema.ResourceData, meta interface{}) p.SetAffinitygroupids(groups) } + // Check if the affinity group names have changed and if so, update the names if d.HasChange("affinity_group_names") { p := cs.AffinityGroup.NewUpdateVMAffinityGroupParams(d.Id()) groups := []string{} @@ -464,6 +469,7 @@ func resourceCloudStackInstanceUpdate(d *schema.ResourceData, meta interface{}) p.SetAffinitygroupids(groups) } + // Check if the keypair has changed and if so, update the keypair if d.HasChange("keypair") { log.Printf("[DEBUG] SSH keypair changed for %s, starting update", name) @@ -478,10 +484,11 @@ func resourceCloudStackInstanceUpdate(d *schema.ResourceData, meta interface{}) d.SetPartial("keypair") } + // Check if the user data has changed and if so, update the user data if d.HasChange("user_data") { log.Printf("[DEBUG] user_data changed for %s, starting update", name) - ud, err := getUserData(d, cs) + ud, err := getUserData(d.Get("user_data").(string), cs.HTTPGETOnly) if err != nil { return err } @@ -534,28 +541,23 @@ func resourceCloudStackInstanceDelete(d *schema.ResourceData, meta interface{}) return nil } -// getUserData returns user_data as a base64 encoded string. An empty -// string is returned if unset. -func getUserData(d *schema.ResourceData, cs *cloudstack.CloudStackClient) (string, error) { - if userData, ok := d.GetOk("user_data"); ok { - ud := base64.StdEncoding.EncodeToString([]byte(userData.(string))) +// getUserData returns the user data as a base64 encoded string +func getUserData(userData string, httpGetOnly bool) (string, error) { + ud := base64.StdEncoding.EncodeToString([]byte(userData)) - // deployVirtualMachine uses POST by default, so max userdata is 32K - maxUD := 32768 + // deployVirtualMachine uses POST by default, so max userdata is 32K + maxUD := 32768 - if cs.HTTPGETOnly { - // deployVirtualMachine using GET instead, so max userdata is 2K - maxUD = 2048 - } - - if len(ud) > maxUD { - return "", fmt.Errorf( - "The supplied user_data contains %d bytes after encoding, "+ - "this exeeds the limit of %d bytes", len(ud), maxUD) - } - - return ud, nil + if httpGetOnly { + // deployVirtualMachine using GET instead, so max userdata is 2K + maxUD = 2048 } - return "", nil + if len(ud) > maxUD { + return "", fmt.Errorf( + "The supplied user_data contains %d bytes after encoding, "+ + "this exeeds the limit of %d bytes", len(ud), maxUD) + } + + return ud, nil } diff --git a/builtin/providers/cloudstack/resource_cloudstack_port_forward.go b/builtin/providers/cloudstack/resource_cloudstack_port_forward.go index 616adcf78..96064251d 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_port_forward.go +++ b/builtin/providers/cloudstack/resource_cloudstack_port_forward.go @@ -2,6 +2,7 @@ package cloudstack import ( "fmt" + "log" "sync" "time" @@ -173,6 +174,22 @@ func createPortForward(d *schema.ResourceData, meta interface{}, forward map[str func resourceCloudStackPortForwardRead(d *schema.ResourceData, meta interface{}) error { cs := meta.(*cloudstack.CloudStackClient) + // First check if the IP address is still associated + _, count, err := cs.Address.GetPublicIpAddressByID( + d.Id(), + cloudstack.WithProject(d.Get("project").(string)), + ) + if err != nil { + if count == 0 { + log.Printf( + "[DEBUG] IP address with ID %s is no longer associated", d.Id()) + d.SetId("") + return nil + } + + return err + } + // Get all the forwards from the running environment p := cs.Firewall.NewListPortForwardingRulesParams() p.SetIpaddressid(d.Id())