diff --git a/cloudstack/resource_cloudstack_instance.go b/cloudstack/resource_cloudstack_instance.go index 09e345d..fdf77ee 100644 --- a/cloudstack/resource_cloudstack_instance.go +++ b/cloudstack/resource_cloudstack_instance.go @@ -390,7 +390,7 @@ func resourceCloudStackInstanceCreate(d *schema.ResourceData, meta interface{}) } if userData, ok := d.GetOk("user_data"); ok { - ud, err := getUserData(userData.(string), cs.HTTPGETOnly) + ud, err := getUserData(userData.(string)) if err != nil { return err } @@ -695,7 +695,7 @@ func resourceCloudStackInstanceUpdate(d *schema.ResourceData, meta interface{}) if d.HasChange("user_data") { log.Printf("[DEBUG] user_data changed for %s, starting update", name) - ud, err := getUserData(d.Get("user_data").(string), cs.HTTPGETOnly) + ud, err := getUserData(d.Get("user_data").(string)) if err != nil { return err } @@ -772,25 +772,11 @@ func resourceCloudStackInstanceImport(d *schema.ResourceData, meta interface{}) } // getUserData returns the user data as a base64 encoded string -func getUserData(userData string, httpGetOnly bool) (string, error) { +func getUserData(userData string) (string, error) { ud := userData if _, err := base64.StdEncoding.DecodeString(ud); err != nil { ud = base64.StdEncoding.EncodeToString([]byte(userData)) } - // deployVirtualMachine uses POST by default, so max userdata is 32K - maxUD := 32768 - - if 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 exceeds the limit of %d bytes", len(ud), maxUD) - } - return ud, nil } diff --git a/cloudstack/resource_cloudstack_instance_test.go b/cloudstack/resource_cloudstack_instance_test.go index d7eeada..5979aaa 100644 --- a/cloudstack/resource_cloudstack_instance_test.go +++ b/cloudstack/resource_cloudstack_instance_test.go @@ -21,6 +21,7 @@ package cloudstack import ( "fmt" + "regexp" "testing" "github.com/apache/cloudstack-go/v2/cloudstack" @@ -274,6 +275,26 @@ func TestAccCloudStackInstance_importProject(t *testing.T) { }) } +func TestAccCloudStackInstance_userData(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCloudStackInstanceDestroy, + ExternalProviders: map[string]resource.ExternalProvider{ + "random": { + VersionConstraint: ">= 3.6.0", + Source: "hashicorp/random", + }, + }, + Steps: []resource.TestStep{ + { + Config: testAccCloudStackInstance_userData, + ExpectError: regexp.MustCompile("User data has exceeded configurable max length"), + }, + }, + }) +} + func testAccCheckCloudStackInstanceExists( n string, instance *cloudstack.VirtualMachine) resource.TestCheckFunc { return func(s *terraform.State) error { @@ -525,3 +546,33 @@ resource "cloudstack_instance" "foobar" { zone = cloudstack_network.foo.zone expunge = true }` + +const testAccCloudStackInstance_userData = ` +resource "random_bytes" "string" { + length = 32768 +} + +resource "cloudstack_network" "foo" { + name = "terraform-network" + display_text = "terraform-network" + cidr = "10.1.1.0/24" + network_offering = "DefaultIsolatedNetworkOfferingWithSourceNatService" + zone = "Sandbox-simulator" +} + +resource "cloudstack_instance" "foobar" { + name = "terraform-test" + display_name = "terraform-test" + service_offering= "Small Instance" + network_id = cloudstack_network.foo.id + template = "CentOS 5.6 (64-bit) no GUI (Simulator)" + zone = cloudstack_network.foo.zone + expunge = true + user_data = <<-EOFTF +#!/bin/bash + +echo <