Refactor the use of names vs IDs for parameters referencing other TF resources

We have a curtesy function in place allowing you to specify both a
`name` of `ID`. But in order for the graph to be build correctly when
you recreate or taint stuff that other resources depend on, we need to
reference the `ID` and *not* the `name`.

So in order to enforce this and by that help people to not make this
mistake unknowingly, I deprecated all the parameters this allies to and
changed the logic, docs and tests accordingly.
This commit is contained in:
Sander van Harmelen 2016-04-11 17:14:19 +02:00
parent ae371b5492
commit 815c8840a7
50 changed files with 747 additions and 459 deletions

View File

@ -94,14 +94,8 @@ func resourceCloudStackDiskCreate(d *schema.ResourceData, meta interface{}) erro
}
// If there is a project supplied, we retrieve and set the project id
if project, ok := d.GetOk("project"); ok {
// Retrieve the project ID
projectid, e := retrieveID(cs, "project", project.(string))
if e != nil {
return e.Error()
}
// Set the default project ID
p.SetProjectid(projectid)
if err := setProjectid(p, cs, d); err != nil {
return err
}
// Retrieve the zone ID

View File

@ -175,7 +175,7 @@ resource "cloudstack_instance" "foobar" {
name = "terraform-test"
display_name = "terraform"
service_offering= "%s"
network = "%s"
network_id = "%s"
template = "%s"
zone = "%s"
expunge = true
@ -200,7 +200,7 @@ resource "cloudstack_instance" "foobar" {
name = "terraform-test"
display_name = "terraform"
service_offering= "%s"
network = "%s"
network_id = "%s"
template = "%s"
zone = "%s"
expunge = true
@ -224,7 +224,7 @@ resource "cloudstack_instance" "foobar" {
name = "terraform-test"
display_name = "terraform"
service_offering= "%s"
network = "%s"
network_id = "%s"
template = "%s"
zone = "%s"
expunge = true

View File

@ -1,6 +1,7 @@
package cloudstack
import (
"errors"
"fmt"
"strconv"
"strings"
@ -20,10 +21,19 @@ func resourceCloudStackEgressFirewall() *schema.Resource {
Delete: resourceCloudStackEgressFirewallDelete,
Schema: map[string]*schema.Schema{
"network_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ConflictsWith: []string{"network"},
},
"network": &schema.Schema{
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `network_id` field instead",
ConflictsWith: []string{"network_id"},
},
"managed": &schema.Schema{
@ -99,8 +109,16 @@ func resourceCloudStackEgressFirewallCreate(d *schema.ResourceData, meta interfa
return err
}
network, ok := d.GetOk("network_id")
if !ok {
network, ok = d.GetOk("network")
}
if !ok {
return errors.New("Either `network_id` or [deprecated] `network` must be provided.")
}
// Retrieve the network ID
networkid, e := retrieveID(cs, "network", d.Get("network").(string))
networkid, e := retrieveID(cs, "network", network.(string))
if e != nil {
return e.Error()
}

View File

@ -21,7 +21,7 @@ func TestAccCloudStackEgressFirewall_basic(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudStackEgressFirewallRulesExist("cloudstack_egress_firewall.foo"),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "network", CLOUDSTACK_NETWORK_1),
"cloudstack_egress_firewall.foo", "network_id", CLOUDSTACK_NETWORK_1),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.#", "2"),
resource.TestCheckResourceAttr(
@ -59,7 +59,7 @@ func TestAccCloudStackEgressFirewall_update(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudStackEgressFirewallRulesExist("cloudstack_egress_firewall.foo"),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "network", CLOUDSTACK_NETWORK_1),
"cloudstack_egress_firewall.foo", "network_id", CLOUDSTACK_NETWORK_1),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.#", "2"),
resource.TestCheckResourceAttr(
@ -88,7 +88,7 @@ func TestAccCloudStackEgressFirewall_update(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudStackEgressFirewallRulesExist("cloudstack_egress_firewall.foo"),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "network", CLOUDSTACK_NETWORK_1),
"cloudstack_egress_firewall.foo", "network_id", CLOUDSTACK_NETWORK_1),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.#", "3"),
resource.TestCheckResourceAttr(
@ -188,7 +188,7 @@ func testAccCheckCloudStackEgressFirewallDestroy(s *terraform.State) error {
var testAccCloudStackEgressFirewall_basic = fmt.Sprintf(`
resource "cloudstack_egress_firewall" "foo" {
network = "%s"
network_id = "%s"
rule {
cidr_list = ["%s/32"]
@ -208,7 +208,7 @@ resource "cloudstack_egress_firewall" "foo" {
var testAccCloudStackEgressFirewall_update = fmt.Sprintf(`
resource "cloudstack_egress_firewall" "foo" {
network = "%s"
network_id = "%s"
rule {
cidr_list = ["%s/32", "%s/32"]

View File

@ -21,7 +21,7 @@ func resourceCloudStackFirewall() *schema.Resource {
Delete: resourceCloudStackFirewallDelete,
Schema: map[string]*schema.Schema{
"ip_address": &schema.Schema{
"ip_address_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
@ -32,8 +32,8 @@ func resourceCloudStackFirewall() *schema.Resource {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `ip_address` field instead",
ConflictsWith: []string{"ip_address"},
Deprecated: "Please use the `ip_address_id` field instead",
ConflictsWith: []string{"ip_address_id"},
},
"managed": &schema.Schema{
@ -109,12 +109,12 @@ func resourceCloudStackFirewallCreate(d *schema.ResourceData, meta interface{})
return err
}
ipaddress, ok := d.GetOk("ip_address")
ipaddress, ok := d.GetOk("ip_address_id")
if !ok {
ipaddress, ok = d.GetOk("ipaddress")
}
if !ok {
return errors.New("Either `ip_address` or [deprecated] `ipaddress` must be provided.")
return errors.New("Either `ip_address_id` or [deprecated] `ipaddress` must be provided.")
}
// Retrieve the ipaddress ID

View File

@ -21,7 +21,7 @@ func TestAccCloudStackFirewall_basic(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudStackFirewallRulesExist("cloudstack_firewall.foo"),
resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "ip_address", CLOUDSTACK_PUBLIC_IPADDRESS),
"cloudstack_firewall.foo", "ip_address_id", CLOUDSTACK_PUBLIC_IPADDRESS),
resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.#", "2"),
resource.TestCheckResourceAttr(
@ -55,7 +55,7 @@ func TestAccCloudStackFirewall_update(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudStackFirewallRulesExist("cloudstack_firewall.foo"),
resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "ip_address", CLOUDSTACK_PUBLIC_IPADDRESS),
"cloudstack_firewall.foo", "ip_address_id", CLOUDSTACK_PUBLIC_IPADDRESS),
resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.#", "2"),
resource.TestCheckResourceAttr(
@ -80,7 +80,7 @@ func TestAccCloudStackFirewall_update(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudStackFirewallRulesExist("cloudstack_firewall.foo"),
resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "ip_address", CLOUDSTACK_PUBLIC_IPADDRESS),
"cloudstack_firewall.foo", "ip_address_id", CLOUDSTACK_PUBLIC_IPADDRESS),
resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.#", "3"),
resource.TestCheckResourceAttr(
@ -174,7 +174,7 @@ func testAccCheckCloudStackFirewallDestroy(s *terraform.State) error {
var testAccCloudStackFirewall_basic = fmt.Sprintf(`
resource "cloudstack_firewall" "foo" {
ip_address = "%s"
ip_address_id = "%s"
rule {
cidr_list = ["10.0.0.0/24"]
@ -191,7 +191,7 @@ resource "cloudstack_firewall" "foo" {
var testAccCloudStackFirewall_update = fmt.Sprintf(`
resource "cloudstack_firewall" "foo" {
ip_address = "%s"
ip_address_id = "%s"
rule {
cidr_list = ["10.0.0.0/24", "10.0.1.0/24"]

View File

@ -4,6 +4,7 @@ import (
"crypto/sha1"
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
"log"
"strings"
@ -37,10 +38,18 @@ func resourceCloudStackInstance() *schema.Resource {
Required: true,
},
"network_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"network": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `network_id` field instead",
},
"ip_address": &schema.Schema{
@ -149,11 +158,21 @@ func resourceCloudStackInstanceCreate(d *schema.ResourceData, meta interface{})
}
if zone.Networktype == "Advanced" {
network, ok := d.GetOk("network_id")
if !ok {
network, ok = d.GetOk("network")
}
if !ok {
return errors.New(
"Either `network_id` or [deprecated] `network` must be provided when using a zone with network type `advanced`.")
}
// Retrieve the network ID
networkid, e := retrieveID(cs, "network", d.Get("network").(string))
networkid, e := retrieveID(cs, "network", network.(string))
if e != nil {
return e.Error()
}
// Set the default network ID
p.SetNetworkids([]string{networkid})
}
@ -168,14 +187,8 @@ func resourceCloudStackInstanceCreate(d *schema.ResourceData, meta interface{})
}
// If there is a project supplied, we retrieve and set the project id
if project, ok := d.GetOk("project"); ok {
// Retrieve the project ID
projectid, e := retrieveID(cs, "project", project.(string))
if e != nil {
return e.Error()
}
// Set the default project ID
p.SetProjectid(projectid)
if err := setProjectid(p, cs, d); err != nil {
return err
}
// If a keypair is supplied, add it to the parameter struct
@ -240,10 +253,9 @@ func resourceCloudStackInstanceRead(d *schema.ResourceData, meta interface{}) er
// Update the config
d.Set("name", vm.Name)
d.Set("display_name", vm.Displayname)
d.Set("network_id", vm.Nic[0].Networkid)
d.Set("ip_address", vm.Nic[0].Ipaddress)
//NB cloudstack sometimes sends back the wrong keypair name, so dont update it
setValueOrID(d, "network", vm.Nic[0].Networkname, vm.Nic[0].Networkid)
setValueOrID(d, "service_offering", vm.Serviceofferingname, vm.Serviceofferingid)
setValueOrID(d, "template", vm.Templatename, vm.Templateid)
setValueOrID(d, "project", vm.Project, vm.Projectid)

View File

@ -180,8 +180,8 @@ func testAccCheckCloudStackInstanceAttributes(
return fmt.Errorf("Bad template: %s", instance.Templatename)
}
if instance.Nic[0].Networkname != CLOUDSTACK_NETWORK_1 {
return fmt.Errorf("Bad network: %s", instance.Nic[0].Networkname)
if instance.Nic[0].Networkid != CLOUDSTACK_NETWORK_1 {
return fmt.Errorf("Bad network ID: %s", instance.Nic[0].Networkid)
}
return nil
@ -234,7 +234,7 @@ resource "cloudstack_instance" "foobar" {
name = "terraform-test"
display_name = "terraform-test"
service_offering= "%s"
network = "%s"
network_id = "%s"
template = "%s"
zone = "%s"
user_data = "foobar\nfoo\nbar"
@ -250,7 +250,7 @@ resource "cloudstack_instance" "foobar" {
name = "terraform-updated"
display_name = "terraform-updated"
service_offering= "%s"
network = "%s"
network_id = "%s"
template = "%s"
zone = "%s"
user_data = "foobar\nfoo\nbar"
@ -266,7 +266,7 @@ resource "cloudstack_instance" "foobar" {
name = "terraform-test"
display_name = "terraform-test"
service_offering= "%s"
network = "%s"
network_id = "%s"
ip_address = "%s"
template = "%s"
zone = "%s"
@ -287,7 +287,7 @@ resource "cloudstack_instance" "foobar" {
name = "terraform-test"
display_name = "terraform-test"
service_offering= "%s"
network = "%s"
network_id = "%s"
ip_address = "%s"
template = "%s"
zone = "%s"
@ -305,7 +305,7 @@ resource "cloudstack_instance" "foobar" {
name = "terraform-test"
display_name = "terraform-test"
service_offering= "%s"
network = "%s"
network_id = "%s"
template = "%s"
project = "%s"
zone = "%s"

View File

@ -16,16 +16,32 @@ func resourceCloudStackIPAddress() *schema.Resource {
Delete: resourceCloudStackIPAddressDelete,
Schema: map[string]*schema.Schema{
"network_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"network": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `network_id` field instead",
},
"vpc_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"vpc": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `vpc_id` field instead",
},
"project": &schema.Schema{
@ -52,7 +68,11 @@ func resourceCloudStackIPAddressCreate(d *schema.ResourceData, meta interface{})
// Create a new parameter struct
p := cs.Address.NewAssociateIpAddressParams()
if network, ok := d.GetOk("network"); ok {
network, ok := d.GetOk("network_id")
if !ok {
network, ok = d.GetOk("network")
}
if ok {
// Retrieve the network ID
networkid, e := retrieveID(cs, "network", network.(string))
if e != nil {
@ -63,7 +83,11 @@ func resourceCloudStackIPAddressCreate(d *schema.ResourceData, meta interface{})
p.SetNetworkid(networkid)
}
if vpc, ok := d.GetOk("vpc"); ok {
vpc, ok := d.GetOk("vpc_id")
if !ok {
vpc, ok = d.GetOk("vpc")
}
if ok {
// Retrieve the vpc ID
vpcid, e := retrieveID(cs, "vpc", vpc.(string))
if e != nil {
@ -75,14 +99,8 @@ func resourceCloudStackIPAddressCreate(d *schema.ResourceData, meta interface{})
}
// If there is a project supplied, we retrieve and set the project id
if project, ok := d.GetOk("project"); ok {
// Retrieve the project ID
projectid, e := retrieveID(cs, "project", project.(string))
if e != nil {
return e.Error()
}
// Set the default project ID
p.SetProjectid(projectid)
if err := setProjectid(p, cs, d); err != nil {
return err
}
// Associate a new IP address
@ -115,24 +133,16 @@ func resourceCloudStackIPAddressRead(d *schema.ResourceData, meta interface{}) e
// Updated the IP address
d.Set("ip_address", ip.Ipaddress)
if _, ok := d.GetOk("network"); ok {
// Get the network details
n, _, err := cs.Network.GetNetworkByID(ip.Associatednetworkid)
if err != nil {
return err
_, networkID := d.GetOk("network_id")
_, network := d.GetOk("network")
if networkID || network {
d.Set("network_id", ip.Associatednetworkid)
}
setValueOrID(d, "network", n.Name, ip.Associatednetworkid)
}
if _, ok := d.GetOk("vpc"); ok {
// Get the VPC details
v, _, err := cs.VPC.GetVPCByID(ip.Vpcid)
if err != nil {
return err
}
setValueOrID(d, "vpc", v.Name, ip.Vpcid)
_, vpcID := d.GetOk("vpc_id")
_, vpc := d.GetOk("vpc")
if vpcID || vpc {
d.Set("vpc_id", ip.Vpcid)
}
setValueOrID(d, "project", ip.Project, ip.Projectid)
@ -162,12 +172,14 @@ func resourceCloudStackIPAddressDelete(d *schema.ResourceData, meta interface{})
}
func verifyIPAddressParams(d *schema.ResourceData) error {
_, networkID := d.GetOk("network_id")
_, network := d.GetOk("network")
_, vpcID := d.GetOk("vpc_id")
_, vpc := d.GetOk("vpc")
if network && vpc || !network && !vpc {
if (networkID || network) && (vpcID || vpc) || (!networkID && !network) && (!vpcID && !vpc) {
return fmt.Errorf(
"You must supply a value for either (so not both) the 'network' or 'vpc' parameter")
"You must supply a value for either (so not both) the 'network_id' or 'vpc_id' parameter")
}
return nil

View File

@ -42,8 +42,6 @@ func TestAccCloudStackIPAddress_vpc(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudStackIPAddressExists(
"cloudstack_ipaddress.foo", &ipaddr),
resource.TestCheckResourceAttr(
"cloudstack_ipaddress.foo", "vpc", "terraform-vpc"),
),
},
},
@ -83,8 +81,8 @@ func testAccCheckCloudStackIPAddressAttributes(
ipaddr *cloudstack.PublicIpAddress) resource.TestCheckFunc {
return func(s *terraform.State) error {
if ipaddr.Associatednetworkname != CLOUDSTACK_NETWORK_1 {
return fmt.Errorf("Bad network: %s", ipaddr.Associatednetworkname)
if ipaddr.Associatednetworkid != CLOUDSTACK_NETWORK_1 {
return fmt.Errorf("Bad network ID: %s", ipaddr.Associatednetworkid)
}
return nil
@ -114,7 +112,7 @@ func testAccCheckCloudStackIPAddressDestroy(s *terraform.State) error {
var testAccCloudStackIPAddress_basic = fmt.Sprintf(`
resource "cloudstack_ipaddress" "foo" {
network = "%s"
network_id = "%s"
}`, CLOUDSTACK_NETWORK_1)
var testAccCloudStackIPAddress_vpc = fmt.Sprintf(`
@ -126,7 +124,7 @@ resource "cloudstack_vpc" "foobar" {
}
resource "cloudstack_ipaddress" "foo" {
vpc = "${cloudstack_vpc.foobar.name}"
vpc_id = "${cloudstack_vpc.foobar.id}"
}`,
CLOUDSTACK_VPC_CIDR_1,
CLOUDSTACK_VPC_OFFERING,

View File

@ -29,25 +29,32 @@ func resourceCloudStackLoadBalancerRule() *schema.Resource {
Computed: true,
},
"ip_address": &schema.Schema{
"ip_address_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ConflictsWith: []string{"ipaddress"},
},
"ipaddress": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `ip_address` field instead",
ConflictsWith: []string{"ip_address"},
Deprecated: "Please use the `ip_address_id` field instead",
},
"network_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"network": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `network_id` field instead",
},
"algorithm": &schema.Schema{
@ -67,11 +74,21 @@ func resourceCloudStackLoadBalancerRule() *schema.Resource {
ForceNew: true,
},
"members": &schema.Schema{
"member_ids": &schema.Schema{
Type: schema.TypeList,
Required: true,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
ConflictsWith: []string{"members"},
},
"members": &schema.Schema{
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
Deprecated: "Please use the `member_ids` field instead",
ConflictsWith: []string{"member_ids"},
},
},
}
@ -99,23 +116,27 @@ func resourceCloudStackLoadBalancerRuleCreate(d *schema.ResourceData, meta inter
p.SetDescription(d.Get("name").(string))
}
// Retrieve the network and the ID
if network, ok := d.GetOk("network"); ok {
network, ok := d.GetOk("network_id")
if !ok {
network, ok = d.GetOk("network")
}
if ok {
// Retrieve the network ID
networkid, e := retrieveID(cs, "network", network.(string))
if e != nil {
return e.Error()
}
// Set the default network ID
// Set the networkid
p.SetNetworkid(networkid)
}
ipaddress, ok := d.GetOk("ip_address")
ipaddress, ok := d.GetOk("ip_address_id")
if !ok {
ipaddress, ok = d.GetOk("ipaddress")
}
if !ok {
return errors.New("Either `ip_address` or [deprecated] `ipaddress` must be provided.")
return errors.New("Either `ip_address_id` or [deprecated] `ipaddress` must be provided.")
}
// Retrieve the ipaddress ID
@ -135,8 +156,8 @@ func resourceCloudStackLoadBalancerRuleCreate(d *schema.ResourceData, meta inter
d.SetId(r.Id)
d.SetPartial("name")
d.SetPartial("description")
d.SetPartial("ip_address")
d.SetPartial("network")
d.SetPartial("ip_address_id")
d.SetPartial("network_id")
d.SetPartial("algorithm")
d.SetPartial("private_port")
d.SetPartial("public_port")
@ -144,8 +165,16 @@ func resourceCloudStackLoadBalancerRuleCreate(d *schema.ResourceData, meta inter
// Create a new parameter struct
ap := cs.LoadBalancer.NewAssignToLoadBalancerRuleParams(r.Id)
members, ok := d.GetOk("member_ids")
if !ok {
members, ok = d.GetOk("members")
}
if !ok {
return errors.New("Either `member_ids` or [deprecated] `members` must be provided.")
}
var mbs []string
for _, id := range d.Get("members").([]interface{}) {
for _, id := range members.([]interface{}) {
mbs = append(mbs, id.(string))
}
@ -156,9 +185,10 @@ func resourceCloudStackLoadBalancerRuleCreate(d *schema.ResourceData, meta inter
return err
}
d.SetPartial("member_ids")
d.SetPartial("members")
d.Partial(false)
return resourceCloudStackLoadBalancerRuleRead(d, meta)
}
@ -180,16 +210,13 @@ func resourceCloudStackLoadBalancerRuleRead(d *schema.ResourceData, meta interfa
d.Set("algorithm", lb.Algorithm)
d.Set("public_port", lb.Publicport)
d.Set("private_port", lb.Privateport)
setValueOrID(d, "ip_address", lb.Publicip, lb.Publicipid)
d.Set("ip_address_id", lb.Publicipid)
// Only set network if user specified it to avoid spurious diffs
if _, ok := d.GetOk("network"); ok {
network, _, err := cs.Network.GetNetworkByID(lb.Networkid)
if err != nil {
return err
}
setValueOrID(d, "network", network.Name, lb.Networkid)
_, networkID := d.GetOk("network_id")
_, network := d.GetOk("network")
if networkID || network {
d.Set("network_id", lb.Networkid)
}
return nil

View File

@ -75,7 +75,7 @@ func TestAccCloudStackLoadBalancerRule_update(t *testing.T) {
})
}
func TestAccCloudStackLoadBalancerRule_forcenew(t *testing.T) {
func TestAccCloudStackLoadBalancerRule_forceNew(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
@ -138,7 +138,7 @@ func TestAccCloudStackLoadBalancerRule_vpc(t *testing.T) {
})
}
func TestAccCloudStackLoadBalancerRule_vpc_update(t *testing.T) {
func TestAccCloudStackLoadBalancerRule_vpcUpdate(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
@ -243,7 +243,7 @@ resource "cloudstack_instance" "foobar1" {
name = "terraform-server1"
display_name = "terraform"
service_offering= "%s"
network = "%s"
network_id = "%s"
template = "%s"
zone = "%s"
expunge = true
@ -251,11 +251,11 @@ resource "cloudstack_instance" "foobar1" {
resource "cloudstack_loadbalancer_rule" "foo" {
name = "terraform-lb"
ip_address = "%s"
ip_address_id = "%s"
algorithm = "roundrobin"
public_port = 80
private_port = 80
members = ["${cloudstack_instance.foobar1.id}"]
member_ids = ["${cloudstack_instance.foobar1.id}"]
}
`,
CLOUDSTACK_SERVICE_OFFERING_1,
@ -269,7 +269,7 @@ resource "cloudstack_instance" "foobar1" {
name = "terraform-server1"
display_name = "terraform"
service_offering= "%s"
network = "%s"
network_id = "%s"
template = "%s"
zone = "%s"
expunge = true
@ -277,11 +277,11 @@ resource "cloudstack_instance" "foobar1" {
resource "cloudstack_loadbalancer_rule" "foo" {
name = "terraform-lb-update"
ip_address = "%s"
ip_address_id = "%s"
algorithm = "leastconn"
public_port = 80
private_port = 80
members = ["${cloudstack_instance.foobar1.id}"]
member_ids = ["${cloudstack_instance.foobar1.id}"]
}
`,
CLOUDSTACK_SERVICE_OFFERING_1,
@ -295,7 +295,7 @@ resource "cloudstack_instance" "foobar1" {
name = "terraform-server1"
display_name = "terraform"
service_offering= "%s"
network = "%s"
network_id = "%s"
template = "%s"
zone = "%s"
expunge = true
@ -303,11 +303,11 @@ resource "cloudstack_instance" "foobar1" {
resource "cloudstack_loadbalancer_rule" "foo" {
name = "terraform-lb-update"
ip_address = "%s"
ip_address_id = "%s"
algorithm = "leastconn"
public_port = 443
private_port = 443
members = ["${cloudstack_instance.foobar1.id}"]
member_ids = ["${cloudstack_instance.foobar1.id}"]
}
`,
CLOUDSTACK_SERVICE_OFFERING_1,
@ -328,19 +328,19 @@ resource "cloudstack_network" "foo" {
name = "terraform-network"
cidr = "%s"
network_offering = "%s"
vpc = "${cloudstack_vpc.foobar.name}"
vpc_id = "${cloudstack_vpc.foobar.id}"
zone = "${cloudstack_vpc.foobar.zone}"
}
resource "cloudstack_ipaddress" "foo" {
vpc = "${cloudstack_vpc.foobar.name}"
vpc_id = "${cloudstack_vpc.foobar.id}"
}
resource "cloudstack_instance" "foobar1" {
name = "terraform-server1"
display_name = "terraform"
service_offering= "%s"
network = "${cloudstack_network.foo.name}"
network_id = "${cloudstack_network.foo.id}"
template = "%s"
zone = "${cloudstack_network.foo.zone}"
expunge = true
@ -348,12 +348,12 @@ resource "cloudstack_instance" "foobar1" {
resource "cloudstack_loadbalancer_rule" "foo" {
name = "terraform-lb"
ip_address = "${cloudstack_ipaddress.foo.ip_address}"
ip_address_id = "${cloudstack_ipaddress.foo.id}"
algorithm = "roundrobin"
network = "${cloudstack_network.foo.id}"
network_id = "${cloudstack_network.foo.id}"
public_port = 80
private_port = 80
members = ["${cloudstack_instance.foobar1.id}"]
member_ids = ["${cloudstack_instance.foobar1.id}"]
}`,
CLOUDSTACK_VPC_CIDR_1,
CLOUDSTACK_VPC_OFFERING,
@ -375,19 +375,19 @@ resource "cloudstack_network" "foo" {
name = "terraform-network"
cidr = "%s"
network_offering = "%s"
vpc = "${cloudstack_vpc.foobar.name}"
vpc_id = "${cloudstack_vpc.foobar.id}"
zone = "${cloudstack_vpc.foobar.zone}"
}
resource "cloudstack_ipaddress" "foo" {
vpc = "${cloudstack_vpc.foobar.name}"
vpc_id = "${cloudstack_vpc.foobar.id}"
}
resource "cloudstack_instance" "foobar1" {
name = "terraform-server1"
display_name = "terraform"
service_offering= "%s"
network = "${cloudstack_network.foo.name}"
network_id = "${cloudstack_network.foo.id}"
template = "%s"
zone = "${cloudstack_network.foo.zone}"
expunge = true
@ -397,7 +397,7 @@ resource "cloudstack_instance" "foobar2" {
name = "terraform-server2"
display_name = "terraform"
service_offering= "%s"
network = "${cloudstack_network.foo.name}"
network_id = "${cloudstack_network.foo.id}"
template = "%s"
zone = "${cloudstack_network.foo.zone}"
expunge = true
@ -405,12 +405,12 @@ resource "cloudstack_instance" "foobar2" {
resource "cloudstack_loadbalancer_rule" "foo" {
name = "terraform-lb-update"
ip_address = "${cloudstack_ipaddress.foo.ip_address}"
ip_address_id = "${cloudstack_ipaddress.foo.id}"
algorithm = "leastconn"
network = "${cloudstack_network.foo.id}"
network_id = "${cloudstack_network.foo.id}"
public_port = 443
private_port = 443
members = ["${cloudstack_instance.foobar1.id}", "${cloudstack_instance.foobar2.id}"]
member_ids = ["${cloudstack_instance.foobar1.id}", "${cloudstack_instance.foobar2.id}"]
}`,
CLOUDSTACK_VPC_CIDR_1,
CLOUDSTACK_VPC_OFFERING,

View File

@ -68,16 +68,33 @@ func resourceCloudStackNetwork() *schema.Resource {
ForceNew: true,
},
"vpc_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"vpc": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `vpc_id` field instead",
},
"acl_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ConflictsWith: []string{"aclid"},
},
"aclid": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `acl_id` field instead",
},
"project": &schema.Schema{
@ -138,34 +155,34 @@ func resourceCloudStackNetworkCreate(d *schema.ResourceData, meta interface{}) e
}
// Check is this network needs to be created in a VPC
vpc := d.Get("vpc").(string)
if vpc != "" {
vpc, ok := d.GetOk("vpc_id")
if !ok {
vpc, ok = d.GetOk("vpc")
}
if ok {
// Retrieve the vpc ID
vpcid, e := retrieveID(cs, "vpc", vpc)
vpcid, e := retrieveID(cs, "vpc", vpc.(string))
if e != nil {
return e.Error()
}
// Set the vpc ID
// Set the vpcid
p.SetVpcid(vpcid)
// Since we're in a VPC, check if we want to assiciate an ACL list
aclid := d.Get("aclid").(string)
if aclid != "" {
aclid, ok := d.GetOk("acl_id")
if !ok {
aclid, ok = d.GetOk("acl")
}
if ok {
// Set the acl ID
p.SetAclid(aclid)
p.SetAclid(aclid.(string))
}
}
// If there is a project supplied, we retrieve and set the project id
if project, ok := d.GetOk("project"); ok {
// Retrieve the project ID
projectid, e := retrieveID(cs, "project", project.(string))
if e != nil {
return e.Error()
}
// Set the default project ID
p.SetProjectid(projectid)
if err := setProjectid(p, cs, d); err != nil {
return err
}
// Create the new network
@ -205,6 +222,18 @@ func resourceCloudStackNetworkRead(d *schema.ResourceData, meta interface{}) err
d.Set("cidr", n.Cidr)
d.Set("gateway", n.Gateway)
_, vpcID := d.GetOk("vpc_id")
_, vpc := d.GetOk("vpc")
if vpcID || vpc {
d.Set("vpc_id", n.Vpcid)
}
_, aclID := d.GetOk("acl_id")
_, acl := d.GetOk("aclid")
if aclID || acl {
d.Set("acl_id", n.Aclid)
}
// Read the tags and store them in a map
tags := make(map[string]interface{})
for item := range n.Tags {

View File

@ -1,6 +1,7 @@
package cloudstack
import (
"errors"
"fmt"
"log"
"strings"
@ -29,10 +30,18 @@ func resourceCloudStackNetworkACL() *schema.Resource {
ForceNew: true,
},
"vpc_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"vpc": &schema.Schema{
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `vpc_id` field instead",
},
},
}
@ -43,8 +52,16 @@ func resourceCloudStackNetworkACLCreate(d *schema.ResourceData, meta interface{}
name := d.Get("name").(string)
vpc, ok := d.GetOk("vpc_id")
if !ok {
vpc, ok = d.GetOk("vpc")
}
if !ok {
return errors.New("Either `vpc_id` or [deprecated] `vpc` must be provided.")
}
// Retrieve the vpc ID
vpcid, e := retrieveID(cs, "vpc", d.Get("vpc").(string))
vpcid, e := retrieveID(cs, "vpc", vpc.(string))
if e != nil {
return e.Error()
}
@ -88,14 +105,7 @@ func resourceCloudStackNetworkACLRead(d *schema.ResourceData, meta interface{})
d.Set("name", f.Name)
d.Set("description", f.Description)
// Get the VPC details
v, _, err := cs.VPC.GetVPCByID(f.Vpcid)
if err != nil {
return err
}
setValueOrID(d, "vpc", v.Name, v.Id)
d.Set("vpc_id", f.Vpcid)
return nil
}

View File

@ -1,6 +1,7 @@
package cloudstack
import (
"errors"
"fmt"
"strconv"
"strings"
@ -20,10 +21,19 @@ func resourceCloudStackNetworkACLRule() *schema.Resource {
Delete: resourceCloudStackNetworkACLRuleDelete,
Schema: map[string]*schema.Schema{
"acl_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ConflictsWith: []string{"aclid"},
},
"aclid": &schema.Schema{
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `acl_id` field instead",
ConflictsWith: []string{"acl_id"},
},
"managed": &schema.Schema{
@ -109,8 +119,16 @@ func resourceCloudStackNetworkACLRuleCreate(d *schema.ResourceData, meta interfa
return err
}
aclid, ok := d.GetOk("acl_id")
if !ok {
aclid, ok = d.GetOk("aclid")
}
if !ok {
return errors.New("Either `acl_id` or [deprecated] `aclid` must be provided.")
}
// We need to set this upfront in order to be able to save a partial state
d.SetId(d.Get("aclid").(string))
d.SetId(aclid.(string))
// Create all rules that are configured
if nrs := d.Get("rule").(*schema.Set); nrs.Len() > 0 {

View File

@ -219,11 +219,11 @@ resource "cloudstack_vpc" "foobar" {
resource "cloudstack_network_acl" "foo" {
name = "terraform-acl"
description = "terraform-acl-text"
vpc = "${cloudstack_vpc.foobar.id}"
vpc_id = "${cloudstack_vpc.foobar.id}"
}
resource "cloudstack_network_acl_rule" "foo" {
aclid = "${cloudstack_network_acl.foo.id}"
acl_id = "${cloudstack_network_acl.foo.id}"
rule {
action = "allow"
@ -263,11 +263,11 @@ resource "cloudstack_vpc" "foobar" {
resource "cloudstack_network_acl" "foo" {
name = "terraform-acl"
description = "terraform-acl-text"
vpc = "${cloudstack_vpc.foobar.id}"
vpc_id = "${cloudstack_vpc.foobar.id}"
}
resource "cloudstack_network_acl_rule" "foo" {
aclid = "${cloudstack_network_acl.foo.id}"
acl_id = "${cloudstack_network_acl.foo.id}"
rule {
action = "deny"

View File

@ -22,8 +22,6 @@ func TestAccCloudStackNetworkACL_basic(t *testing.T) {
testAccCheckCloudStackNetworkACLExists(
"cloudstack_network_acl.foo", &acl),
testAccCheckCloudStackNetworkACLBasicAttributes(&acl),
resource.TestCheckResourceAttr(
"cloudstack_network_acl.foo", "vpc", "terraform-vpc"),
),
},
},
@ -106,7 +104,7 @@ resource "cloudstack_vpc" "foobar" {
resource "cloudstack_network_acl" "foo" {
name = "terraform-acl"
description = "terraform-acl-text"
vpc = "${cloudstack_vpc.foobar.name}"
vpc_id = "${cloudstack_vpc.foobar.id}"
}`,
CLOUDSTACK_VPC_CIDR_1,
CLOUDSTACK_VPC_OFFERING,

View File

@ -44,8 +44,6 @@ func TestAccCloudStackNetwork_vpc(t *testing.T) {
testAccCheckCloudStackNetworkExists(
"cloudstack_network.foo", &network),
testAccCheckCloudStackNetworkVPCAttributes(&network),
resource.TestCheckResourceAttr(
"cloudstack_network.foo", "vpc", "terraform-vpc"),
),
},
},
@ -187,7 +185,7 @@ resource "cloudstack_network" "foo" {
name = "terraform-network"
cidr = "%s"
network_offering = "%s"
vpc = "${cloudstack_vpc.foobar.name}"
vpc_id = "${cloudstack_vpc.foobar.id}"
zone = "${cloudstack_vpc.foobar.zone}"
}`,
CLOUDSTACK_VPC_CIDR_1,

View File

@ -1,6 +1,7 @@
package cloudstack
import (
"errors"
"fmt"
"log"
"strings"
@ -16,10 +17,18 @@ func resourceCloudStackNIC() *schema.Resource {
Delete: resourceCloudStackNICDelete,
Schema: map[string]*schema.Schema{
"network_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"network": &schema.Schema{
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `network_id` field instead",
},
"ip_address": &schema.Schema{
@ -32,15 +41,22 @@ func resourceCloudStackNIC() *schema.Resource {
"ipaddress": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
Deprecated: "Please use the `ip_address` field instead",
},
"virtual_machine_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"virtual_machine": &schema.Schema{
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `virtual_machine_id` field instead",
},
},
}
@ -49,14 +65,31 @@ func resourceCloudStackNIC() *schema.Resource {
func resourceCloudStackNICCreate(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)
network, ok := d.GetOk("network_id")
if !ok {
network, ok = d.GetOk("network")
}
if !ok {
return errors.New("Either `network_id` or [deprecated] `network` must be provided.")
}
// Retrieve the network ID
networkid, e := retrieveID(cs, "network", d.Get("network").(string))
networkid, e := retrieveID(cs, "network", network.(string))
if e != nil {
return e.Error()
}
virtualmachine, ok := d.GetOk("virtual_machine_id")
if !ok {
virtualmachine, ok = d.GetOk("virtual_machine")
}
if !ok {
return errors.New(
"Either `virtual_machine_id` or [deprecated] `virtual_machine` must be provided.")
}
// Retrieve the virtual_machine ID
virtualmachineid, e := retrieveID(cs, "virtual_machine", d.Get("virtual_machine").(string))
virtualmachineid, e := retrieveID(cs, "virtual_machine", virtualmachine.(string))
if e != nil {
return e.Error()
}
@ -89,7 +122,7 @@ func resourceCloudStackNICCreate(d *schema.ResourceData, meta interface{}) error
}
if !found {
return fmt.Errorf("Could not find NIC ID for network: %s", d.Get("network").(string))
return fmt.Errorf("Could not find NIC ID for network ID: %s", networkid)
}
return resourceCloudStackNICRead(d, meta)
@ -98,8 +131,23 @@ func resourceCloudStackNICCreate(d *schema.ResourceData, meta interface{}) error
func resourceCloudStackNICRead(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)
virtualmachine, ok := d.GetOk("virtual_machine_id")
if !ok {
virtualmachine, ok = d.GetOk("virtual_machine")
}
if !ok {
return errors.New(
"Either `virtual_machine_id` or [deprecated] `virtual_machine` must be provided.")
}
// Retrieve the virtual_machine ID
virtualmachineid, e := retrieveID(cs, "virtual_machine", virtualmachine.(string))
if e != nil {
return e.Error()
}
// Get the virtual machine details
vm, count, err := cs.VirtualMachine.GetVirtualMachineByName(d.Get("virtual_machine").(string))
vm, count, err := cs.VirtualMachine.GetVirtualMachineByID(virtualmachineid)
if err != nil {
if count == 0 {
log.Printf("[DEBUG] Instance %s does no longer exist", d.Get("virtual_machine").(string))
@ -115,15 +163,15 @@ func resourceCloudStackNICRead(d *schema.ResourceData, meta interface{}) error {
for _, n := range vm.Nic {
if n.Id == d.Id() {
d.Set("ip_address", n.Ipaddress)
setValueOrID(d, "network", n.Networkname, n.Networkid)
setValueOrID(d, "virtual_machine", vm.Name, vm.Id)
d.Set("network_id", n.Networkid)
d.Set("virtual_machine_id", vm.Id)
found = true
break
}
}
if !found {
log.Printf("[DEBUG] NIC for network %s does no longer exist", d.Get("network").(string))
log.Printf("[DEBUG] NIC for network ID %s does no longer exist", d.Get("network_id").(string))
d.SetId("")
}
@ -133,8 +181,17 @@ func resourceCloudStackNICRead(d *schema.ResourceData, meta interface{}) error {
func resourceCloudStackNICDelete(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)
virtualmachine, ok := d.GetOk("virtual_machine_id")
if !ok {
virtualmachine, ok = d.GetOk("virtual_machine")
}
if !ok {
return errors.New(
"Either `virtual_machine_id` or [deprecated] `virtual_machine` must be provided.")
}
// Retrieve the virtual_machine ID
virtualmachineid, e := retrieveID(cs, "virtual_machine", d.Get("virtual_machine").(string))
virtualmachineid, e := retrieveID(cs, "virtual_machine", virtualmachine.(string))
if e != nil {
return e.Error()
}

View File

@ -103,8 +103,8 @@ func testAccCheckCloudStackNICAttributes(
nic *cloudstack.Nic) resource.TestCheckFunc {
return func(s *terraform.State) error {
if nic.Networkname != CLOUDSTACK_2ND_NIC_NETWORK {
return fmt.Errorf("Bad network: %s", nic.Networkname)
if nic.Networkid != CLOUDSTACK_2ND_NIC_NETWORK {
return fmt.Errorf("Bad network ID: %s", nic.Networkid)
}
return nil
@ -115,8 +115,8 @@ func testAccCheckCloudStackNICIPAddress(
nic *cloudstack.Nic) resource.TestCheckFunc {
return func(s *terraform.State) error {
if nic.Networkname != CLOUDSTACK_2ND_NIC_NETWORK {
return fmt.Errorf("Bad network: %s", nic.Networkname)
if nic.Networkid != CLOUDSTACK_2ND_NIC_NETWORK {
return fmt.Errorf("Bad network ID: %s", nic.Networkname)
}
if nic.Ipaddress != CLOUDSTACK_2ND_NIC_IPADDRESS {
@ -154,15 +154,15 @@ resource "cloudstack_instance" "foobar" {
name = "terraform-test"
display_name = "terraform"
service_offering= "%s"
network = "%s"
network_id = "%s"
template = "%s"
zone = "%s"
expunge = true
}
resource "cloudstack_nic" "foo" {
network = "%s"
virtual_machine = "${cloudstack_instance.foobar.name}"
network_id = "%s"
virtual_machine_id = "${cloudstack_instance.foobar.id}"
}`,
CLOUDSTACK_SERVICE_OFFERING_1,
CLOUDSTACK_NETWORK_1,
@ -175,16 +175,16 @@ resource "cloudstack_instance" "foobar" {
name = "terraform-test"
display_name = "terraform"
service_offering= "%s"
network = "%s"
network_id = "%s"
template = "%s"
zone = "%s"
expunge = true
}
resource "cloudstack_nic" "foo" {
network = "%s"
network_id = "%s"
ip_address = "%s"
virtual_machine = "${cloudstack_instance.foobar.name}"
virtual_machine_id = "${cloudstack_instance.foobar.id}"
}`,
CLOUDSTACK_SERVICE_OFFERING_1,
CLOUDSTACK_NETWORK_1,

View File

@ -22,7 +22,7 @@ func resourceCloudStackPortForward() *schema.Resource {
Delete: resourceCloudStackPortForwardDelete,
Schema: map[string]*schema.Schema{
"ip_address": &schema.Schema{
"ip_address_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
@ -33,8 +33,8 @@ func resourceCloudStackPortForward() *schema.Resource {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `ip_address` field instead",
ConflictsWith: []string{"ip_address"},
Deprecated: "Please use the `ip_address_id` field instead",
ConflictsWith: []string{"ip_address_id"},
},
"managed": &schema.Schema{
@ -69,9 +69,15 @@ func resourceCloudStackPortForward() *schema.Resource {
Required: true,
},
"virtual_machine_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"virtual_machine": &schema.Schema{
Type: schema.TypeString,
Required: true,
Optional: true,
Deprecated: "Please use the `virtual_machine_id` field instead",
},
"uuid": &schema.Schema{
@ -88,12 +94,12 @@ func resourceCloudStackPortForward() *schema.Resource {
func resourceCloudStackPortForwardCreate(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)
ipaddress, ok := d.GetOk("ip_address")
ipaddress, ok := d.GetOk("ip_address_id")
if !ok {
ipaddress, ok = d.GetOk("ipaddress")
}
if !ok {
return errors.New("Either `ip_address` or [deprecated] `ipaddress` must be provided.")
return errors.New("Either `ip_address_id` or [deprecated] `ipaddress` must be provided.")
}
// Retrieve the ipaddress ID
@ -173,8 +179,17 @@ func createPortForward(
return err
}
virtualmachine, ok := forward["virtual_machine_id"]
if !ok {
virtualmachine, ok = forward["virtual_machine"]
}
if !ok {
return errors.New(
"Either `virtual_machine_id` or [deprecated] `virtual_machine` must be provided.")
}
// Retrieve the virtual_machine ID
virtualmachineid, e := retrieveID(cs, "virtual_machine", forward["virtual_machine"].(string))
virtualmachineid, e := retrieveID(cs, "virtual_machine", virtualmachine.(string))
if e != nil {
return e.Error()
}
@ -265,12 +280,7 @@ func resourceCloudStackPortForwardRead(d *schema.ResourceData, meta interface{})
forward["protocol"] = f.Protocol
forward["private_port"] = privPort
forward["public_port"] = pubPort
if isID(forward["virtual_machine"].(string)) {
forward["virtual_machine"] = f.Virtualmachineid
} else {
forward["virtual_machine"] = f.Virtualmachinename
}
forward["virtual_machine_id"] = f.Virtualmachineid
forwards.Add(forward)
}
@ -285,7 +295,7 @@ func resourceCloudStackPortForwardRead(d *schema.ResourceData, meta interface{})
"protocol": uuid,
"private_port": 0,
"public_port": 0,
"virtual_machine": uuid,
"virtual_machine_id": uuid,
"uuid": uuid,
}

View File

@ -21,15 +21,9 @@ func TestAccCloudStackPortForward_basic(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudStackPortForwardsExist("cloudstack_port_forward.foo"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "ip_address", CLOUDSTACK_PUBLIC_IPADDRESS),
"cloudstack_port_forward.foo", "ip_address_id", CLOUDSTACK_PUBLIC_IPADDRESS),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.952396423.protocol", "tcp"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.952396423.private_port", "443"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.952396423.public_port", "8443"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.952396423.virtual_machine", "terraform-test"),
"cloudstack_port_forward.foo", "forward.#", "1"),
),
},
},
@ -47,17 +41,9 @@ func TestAccCloudStackPortForward_update(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudStackPortForwardsExist("cloudstack_port_forward.foo"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "ip_address", CLOUDSTACK_PUBLIC_IPADDRESS),
"cloudstack_port_forward.foo", "ip_address_id", CLOUDSTACK_PUBLIC_IPADDRESS),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.#", "1"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.952396423.protocol", "tcp"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.952396423.private_port", "443"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.952396423.public_port", "8443"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.952396423.virtual_machine", "terraform-test"),
),
},
@ -66,25 +52,9 @@ func TestAccCloudStackPortForward_update(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudStackPortForwardsExist("cloudstack_port_forward.foo"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "ip_address", CLOUDSTACK_PUBLIC_IPADDRESS),
"cloudstack_port_forward.foo", "ip_address_id", CLOUDSTACK_PUBLIC_IPADDRESS),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.#", "2"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.260687715.protocol", "tcp"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.260687715.private_port", "80"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.260687715.public_port", "8080"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.260687715.virtual_machine", "terraform-test"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.952396423.protocol", "tcp"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.952396423.private_port", "443"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.952396423.public_port", "8443"),
resource.TestCheckResourceAttr(
"cloudstack_port_forward.foo", "forward.952396423.virtual_machine", "terraform-test"),
),
},
},
@ -161,13 +131,13 @@ resource "cloudstack_instance" "foobar" {
}
resource "cloudstack_port_forward" "foo" {
ip_address = "%s"
ip_address_id = "%s"
forward {
protocol = "tcp"
private_port = 443
public_port = 8443
virtual_machine = "${cloudstack_instance.foobar.name}"
virtual_machine_id = "${cloudstack_instance.foobar.id}"
}
}`,
CLOUDSTACK_SERVICE_OFFERING_1,
@ -187,20 +157,20 @@ resource "cloudstack_instance" "foobar" {
}
resource "cloudstack_port_forward" "foo" {
ip_address = "%s"
ip_address_id = "%s"
forward {
protocol = "tcp"
private_port = 443
public_port = 8443
virtual_machine = "${cloudstack_instance.foobar.name}"
virtual_machine_id = "${cloudstack_instance.foobar.id}"
}
forward {
protocol = "tcp"
private_port = 80
public_port = 8080
virtual_machine = "${cloudstack_instance.foobar.name}"
virtual_machine_id = "${cloudstack_instance.foobar.id}"
}
}`,
CLOUDSTACK_SERVICE_OFFERING_1,

View File

@ -1,6 +1,7 @@
package cloudstack
import (
"errors"
"fmt"
"log"
"strings"
@ -26,12 +27,25 @@ func resourceCloudStackSecondaryIPAddress() *schema.Resource {
"ipaddress": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
Deprecated: "Please use the `ip_address` field instead",
},
"nic_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"nicid": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `nic_id` field instead",
},
"virtual_machine_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
@ -40,8 +54,9 @@ func resourceCloudStackSecondaryIPAddress() *schema.Resource {
"virtual_machine": &schema.Schema{
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `virtual_machine_id` field instead",
},
},
}
@ -50,10 +65,22 @@ func resourceCloudStackSecondaryIPAddress() *schema.Resource {
func resourceCloudStackSecondaryIPAddressCreate(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)
nicid := d.Get("nicid").(string)
if nicid == "" {
nicid, ok := d.GetOk("nic_id")
if !ok {
nicid, ok = d.GetOk("nicid")
}
if !ok {
virtualmachine, ok := d.GetOk("virtual_machine_id")
if !ok {
virtualmachine, ok = d.GetOk("virtual_machine")
}
if !ok {
return errors.New(
"Either `virtual_machine_id` or [deprecated] `virtual_machine` must be provided.")
}
// Retrieve the virtual_machine ID
virtualmachineid, e := retrieveID(cs, "virtual_machine", d.Get("virtual_machine").(string))
virtualmachineid, e := retrieveID(cs, "virtual_machine", virtualmachine.(string))
if e != nil {
return e.Error()
}
@ -62,7 +89,7 @@ func resourceCloudStackSecondaryIPAddressCreate(d *schema.ResourceData, meta int
vm, count, err := cs.VirtualMachine.GetVirtualMachineByID(virtualmachineid)
if err != nil {
if count == 0 {
log.Printf("[DEBUG] Instance %s does no longer exist", d.Get("virtual_machine").(string))
log.Printf("[DEBUG] Virtual Machine %s does no longer exist", virtualmachineid)
d.SetId("")
return nil
}
@ -73,7 +100,7 @@ func resourceCloudStackSecondaryIPAddressCreate(d *schema.ResourceData, meta int
}
// Create a new parameter struct
p := cs.Nic.NewAddIpToNicParams(nicid)
p := cs.Nic.NewAddIpToNicParams(nicid.(string))
// If there is a ipaddres supplied, add it to the parameter struct
ipaddress, ok := d.GetOk("ip_address")
@ -97,8 +124,17 @@ func resourceCloudStackSecondaryIPAddressCreate(d *schema.ResourceData, meta int
func resourceCloudStackSecondaryIPAddressRead(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)
virtualmachine, ok := d.GetOk("virtual_machine_id")
if !ok {
virtualmachine, ok = d.GetOk("virtual_machine")
}
if !ok {
return errors.New(
"Either `virtual_machine_id` or [deprecated] `virtual_machine` must be provided.")
}
// Retrieve the virtual_machine ID
virtualmachineid, e := retrieveID(cs, "virtual_machine", d.Get("virtual_machine").(string))
virtualmachineid, e := retrieveID(cs, "virtual_machine", virtualmachine.(string))
if e != nil {
return e.Error()
}
@ -107,20 +143,23 @@ func resourceCloudStackSecondaryIPAddressRead(d *schema.ResourceData, meta inter
vm, count, err := cs.VirtualMachine.GetVirtualMachineByID(virtualmachineid)
if err != nil {
if count == 0 {
log.Printf("[DEBUG] Instance %s does no longer exist", d.Get("virtual_machine").(string))
log.Printf("[DEBUG] Virtual Machine %s does no longer exist", virtualmachineid)
d.SetId("")
return nil
}
return err
}
nicid := d.Get("nicid").(string)
if nicid == "" {
nicid, ok := d.GetOk("nic_id")
if !ok {
nicid, ok = d.GetOk("nicid")
}
if !ok {
nicid = vm.Nic[0].Id
}
p := cs.Nic.NewListNicsParams(virtualmachineid)
p.SetNicid(nicid)
p.SetNicid(nicid.(string))
l, err := cs.Nic.ListNics(p)
if err != nil {
@ -140,7 +179,8 @@ func resourceCloudStackSecondaryIPAddressRead(d *schema.ResourceData, meta inter
for _, ip := range l.Nics[0].Secondaryip {
if ip.Id == d.Id() {
d.Set("ip_address", ip.Ipaddress)
d.Set("nicid", l.Nics[0].Id)
d.Set("nic_id", l.Nics[0].Id)
d.Set("virtual_machine_id", l.Nics[0].Virtualmachineid)
return nil
}
}

View File

@ -64,9 +64,13 @@ func testAccCheckCloudStackSecondaryIPAddressExists(
cs := testAccProvider.Meta().(*cloudstack.CloudStackClient)
virtualmachine, ok := rs.Primary.Attributes["virtual_machine_id"]
if !ok {
virtualmachine, ok = rs.Primary.Attributes["virtual_machine"]
}
// Retrieve the virtual_machine ID
virtualmachineid, e := retrieveID(
cs, "virtual_machine", rs.Primary.Attributes["virtual_machine"])
virtualmachineid, e := retrieveID(cs, "virtual_machine", virtualmachine)
if e != nil {
return e.Error()
}
@ -80,8 +84,11 @@ func testAccCheckCloudStackSecondaryIPAddressExists(
return err
}
nicid := rs.Primary.Attributes["nicid"]
if nicid == "" {
nicid, ok := rs.Primary.Attributes["nic_id"]
if !ok {
nicid, ok = rs.Primary.Attributes["nicid"]
}
if !ok {
nicid = vm.Nic[0].Id
}
@ -136,9 +143,13 @@ func testAccCheckCloudStackSecondaryIPAddressDestroy(s *terraform.State) error {
return fmt.Errorf("No IP address ID is set")
}
virtualmachine, ok := rs.Primary.Attributes["virtual_machine_id"]
if !ok {
virtualmachine, ok = rs.Primary.Attributes["virtual_machine"]
}
// Retrieve the virtual_machine ID
virtualmachineid, e := retrieveID(
cs, "virtual_machine", rs.Primary.Attributes["virtual_machine"])
virtualmachineid, e := retrieveID(cs, "virtual_machine", virtualmachine)
if e != nil {
return e.Error()
}
@ -152,8 +163,11 @@ func testAccCheckCloudStackSecondaryIPAddressDestroy(s *terraform.State) error {
return err
}
nicid := rs.Primary.Attributes["nicid"]
if nicid == "" {
nicid, ok := rs.Primary.Attributes["nic_id"]
if !ok {
nicid, ok = rs.Primary.Attributes["nicid"]
}
if !ok {
nicid = vm.Nic[0].Id
}
@ -189,14 +203,14 @@ var testAccCloudStackSecondaryIPAddress_basic = fmt.Sprintf(`
resource "cloudstack_instance" "foobar" {
name = "terraform-test"
service_offering= "%s"
network = "%s"
network_id = "%s"
template = "%s"
zone = "%s"
expunge = true
}
resource "cloudstack_secondary_ipaddress" "foo" {
virtual_machine = "${cloudstack_instance.foobar.id}"
virtual_machine_id = "${cloudstack_instance.foobar.id}"
}
`,
CLOUDSTACK_SERVICE_OFFERING_1,
@ -208,7 +222,7 @@ var testAccCloudStackSecondaryIPAddress_fixedIP = fmt.Sprintf(`
resource "cloudstack_instance" "foobar" {
name = "terraform-test"
service_offering= "%s"
network = "%s"
network_id = "%s"
template = "%s"
zone = "%s"
expunge = true
@ -216,7 +230,7 @@ resource "cloudstack_instance" "foobar" {
resource "cloudstack_secondary_ipaddress" "foo" {
ip_address = "%s"
virtual_machine = "${cloudstack_instance.foobar.id}"
virtual_machine_id = "${cloudstack_instance.foobar.id}"
}`,
CLOUDSTACK_SERVICE_OFFERING_1,
CLOUDSTACK_NETWORK_1,

View File

@ -63,6 +63,7 @@ func resourceCloudStackSSHKeyPairCreate(d *schema.ResourceData, meta interface{}
p := cs.SSH.NewRegisterSSHKeyPairParams(name, string(key))
// If there is a project supplied, we retrieve and set the project id
if err := setProjectid(p, cs, d); err != nil {
return err
}
@ -75,6 +76,7 @@ func resourceCloudStackSSHKeyPairCreate(d *schema.ResourceData, meta interface{}
// No key supplied, must create one and return the private key
p := cs.SSH.NewCreateSSHKeyPairParams(name)
// If there is a project supplied, we retrieve and set the project id
if err := setProjectid(p, cs, d); err != nil {
return err
}
@ -100,6 +102,7 @@ func resourceCloudStackSSHKeyPairRead(d *schema.ResourceData, meta interface{})
p := cs.SSH.NewListSSHKeyPairsParams()
p.SetName(d.Id())
// If there is a project supplied, we retrieve and set the project id
if err := setProjectid(p, cs, d); err != nil {
return err
}
@ -127,6 +130,7 @@ func resourceCloudStackSSHKeyPairDelete(d *schema.ResourceData, meta interface{}
// Create a new parameter struct
p := cs.SSH.NewDeleteSSHKeyPairParams(d.Id())
// If there is a project supplied, we retrieve and set the project id
if err := setProjectid(p, cs, d); err != nil {
return err
}

View File

@ -146,14 +146,13 @@ func testAccCheckCloudStackSSHKeyPairDestroy(s *terraform.State) error {
if err != nil {
return err
}
if list.Count != 1 {
return fmt.Errorf("Found more Key pair %s still exists", rs.Primary.ID)
}
if list.SSHKeyPairs[0].Name == rs.Primary.ID {
for _, keyPair := range list.SSHKeyPairs {
if keyPair.Name == rs.Primary.ID {
return fmt.Errorf("Key pair %s still exists", rs.Primary.ID)
}
}
}
return nil
}

View File

@ -17,20 +17,20 @@ func resourceCloudStackStaticNAT() *schema.Resource {
Delete: resourceCloudStackStaticNATDelete,
Schema: map[string]*schema.Schema{
"ipaddress": &schema.Schema{
"ip_address_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"network": &schema.Schema{
"network_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"virtual_machine": &schema.Schema{
"virtual_machine_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
@ -49,29 +49,14 @@ func resourceCloudStackStaticNAT() *schema.Resource {
func resourceCloudStackStaticNATCreate(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)
// Retrieve the ipaddress ID
ipaddressid, e := retrieveID(cs, "ipaddress", d.Get("ipaddress").(string))
if e != nil {
return e.Error()
}
// Retrieve the virtual_machine ID
virtualmachineid, e := retrieveID(cs, "virtual_machine", d.Get("virtual_machine").(string))
if e != nil {
return e.Error()
}
ipaddressid := d.Get("ip_address_id").(string)
virtualmachineid := d.Get("virtual_machine_id").(string)
// Create a new parameter struct
p := cs.NAT.NewEnableStaticNatParams(ipaddressid, virtualmachineid)
if network, ok := d.GetOk("network"); ok {
// Retrieve the network ID
networkid, e := retrieveID(cs, "network", network.(string))
if e != nil {
return e.Error()
}
p.SetNetworkid(networkid)
if networkid, ok := d.GetOk("network_id"); ok {
p.SetNetworkid(networkid.(string))
}
if vmGuestIP, ok := d.GetOk("vm_guest_ip"); ok {
@ -126,8 +111,8 @@ func resourceCloudStackStaticNATRead(d *schema.ResourceData, meta interface{}) e
return nil
}
setValueOrID(d, "network", ip.Associatednetworkname, ip.Associatednetworkid)
setValueOrID(d, "virtual_machine", ip.Virtualmachinename, ip.Virtualmachineid)
d.Set("network_id", ip.Associatednetworkid)
d.Set("virtual_machine_id", ip.Virtualmachineid)
d.Set("vm_guest_ip", ip.Vmipaddress)
return nil

View File

@ -66,12 +66,8 @@ func testAccCheckCloudStackStaticNATAttributes(
ipaddr *cloudstack.PublicIpAddress) resource.TestCheckFunc {
return func(s *terraform.State) error {
if ipaddr.Associatednetworkname != CLOUDSTACK_NETWORK_1 {
return fmt.Errorf("Bad network: %s", ipaddr.Associatednetworkname)
}
if ipaddr.Virtualmachinename != "terraform-test" {
return fmt.Errorf("Bad virtual_machine: %s", ipaddr.Virtualmachinename)
if ipaddr.Associatednetworkid != CLOUDSTACK_NETWORK_1 {
return fmt.Errorf("Bad network ID: %s", ipaddr.Associatednetworkid)
}
return nil
@ -104,7 +100,7 @@ resource "cloudstack_instance" "foobar" {
name = "terraform-test"
display_name = "terraform-test"
service_offering= "%s"
network = "%s"
network_id = "%s"
template = "%s"
zone = "%s"
user_data = "foobar\nfoo\nbar"
@ -112,17 +108,16 @@ resource "cloudstack_instance" "foobar" {
}
resource "cloudstack_ipaddress" "foo" {
network = "%s"
network_id = "${cloudstack_instance.foobar.network_id}"
}
resource "cloudstack_static_nat" "foo" {
ipaddress = "${cloudstack_ipaddress.foo.id}"
network = "${cloudstack_ipaddress.foo.network}"
virtual_machine = "${cloudstack_instance.foobar.id}"
ip_address_id = "${cloudstack_ipaddress.foo.id}"
network_id = "${cloudstack_ipaddress.foo.network_id}"
virtual_machine_id = "${cloudstack_instance.foobar.id}"
}`,
CLOUDSTACK_SERVICE_OFFERING_1,
CLOUDSTACK_NETWORK_1,
CLOUDSTACK_TEMPLATE,
CLOUDSTACK_ZONE,
CLOUDSTACK_NETWORK_1,
)

View File

@ -168,14 +168,8 @@ func resourceCloudStackTemplateCreate(d *schema.ResourceData, meta interface{})
}
// If there is a project supplied, we retrieve and set the project id
if project, ok := d.GetOk("project"); ok {
// Retrieve the project ID
projectid, e := retrieveID(cs, "project", project.(string))
if e != nil {
return e.Error()
}
// Set the default project ID
p.SetProjectid(projectid)
if err := setProjectid(p, cs, d); err != nil {
return err
}
// Create the new template

View File

@ -106,14 +106,8 @@ func resourceCloudStackVPCCreate(d *schema.ResourceData, meta interface{}) error
}
// If there is a project supplied, we retrieve and set the project id
if project, ok := d.GetOk("project"); ok {
// Retrieve the project ID
projectid, e := retrieveID(cs, "project", project.(string))
if e != nil {
return e.Error()
}
// Set the default project ID
p.SetProjectid(projectid)
if err := setProjectid(p, cs, d); err != nil {
return err
}
// Create the new VPC
@ -163,8 +157,9 @@ func resourceCloudStackVPCRead(d *schema.ResourceData, meta interface{}) error {
p.SetVpcid(d.Id())
p.SetIssourcenat(true)
if _, ok := d.GetOk("project"); ok {
p.SetProjectid(v.Projectid)
// If there is a project supplied, we retrieve and set the project id
if err := setProjectid(p, cs, d); err != nil {
return err
}
// Get the source NAT IP assigned to the VPC

View File

@ -1,6 +1,7 @@
package cloudstack
import (
"errors"
"fmt"
"log"
"strings"
@ -16,16 +17,32 @@ func resourceCloudStackVPNConnection() *schema.Resource {
Delete: resourceCloudStackVPNConnectionDelete,
Schema: map[string]*schema.Schema{
"customer_gateway_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"customergatewayid": &schema.Schema{
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `customer_gateway_id` field instead",
},
"vpn_gateway_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"vpngatewayid": &schema.Schema{
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `vpn_gateway_id` field instead",
},
},
}
@ -34,10 +51,27 @@ func resourceCloudStackVPNConnection() *schema.Resource {
func resourceCloudStackVPNConnectionCreate(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)
customergatewayid, ok := d.GetOk("customer_gateway_id")
if !ok {
customergatewayid, ok = d.GetOk("customergatewayid")
}
if !ok {
return errors.New(
"Either `customer_gateway_id` or [deprecated] `customergatewayid` must be provided.")
}
vpngatewayid, ok := d.GetOk("vpn_gateway_id")
if !ok {
vpngatewayid, ok = d.GetOk("vpngatewayid")
}
if !ok {
return errors.New("Either `vpn_gateway_id` or [deprecated] `vpngatewayid` must be provided.")
}
// Create a new parameter struct
p := cs.VPN.NewCreateVpnConnectionParams(
d.Get("customergatewayid").(string),
d.Get("vpngatewayid").(string),
customergatewayid.(string),
vpngatewayid.(string),
)
// Create the new VPN Connection
@ -66,8 +100,8 @@ func resourceCloudStackVPNConnectionRead(d *schema.ResourceData, meta interface{
return err
}
d.Set("customergatewayid", v.S2scustomergatewayid)
d.Set("vpngatewayid", v.S2svpngatewayid)
d.Set("customer_gateway_id", v.S2scustomergatewayid)
d.Set("vpn_gateway_id", v.S2svpngatewayid)
return nil
}

View File

@ -96,11 +96,11 @@ resource "cloudstack_vpc" "bar" {
}
resource "cloudstack_vpn_gateway" "foo" {
vpc = "${cloudstack_vpc.foo.name}"
vpc_id = "${cloudstack_vpc.foo.id}"
}
resource "cloudstack_vpn_gateway" "bar" {
vpc = "${cloudstack_vpc.bar.name}"
vpc_id = "${cloudstack_vpc.bar.id}"
}
resource "cloudstack_vpn_customer_gateway" "foo" {
@ -122,13 +122,13 @@ resource "cloudstack_vpn_customer_gateway" "bar" {
}
resource "cloudstack_vpn_connection" "foo-bar" {
customergatewayid = "${cloudstack_vpn_customer_gateway.foo.id}"
vpngatewayid = "${cloudstack_vpn_gateway.bar.id}"
customer_gateway_id = "${cloudstack_vpn_customer_gateway.foo.id}"
vpn_gateway_id = "${cloudstack_vpn_gateway.bar.id}"
}
resource "cloudstack_vpn_connection" "bar-foo" {
customergatewayid = "${cloudstack_vpn_customer_gateway.bar.id}"
vpngatewayid = "${cloudstack_vpn_gateway.foo.id}"
customer_gateway_id = "${cloudstack_vpn_customer_gateway.bar.id}"
vpn_gateway_id = "${cloudstack_vpn_gateway.foo.id}"
}`,
CLOUDSTACK_VPC_CIDR_1,
CLOUDSTACK_VPC_OFFERING,

View File

@ -188,11 +188,11 @@ resource "cloudstack_vpc" "bar" {
}
resource "cloudstack_vpn_gateway" "foo" {
vpc = "${cloudstack_vpc.foo.name}"
vpc_id = "${cloudstack_vpc.foo.id}"
}
resource "cloudstack_vpn_gateway" "bar" {
vpc = "${cloudstack_vpc.bar.name}"
vpc_id = "${cloudstack_vpc.bar.id}"
}
resource "cloudstack_vpn_customer_gateway" "foo" {
@ -235,11 +235,11 @@ resource "cloudstack_vpc" "bar" {
}
resource "cloudstack_vpn_gateway" "foo" {
vpc = "${cloudstack_vpc.foo.name}"
vpc_id = "${cloudstack_vpc.foo.id}"
}
resource "cloudstack_vpn_gateway" "bar" {
vpc = "${cloudstack_vpc.bar.name}"
vpc_id = "${cloudstack_vpc.bar.id}"
}
resource "cloudstack_vpn_customer_gateway" "foo" {

View File

@ -1,6 +1,7 @@
package cloudstack
import (
"errors"
"fmt"
"log"
"strings"
@ -16,10 +17,18 @@ func resourceCloudStackVPNGateway() *schema.Resource {
Delete: resourceCloudStackVPNGatewayDelete,
Schema: map[string]*schema.Schema{
"vpc_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"vpc": &schema.Schema{
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `vpc_id` field instead",
},
"public_ip": &schema.Schema{
@ -33,8 +42,16 @@ func resourceCloudStackVPNGateway() *schema.Resource {
func resourceCloudStackVPNGatewayCreate(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)
vpc, ok := d.GetOk("vpc_id")
if !ok {
vpc, ok = d.GetOk("vpc")
}
if !ok {
return errors.New("Either `vpc_id` or [deprecated] `vpc` must be provided.")
}
// Retrieve the VPC ID
vpcid, e := retrieveID(cs, "vpc", d.Get("vpc").(string))
vpcid, e := retrieveID(cs, "vpc", vpc.(string))
if e != nil {
return e.Error()
}
@ -45,7 +62,7 @@ func resourceCloudStackVPNGatewayCreate(d *schema.ResourceData, meta interface{}
// Create the new VPN Gateway
v, err := cs.VPN.CreateVpnGateway(p)
if err != nil {
return fmt.Errorf("Error creating VPN Gateway for VPC %s: %s", d.Get("vpc").(string), err)
return fmt.Errorf("Error creating VPN Gateway for VPC ID %s: %s", vpcid, err)
}
d.SetId(v.Id)
@ -61,7 +78,7 @@ func resourceCloudStackVPNGatewayRead(d *schema.ResourceData, meta interface{})
if err != nil {
if count == 0 {
log.Printf(
"[DEBUG] VPN Gateway for VPC %s does no longer exist", d.Get("vpc").(string))
"[DEBUG] VPN Gateway for VPC ID %s does no longer exist", d.Get("vpc_id").(string))
d.SetId("")
return nil
}
@ -69,8 +86,7 @@ func resourceCloudStackVPNGatewayRead(d *schema.ResourceData, meta interface{})
return err
}
setValueOrID(d, "vpc", d.Get("vpc").(string), v.Vpcid)
d.Set("vpc_id", v.Vpcid)
d.Set("public_ip", v.Publicip)
return nil
@ -92,7 +108,7 @@ func resourceCloudStackVPNGatewayDelete(d *schema.ResourceData, meta interface{}
return nil
}
return fmt.Errorf("Error deleting VPN Gateway for VPC %s: %s", d.Get("vpc").(string), err)
return fmt.Errorf("Error deleting VPN Gateway for VPC %s: %s", d.Get("vpc_id").(string), err)
}
return nil

View File

@ -22,8 +22,6 @@ func TestAccCloudStackVPNGateway_basic(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudStackVPNGatewayExists(
"cloudstack_vpn_gateway.foo", &vpnGateway),
resource.TestCheckResourceAttr(
"cloudstack_vpn_gateway.foo", "vpc", "terraform-vpc"),
),
},
},
@ -90,7 +88,7 @@ resource "cloudstack_vpc" "foo" {
}
resource "cloudstack_vpn_gateway" "foo" {
vpc = "${cloudstack_vpc.foo.name}"
vpc_id = "${cloudstack_vpc.foo.id}"
}`,
CLOUDSTACK_VPC_CIDR_1,
CLOUDSTACK_VPC_OFFERING,

View File

@ -14,7 +14,7 @@ Creates egress firewall rules for a given network.
```
resource "cloudstack_egress_firewall" "default" {
network = "test-network"
network_id = "6eb22f91-7454-4107-89f4-36afcdf33021"
rule {
cidr_list = ["10.0.0.0/8"]
@ -28,8 +28,11 @@ resource "cloudstack_egress_firewall" "default" {
The following arguments are supported:
* `network` - (Required) The network for which to create the egress firewall
rules. Changing this forces a new resource to be created.
* `network_id` - (Required) The network ID for which to create the egress
firewall rules. Changing this forces a new resource to be created.
* `network` - (Required, Deprecated) The network for which to create the egress
firewall rules. Changing this forces a new resource to be created.
* `managed` - (Optional) USE WITH CAUTION! If enabled all the egress firewall
rules for this network will be managed by this resource. This means it will

View File

@ -14,7 +14,7 @@ Creates firewall rules for a given IP address.
```
resource "cloudstack_firewall" "default" {
ip_address = "192.168.0.1"
ip_address_id = "30b21801-d4b3-4174-852b-0c0f30bdbbfb"
rule {
cidr_list = ["10.0.0.0/8"]
@ -28,8 +28,8 @@ resource "cloudstack_firewall" "default" {
The following arguments are supported:
* `ip_address` - (Required) The IP address or ID for which to create the firewall
rules. Changing this forces a new resource to be created.
* `ip_address_id` - (Required) The IP address ID for which to create the
firewall rules. Changing this forces a new resource to be created.
* `ipaddress` - (Required, Deprecated) The IP address or ID for which to create
the firewall rules. Changing this forces a new resource to be created.

View File

@ -17,7 +17,7 @@ disk offering, and template.
resource "cloudstack_instance" "web" {
name = "server-1"
service_offering= "small"
network = "network-1"
network_id = "6eb22f91-7454-4107-89f4-36afcdf33021"
template = "CentOS 6.5"
zone = "zone-1"
}
@ -34,9 +34,12 @@ The following arguments are supported:
* `service_offering` - (Required) The name or ID of the service offering used
for this instance.
* `network` - (Optional) The name or ID of the network to connect this instance
* `network_id` - (Optional) The ID of the network to connect this instance
to. Changing this forces a new resource to be created.
* `network` - (Optional, Deprecated) The name or ID of the network to connect
this instance to. Changing this forces a new resource to be created.
* `ip_address` - (Optional) The IP address to assign to this instance. Changing
this forces a new resource to be created.

View File

@ -14,7 +14,7 @@ Acquires and associates a public IP.
```
resource "cloudstack_ipaddress" "default" {
network = "test-network"
network_id = "6eb22f91-7454-4107-89f4-36afcdf33021"
}
```
@ -22,16 +22,24 @@ resource "cloudstack_ipaddress" "default" {
The following arguments are supported:
* `network` - (Optional) The name or ID of the network for which an IP address should
* `network_id` - (Optional) The ID of the network for which an IP address should
be acquired and associated. Changing this forces a new resource to be created.
* `vpc` - (Optional) The name or ID of the VPC for which an IP address should
be acquired and associated. Changing this forces a new resource to be created.
* `network` - (Optional, Deprecated) The name or ID of the network for which an IP
addess should be acquired and associated. Changing this forces a new resource
to be created.
* `vpc_id` - (Optional) The ID of the VPC for which an IP address should be
acquired and associated. Changing this forces a new resource to be created.
* `vpc` - (Optional, Deprecated) The name or ID of the VPC for which an IP address
should be acquired and associated. Changing this forces a new resource to be
created.
* `project` - (Optional) The name or ID of the project to deploy this
instance to. Changing this forces a new resource to be created.
*NOTE: Either `network` or `vpc` should have a value!*
*NOTE: Either `network_id` or `vpc_id` should have a value!*
## Attributes Reference

View File

@ -16,11 +16,11 @@ Creates a loadbalancer rule.
resource "cloudstack_loadbalancer_rule" "default" {
name = "loadbalancer-rule-1"
description = "Loadbalancer rule 1"
ip_address = "192.168.0.1"
ip_address_id = "30b21801-d4b3-4174-852b-0c0f30bdbbfb"
algorithm = "roundrobin"
private_port = 80
public_port = 80
members = ["server-1", "server-2"]
member_ids = ["f8141e2f-4e7e-4c63-9362-986c908b7ea7"]
}
```
@ -33,16 +33,20 @@ The following arguments are supported:
* `description` - (Optional) The description of the load balancer rule.
* `ip_address` - (Required) Public ip address from where the network traffic
will be load balanced from. Changing this forces a new resource to be
created.
* `ip_address_id` - (Required) Public IP address ID from where the network
traffic will be load balanced from. Changing this forces a new resource
to be created.
* `ipaddress` - (Required, Deprecated) Public ip address from where the
* `ipaddress` - (Required, Deprecated) Public IP address from where the
network traffic will be load balanced from. Changing this forces a new
resource to be created.
* `network` - (Optional) The guest network this rule will be created for.
Required when public IP address is not associated with any Guest network
* `network_id` - (Optional) The network ID this rule will be created for.
Required when public IP address is not associated with any network yet
(VPC case).
* `network` - (Optional, Deprecated) The network this rule will be created
for. Required when public IP address is not associated with any network
yet (VPC case).
* `algorithm` - (Required) Load balancer rule algorithm (source, roundrobin,
@ -56,8 +60,11 @@ The following arguments are supported:
will be load balanced from. Changing this forces a new resource to be
created.
* `members` - (Required) List of instances to assign to the load balancer rule.
Changing this forces a new resource to be created.
* `member_ids` - (Required) List of instance IDs to assign to the load balancer
rule. Changing this forces a new resource to be created.
* `members` - (Required, Deprecated) List of instances to assign to the load
balancer rule. Changing this forces a new resource to be created.
## Attributes Reference

View File

@ -50,11 +50,17 @@ The following arguments are supported:
required by the Network Offering if specifyVlan=true is set. Only the ROOT
admin can set this value.
* `vpc` - (Optional) The name or ID of the VPC to create this network for. Changing
* `vpc_id` - (Optional) The ID of the VPC to create this network for. Changing
this forces a new resource to be created.
* `aclid` - (Optional) The ID of a network ACL that should be attached to the
network. Changing this forces a new resource to be created.
* `vpc` - (Optional, Deprecated) The name or ID of the VPC to create this network
for. Changing this forces a new resource to be created.
* `acl_id` - (Optional) The network ACL ID that should be attached to the network.
Changing this forces a new resource to be created.
* `aclid` - (Optional, Deprecated) The ID of a network ACL that should be attached
to the network. Changing this forces a new resource to be created.
* `project` - (Optional) The name or ID of the project to deploy this
instance to. Changing this forces a new resource to be created.

View File

@ -15,7 +15,7 @@ Creates a Network ACL for the given VPC.
```
resource "cloudstack_network_acl" "default" {
name = "test-acl"
vpc = "vpc-1"
vpc_id = "76f6e8dc-07e3-4971-b2a2-8831b0cc4cb4"
}
```
@ -25,10 +25,15 @@ The following arguments are supported:
* `name` - (Required) The name of the ACL. Changing this forces a new resource
to be created.
* `description` - (Optional) The description of the ACL. Changing this forces a
new resource to be created.
* `vpc` - (Required) The name or ID of the VPC to create this ACL for. Changing
this forces a new resource to be created.
* `vpc_id` - (Required) The ID of the VPC to create this ACL for. Changing this
forces a new resource to be created.
* `vpc` - (Required, Deprecated) The name or ID of the VPC to create this ACL
for. Changing this forces a new resource to be created.
## Attributes Reference

View File

@ -14,7 +14,7 @@ Creates network ACL rules for a given network ACL.
```
resource "cloudstack_network_acl_rule" "default" {
aclid = "f3843ce0-334c-4586-bbd3-0c2e2bc946c6"
acl_id = "f3843ce0-334c-4586-bbd3-0c2e2bc946c6"
rule {
action = "allow"
@ -30,9 +30,12 @@ resource "cloudstack_network_acl_rule" "default" {
The following arguments are supported:
* `aclid` - (Required) The network ACL ID for which to create the rules.
* `acl_id` - (Required) The network ACL ID for which to create the rules.
Changing this forces a new resource to be created.
* `aclid` - (Required, Deprecated) The network ACL ID for which to create
the rules. Changing this forces a new resource to be created.
* `managed` - (Optional) USE WITH CAUTION! If enabled all the firewall rules for
this network ACL will be managed by this resource. This means it will delete
all firewall rules that are not in your config! (defaults false)

View File

@ -16,9 +16,9 @@ Basic usage:
```
resource "cloudstack_nic" "test" {
network = "network-2"
network_id = "6eb22f91-7454-4107-89f4-36afcdf33021"
ip_address = "192.168.1.1"
virtual_machine = "server-1"
virtual_machine_id = "f8141e2f-4e7e-4c63-9362-986c908b7ea7"
}
```
@ -26,17 +26,24 @@ resource "cloudstack_nic" "test" {
The following arguments are supported:
* `network` - (Required) The name or ID of the network to plug the NIC into. Changing
* `network_id` - (Required) The ID of the network to plug the NIC into. Changing
this forces a new resource to be created.
* `network` - (Required, Deprecated) The name or ID of the network to plug the
NIC into. Changing this forces a new resource to be created.
* `ip_address` - (Optional) The IP address to assign to the NIC. Changing this
forces a new resource to be created.
* `ipaddress` - (Optional, Deprecated) The IP address to assign to the NIC. Changing
this forces a new resource to be created.
* `ipaddress` - (Optional, Deprecated) The IP address to assign to the NIC.
Changing this forces a new resource to be created.
* `virtual_machine` - (Required) The name or ID of the virtual machine to which
to attach the NIC. Changing this forces a new resource to be created.
* `virtual_machine_id` - (Required) The ID of the virtual machine to which to
attach the NIC. Changing this forces a new resource to be created.
* `virtual_machine` - (Required, Deprecated) The name or ID of the virtual
machine to which to attach the NIC. Changing this forces a new resource to
be created.
## Attributes Reference

View File

@ -14,13 +14,13 @@ Creates port forwards.
```
resource "cloudstack_port_forward" "default" {
ip_address = "192.168.0.1"
ip_address_id = "30b21801-d4b3-4174-852b-0c0f30bdbbfb"
forward {
protocol = "tcp"
private_port = 80
public_port = 8080
virtual_machine = "server-1"
virtual_machine_id = "f8141e2f-4e7e-4c63-9362-986c908b7ea7"
}
}
```
@ -29,8 +29,8 @@ resource "cloudstack_port_forward" "default" {
The following arguments are supported:
* `ip_address` - (Required) The IP address for which to create the port forwards.
Changing this forces a new resource to be created.
* `ip_address_id` - (Required) The IP address ID for which to create the port
forwards. Changing this forces a new resource to be created.
* `ipaddress` - (Required, Deprecated) The IP address for which to create the port
forwards. Changing this forces a new resource to be created.
@ -51,7 +51,10 @@ The `forward` block supports:
* `public_port` - (Required) The public port to forward from.
* `virtual_machine` - (Required) The name or ID of the virtual machine to forward to.
* `virtual_machine_id` - (Required) The ID of the virtual machine to forward to.
* `virtual_machine` - (Required, Deprecated) The name or ID of the virtual
machine to forward to.
## Attributes Reference

View File

@ -14,7 +14,7 @@ Assigns a secondary IP to a NIC.
```
resource "cloudstack_secondary_ipaddress" "default" {
virtual_machine = "server-1"
virtual_machine_id = "server-1"
}
```
@ -30,13 +30,21 @@ The following arguments are supported:
not supplied an IP address will be selected randomly. Changing this forces
a new resource to be created.
* `nicid` - (Optional) The ID of the NIC to which you want to attach the
secondary IP address. Changing this forces a new resource to be
created (defaults to the ID of the primary NIC)
* `nic_id` - (Optional) The NIC ID to which you want to attach the secondary IP
address. Changing this forces a new resource to be created (defaults to the
ID of the primary NIC)
* `virtual_machine` - (Required) The name or ID of the virtual machine to which
you want to attach the secondary IP address. Changing this forces a new
resource to be created.
* `nicid` - (Optional, Deprecated) The ID of the NIC to which you want to attach
the secondary IP address. Changing this forces a new resource to be created
(defaults to the ID of the primary NIC)
* `virtual_machine_id` - (Required) The ID of the virtual machine to which you
want to attach the secondary IP address. Changing this forces a new resource
to be created.
* `virtual_machine` - (Required, Deprecated) The name or ID of the virtual
machine to which you want to attach the secondary IP address. Changing this
forces a new resource to be created.
## Attributes Reference

View File

@ -14,8 +14,8 @@ Enables static NAT for a given IP address
```
resource "cloudstack_static_nat" "default" {
ipaddress = "192.168.0.1"
virtual_machine = "server-1"
ip_address_id = "f8141e2f-4e7e-4c63-9362-986c908b7ea7"
virtual_machine_id = "6ca2a163-bc68-429c-adc8-ab4a620b1bb3"
}
```
@ -23,18 +23,16 @@ resource "cloudstack_static_nat" "default" {
The following arguments are supported:
* `ipaddress` - (Required) The name or ID of the public IP address for which
static NAT will be enabled. Changing this forces a new resource to be
* `ip_address_id` - (Required) The public IP address ID for which static
NAT will be enabled. Changing this forces a new resource to be created.
* `network_id` - (Optional) The network ID of the VM the static NAT will be
enabled for. Required when public IP address is not associated with any
guest network yet (VPC case). Changing this forces a new resource to be
created.
* `network` - (Optional) The name or ID of the network of the VM the static
NAT will be enabled for. Required when public IP address is not
associated with any guest network yet (VPC case). Changing this forces
a new resource to be created.
* `virtual_machine` - (Required) The name or ID of the virtual machine to
enable the static NAT feature for. Changing this forces a new resource
to be created.
* `virtual_machine_id` - (Required) The virtual machine ID to enable the
static NAT feature for. Changing this forces a new resource to be created.
* `vm_guest_ip` - (Optional) The virtual machine IP address for the port
forwarding rule (useful when the virtual machine has a secondairy NIC).

View File

@ -31,8 +31,8 @@ The following arguments are supported:
* `display_text` - (Optional) The display name of the template.
* `format` - (Required) The format of the template. Valid values are "QCOW2",
"RAW", and "VHD".
* `format` - (Required) The format of the template. Valid values are `QCOW2`,
`RAW`, and `VHD`.
* `hypervisor` - (Required) The target hypervisor for the template. Changing
this forces a new resource to be created.
@ -43,11 +43,14 @@ The following arguments are supported:
* `url` - (Required) The URL of where the template is hosted. Changing this
forces a new resource to be created.
* `project` - (Optional) The name or ID of the project to create this template for.
Changing this forces a new resource to be created.
* `zone` - (Required) The name or ID of the zone where this template will be created.
Changing this forces a new resource to be created.
* `is_dynamically_scalable` - (Optional) Set to indicate if the template contains
tools to support dynamic scaling of VM cpu/memory.
tools to support dynamic scaling of VM cpu/memory (defaults false)
* `is_extractable` - (Optional) Set to indicate if the template is extractable
(defaults false)

View File

@ -16,8 +16,8 @@ Basic usage:
```
resource "cloudstack_vpn_connection" "default" {
customergatewayid = "xxx"
vpngatewayid = "xxx"
customer_gateway_id = "8dab9381-ae73-48b8-9a3d-c460933ef5f7"
vpn_gateway_id = "a7900060-f8a8-44eb-be15-ea54cf499703"
}
```
@ -25,10 +25,16 @@ resource "cloudstack_vpn_connection" "default" {
The following arguments are supported:
* `customergatewayid` - (Required) The Customer Gateway ID to connect.
* `customer_gateway_id` - (Required) The Customer Gateway ID to connect.
Changing this forces a new resource to be created.
* `vpngatewayid` - (Required) The VPN Gateway ID to connect.
* `customergatewayid` - (Required, Deprecated) The Customer Gateway ID
to connect. Changing this forces a new resource to be created.
* `vpn_gateway_id` - (Required) The VPN Gateway ID to connect. Changing
this forces a new resource to be created.
* `vpngatewayid` - (Required, Deprecated) The VPN Gateway ID to connect.
Changing this forces a new resource to be created.
## Attributes Reference

View File

@ -16,7 +16,7 @@ Basic usage:
```
resource "cloudstack_vpn_gateway" "default" {
vpc = "test-vpc"
vpc_id = "f8141e2f-4e7e-4c63-9362-986c908b7ea7"
}
```
@ -24,9 +24,12 @@ resource "cloudstack_vpn_gateway" "default" {
The following arguments are supported:
* `vpc` - (Required) The name or ID of the VPC for which to create the VPN Gateway.
* `vpc_id` - (Required) The ID of the VPC for which to create the VPN Gateway.
Changing this forces a new resource to be created.
* `vpc` - (Required, Deprecated) The name or ID of the VPC for which to create
the VPN Gateway. Changing this forces a new resource to be created.
## Attributes Reference
The following attributes are exported: