Skip to content
Draft
Show file tree
Hide file tree
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
3 changes: 3 additions & 0 deletions cloudstack/resource_cloudstack_autoscale_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ func resourceCloudStackAutoScalePolicy() *schema.Resource {
Read: resourceCloudStackAutoScalePolicyRead,
Update: resourceCloudStackAutoScalePolicyUpdate,
Delete: resourceCloudStackAutoScalePolicyDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"name": {
Expand Down
3 changes: 3 additions & 0 deletions cloudstack/resource_cloudstack_autoscale_vm_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ func resourceCloudStackAutoScaleVMGroup() *schema.Resource {
Read: resourceCloudStackAutoScaleVMGroupRead,
Update: resourceCloudStackAutoScaleVMGroupUpdate,
Delete: resourceCloudStackAutoScaleVMGroupDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"lbrule_id": {
Expand Down
3 changes: 3 additions & 0 deletions cloudstack/resource_cloudstack_autoscale_vm_profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ func resourceCloudStackAutoScaleVMProfile() *schema.Resource {
Read: resourceCloudStackAutoScaleVMProfileRead,
Update: resourceCloudStackAutoScaleVMProfileUpdate,
Delete: resourceCloudStackAutoScaleVMProfileDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"service_offering": {
Expand Down
21 changes: 21 additions & 0 deletions cloudstack/resource_cloudstack_autoscale_vm_profile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,27 @@ func TestAccCloudStackAutoscaleVMProfile_update(t *testing.T) {
})
}

func TestAccCloudStackAutoscaleVMProfile_import(t *testing.T) {
t.Skip("Skipping due to bug in cloudstack-go library")

Comment on lines +88 to +90
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCloudStackAutoscaleVMProfileDestroy,
Steps: []resource.TestStep{
{
Config: testAccCloudStackAutoscaleVMProfile_basic,
},

{
ResourceName: "cloudstack_autoscale_vm_profile.foo",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccCheckResourceMetadata(vmProfile *cloudstack.AutoScaleVmProfile) resource.TestCheckFunc {
return func(s *terraform.State) error {
cs := testAccProvider.Meta().(*cloudstack.CloudStackClient)
Expand Down
3 changes: 3 additions & 0 deletions cloudstack/resource_cloudstack_condition.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ func resourceCloudStackCondition() *schema.Resource {
Read: resourceCloudStackConditionRead,
Update: resourceCloudStackConditionUpdate,
Delete: resourceCloudStackConditionDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"counter_id": {
Expand Down
3 changes: 3 additions & 0 deletions cloudstack/resource_cloudstack_counter.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ func resourceCloudStackCounter() *schema.Resource {
Create: resourceCloudStackCounterCreate,
Read: resourceCloudStackCounterRead,
Delete: resourceCloudStackCounterDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"name": {
Expand Down
3 changes: 3 additions & 0 deletions cloudstack/resource_cloudstack_host.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ func resourceCloudStackHost() *schema.Resource {
Update: resourceCloudStackHostUpdate,
Create: resourceCloudStackHostCreate,
Delete: resourceCloudStackHostDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Comment on lines +40 to +42
Schema: map[string]*schema.Schema{
"hypervisor": {
Type: schema.TypeString,
Expand Down
26 changes: 26 additions & 0 deletions cloudstack/resource_cloudstack_host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,32 @@ func TestAccCloudStackHost_basic(t *testing.T) {
})
}

func TestAccCloudStackHost_import(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccCloudStackHost_basic,
},

{
ResourceName: "cloudstack_host.test",
ImportState: true,
ImportStateVerify: true,
// CloudStack's listHosts API never returns the connection URL or
// credentials, and these timeouts/flags are provider-local knobs that
// aren't part of the host object, so Read can't populate any of them.
ImportStateVerifyIgnore: []string{
"url", "username", "password",
"create_timeout", "destroy_timeout",
"prevent_destroy", "force_destroy",
},
},
},
})
}

const testAccCloudStackHost_basic = `
data "cloudstack_zone" "zone" {
filter {
Expand Down
3 changes: 3 additions & 0 deletions cloudstack/resource_cloudstack_ipaddress.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ func resourceCloudStackIPAddress() *schema.Resource {
Create: resourceCloudStackIPAddressCreate,
Read: resourceCloudStackIPAddressRead,
Delete: resourceCloudStackIPAddressDelete,
Importer: &schema.ResourceImporter{
State: importStatePassthrough,
},

Schema: map[string]*schema.Schema{
"is_portable": {
Expand Down
19 changes: 19 additions & 0 deletions cloudstack/resource_cloudstack_ipaddress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,25 @@ func TestAccCloudStackIPAddress_basic(t *testing.T) {
})
}

func TestAccCloudStackIPAddress_import(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCloudStackIPAddressDestroy,
Steps: []resource.TestStep{
{
Config: testAccCloudStackIPAddress_basic,
},

{
ResourceName: "cloudstack_ipaddress.foo",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccCloudStackIPAddress_vpc(t *testing.T) {
var ipaddr cloudstack.PublicIpAddress

Expand Down
3 changes: 3 additions & 0 deletions cloudstack/resource_cloudstack_loadbalancer_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ func resourceCloudStackLoadBalancerRule() *schema.Resource {
Read: resourceCloudStackLoadBalancerRuleRead,
Update: resourceCloudStackLoadBalancerRuleUpdate,
Delete: resourceCloudStackLoadBalancerRuleDelete,
Importer: &schema.ResourceImporter{
State: importStatePassthrough,
},

Schema: map[string]*schema.Schema{
"name": {
Expand Down
21 changes: 21 additions & 0 deletions cloudstack/resource_cloudstack_loadbalancer_rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,27 @@ func TestAccCloudStackLoadBalancerRule_basic(t *testing.T) {
})
}

func TestAccCloudStackLoadBalancerRule_import(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCloudStackLoadBalancerRuleDestroy,
Steps: []resource.TestStep{
{
Config: testAccCloudStackLoadBalancerRule_basic,
},

{
ResourceName: "cloudstack_loadbalancer_rule.foo",
ImportState: true,
ImportStateVerify: true,
// certificate_id can't be read back from the CloudStack API (write-only field)
ImportStateVerifyIgnore: []string{"certificate_id"},
},
},
})
}

func TestAccCloudStackLoadBalancerRule_update(t *testing.T) {
var id string

Expand Down
20 changes: 20 additions & 0 deletions cloudstack/resource_cloudstack_network_offering.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ func resourceCloudStackNetworkOffering() *schema.Resource {
Read: resourceCloudStackNetworkOfferingRead,
Update: resourceCloudStackNetworkOfferingUpdate,
Delete: resourceCloudStackNetworkOfferingDelete,
Importer: &schema.ResourceImporter{
State: resourceCloudStackNetworkOfferingImport,
},
Comment on lines +36 to +38
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Expand Down Expand Up @@ -342,6 +345,23 @@ func resourceCloudStackNetworkOfferingDelete(d *schema.ResourceData, meta interf
return nil
}

func resourceCloudStackNetworkOfferingImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
cs := meta.(*cloudstack.CloudStackClient)

// Read looks the offering up by name, so resolve the name from the ID first
n, count, err := cs.NetworkOffering.GetNetworkOfferingByID(d.Id())
if err != nil {
if count == 0 {
return nil, fmt.Errorf("network offering with ID %s does not exist", d.Id())
}
return nil, err
}

d.Set("name", n.Name)

return []*schema.ResourceData{d}, nil
}

func resourceCloudStackNetworkOfferingRead(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)
log.Printf("[DEBUG] Retrieving Network Offering %s", d.Get("name").(string))
Expand Down
89 changes: 89 additions & 0 deletions cloudstack/resource_cloudstack_port_forward.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ func resourceCloudStackPortForward() *schema.Resource {
Read: resourceCloudStackPortForwardRead,
Update: resourceCloudStackPortForwardUpdate,
Delete: resourceCloudStackPortForwardDelete,
Importer: &schema.ResourceImporter{
State: resourceCloudStackPortForwardImport,
},

Schema: map[string]*schema.Schema{
"ip_address_id": {
Expand Down Expand Up @@ -230,6 +233,90 @@ func createPortForward(d *schema.ResourceData, meta interface{}, forward map[str
return nil
}

func resourceCloudStackPortForwardImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
cs := meta.(*cloudstack.CloudStackClient)

// Try to split the ID to extract the optional project name.
s := strings.SplitN(d.Id(), "/", 2)
if len(s) == 2 {
d.Set("project", s[0])
}

ipAddressID := s[len(s)-1]
d.SetId(ipAddressID)
d.Set("ip_address_id", ipAddressID)

// Make sure the IP address exists
if _, count, err := cs.Address.GetPublicIpAddressByID(
ipAddressID,
cloudstack.WithProject(d.Get("project").(string)),
); err != nil {
if count == 0 {
return nil, fmt.Errorf("IP address with ID %s does not exist", ipAddressID)
}
return nil, err
}

// Get all the forwards configured for this IP address
p := cs.Firewall.NewListPortForwardingRulesParams()
p.SetIpaddressid(ipAddressID)
p.SetListall(true)

if err := setProjectid(p, cs, d); err != nil {
return nil, err
}

l, err := cs.Firewall.ListPortForwardingRules(p)
if err != nil {
return nil, err
}

forwards := resourceCloudStackPortForward().Schema["forward"].ZeroValue().(*schema.Set)
for _, f := range l.PortForwardingRules {
privPort, err := strconv.Atoi(f.Privateport)
if err != nil {
return nil, err
}

pubPort, err := strconv.Atoi(f.Publicport)
if err != nil {
return nil, err
}

forward := map[string]interface{}{
"protocol": f.Protocol,
"private_port": privPort,
"public_port": pubPort,
"virtual_machine_id": f.Virtualmachineid,
"vm_guest_ip": f.Vmguestip,
"uuid": f.Id,
}

if f.Privateendport != "" && f.Privateendport != f.Privateport {
privEndPort, err := strconv.Atoi(f.Privateendport)
if err != nil {
return nil, err
}
forward["private_end_port"] = privEndPort
}

if f.Publicendport != "" && f.Publicendport != f.Publicport {
pubEndPort, err := strconv.Atoi(f.Publicendport)
if err != nil {
return nil, err
}
forward["public_end_port"] = pubEndPort
}

forwards.Add(forward)
}

d.Set("forward", forwards)
d.Set("managed", true)

return []*schema.ResourceData{d}, nil
Comment on lines +314 to +317
}

func resourceCloudStackPortForwardRead(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)

Expand All @@ -249,6 +336,8 @@ func resourceCloudStackPortForwardRead(d *schema.ResourceData, meta interface{})
return err
}

d.Set("ip_address_id", d.Id())

// Get all the forwards from the running environment
p := cs.Firewall.NewListPortForwardingRulesParams()
p.SetIpaddressid(d.Id())
Expand Down
22 changes: 22 additions & 0 deletions cloudstack/resource_cloudstack_port_forward_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,28 @@ func TestAccCloudStackPortForward_basic(t *testing.T) {
})
}

func TestAccCloudStackPortForward_import(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCloudStackPortForwardDestroy,
Steps: []resource.TestStep{
{
Config: testAccCloudStackPortForward_basic,
},

{
ResourceName: "cloudstack_port_forward.foo",
ImportState: true,
ImportStateVerify: true,
// The importer sets managed=true so unrelated forwards on the same IP
// aren't silently dropped; the applied config leaves it at its default.
ImportStateVerifyIgnore: []string{"managed"},
Comment on lines +74 to +76
},
},
})
}

func TestAccCloudStackPortForward_update(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand Down
Loading
Loading