Adding private gateway and static route resource to cloudstack provider (#9637)
* Adding private gateway and static route resource to cloudstack provider Testing the private gateway and static route resource requires a ROOT account in Cloudstack * changes requested by reviewer
This commit is contained in:
parent
d2eab5a760
commit
2531ab024a
|
@ -53,11 +53,13 @@ func Provider() terraform.ResourceProvider {
|
||||||
"cloudstack_network_acl_rule": resourceCloudStackNetworkACLRule(),
|
"cloudstack_network_acl_rule": resourceCloudStackNetworkACLRule(),
|
||||||
"cloudstack_nic": resourceCloudStackNIC(),
|
"cloudstack_nic": resourceCloudStackNIC(),
|
||||||
"cloudstack_port_forward": resourceCloudStackPortForward(),
|
"cloudstack_port_forward": resourceCloudStackPortForward(),
|
||||||
|
"cloudstack_private_gateway": resourceCloudStackPrivateGateway(),
|
||||||
"cloudstack_secondary_ipaddress": resourceCloudStackSecondaryIPAddress(),
|
"cloudstack_secondary_ipaddress": resourceCloudStackSecondaryIPAddress(),
|
||||||
"cloudstack_security_group": resourceCloudStackSecurityGroup(),
|
"cloudstack_security_group": resourceCloudStackSecurityGroup(),
|
||||||
"cloudstack_security_group_rule": resourceCloudStackSecurityGroupRule(),
|
"cloudstack_security_group_rule": resourceCloudStackSecurityGroupRule(),
|
||||||
"cloudstack_ssh_keypair": resourceCloudStackSSHKeyPair(),
|
"cloudstack_ssh_keypair": resourceCloudStackSSHKeyPair(),
|
||||||
"cloudstack_static_nat": resourceCloudStackStaticNAT(),
|
"cloudstack_static_nat": resourceCloudStackStaticNAT(),
|
||||||
|
"cloudstack_static_route": resourceCloudStackStaticRoute(),
|
||||||
"cloudstack_template": resourceCloudStackTemplate(),
|
"cloudstack_template": resourceCloudStackTemplate(),
|
||||||
"cloudstack_vpc": resourceCloudStackVPC(),
|
"cloudstack_vpc": resourceCloudStackVPC(),
|
||||||
"cloudstack_vpn_connection": resourceCloudStackVPNConnection(),
|
"cloudstack_vpn_connection": resourceCloudStackVPNConnection(),
|
||||||
|
|
|
@ -144,6 +144,21 @@ func testAccPreCheck(t *testing.T) {
|
||||||
if v := os.Getenv("CLOUDSTACK_ZONE"); v == "" {
|
if v := os.Getenv("CLOUDSTACK_ZONE"); v == "" {
|
||||||
t.Fatal("CLOUDSTACK_ZONE must be set for acceptance tests")
|
t.Fatal("CLOUDSTACK_ZONE must be set for acceptance tests")
|
||||||
}
|
}
|
||||||
|
if v := os.Getenv("CLOUDSTACK_PRIVGW_GATEWAY"); v == "" {
|
||||||
|
t.Fatal("CLOUDSTACK_PRIVGW_GATEWAY must be set for acceptance tests")
|
||||||
|
}
|
||||||
|
if v := os.Getenv("CLOUDSTACK_PRIVGW_IPADDRESS"); v == "" {
|
||||||
|
t.Fatal("CLOUDSTACK_PRIVGW_IPADDRESS must be set for acceptance tests")
|
||||||
|
}
|
||||||
|
if v := os.Getenv("CLOUDSTACK_PRIVGW_NETMASK"); v == "" {
|
||||||
|
t.Fatal("CLOUDSTACK_PRIVGW_NETMASK must be set for acceptance tests")
|
||||||
|
}
|
||||||
|
if v := os.Getenv("CLOUDSTACK_PRIVGW_VLAN"); v == "" {
|
||||||
|
t.Fatal("CLOUDSTACK_PRIVGW_VLAN must be set for acceptance tests")
|
||||||
|
}
|
||||||
|
if v := os.Getenv("CLOUDSTACK_STATIC_ROUTE_CIDR"); v == "" {
|
||||||
|
t.Fatal("CLOUDSTACK_STATIC_ROUTE_CIDR must be set for acceptance tests")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name of a valid disk offering
|
// Name of a valid disk offering
|
||||||
|
@ -223,3 +238,12 @@ var CLOUDSTACK_PROJECT_NETWORK = os.Getenv("CLOUDSTACK_PROJECT_NETWORK")
|
||||||
|
|
||||||
// Name of a zone that exists already
|
// Name of a zone that exists already
|
||||||
var CLOUDSTACK_ZONE = os.Getenv("CLOUDSTACK_ZONE")
|
var CLOUDSTACK_ZONE = os.Getenv("CLOUDSTACK_ZONE")
|
||||||
|
|
||||||
|
// Details of the private gateway that will be added to VPC testing this, should be done using ROOT keys
|
||||||
|
var CLOUDSTACK_PRIVGW_GATEWAY = os.Getenv("CLOUDSTACK_PRIVGW_GATEWAY")
|
||||||
|
var CLOUDSTACK_PRIVGW_IPADDRESS = os.Getenv("CLOUDSTACK_PRIVGW_IPADDRESS")
|
||||||
|
var CLOUDSTACK_PRIVGW_NETMASK = os.Getenv("CLOUDSTACK_PRIVGW_NETMASK")
|
||||||
|
var CLOUDSTACK_PRIVGW_VLAN = os.Getenv("CLOUDSTACK_PRIVGW_VLAN")
|
||||||
|
|
||||||
|
// Details of the static route that will be added to private gateway testing this.
|
||||||
|
var CLOUDSTACK_STATIC_ROUTE_CIDR = os.Getenv("CLOUDSTACK_STATIC_ROUTE_CIDR")
|
||||||
|
|
|
@ -0,0 +1,173 @@
|
||||||
|
package cloudstack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/xanzy/go-cloudstack/cloudstack"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceCloudStackPrivateGateway() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceCloudStackPrivateGatewayCreate,
|
||||||
|
Read: resourceCloudStackPrivateGatewayRead,
|
||||||
|
Update: resourceCloudStackPrivateGatewayUpdate,
|
||||||
|
Delete: resourceCloudStackPrivateGatewayDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"gateway": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"ip_address": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"netmask": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"vlan": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"physical_network_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"network_offering": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"acl_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"vpc_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceCloudStackPrivateGatewayCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
cs := meta.(*cloudstack.CloudStackClient)
|
||||||
|
|
||||||
|
ipaddress := d.Get("ip_address").(string)
|
||||||
|
networkofferingid := d.Get("network_offering").(string)
|
||||||
|
|
||||||
|
// Create a new parameter struct
|
||||||
|
p := cs.VPC.NewCreatePrivateGatewayParams(
|
||||||
|
d.Get("gateway").(string),
|
||||||
|
ipaddress,
|
||||||
|
d.Get("netmask").(string),
|
||||||
|
d.Get("vlan").(string),
|
||||||
|
d.Get("vpc_id").(string),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Retrieve the network_offering ID
|
||||||
|
if networkofferingid != "" {
|
||||||
|
networkofferingid, e := retrieveID(cs, "network_offering", networkofferingid)
|
||||||
|
if e != nil {
|
||||||
|
return e.Error()
|
||||||
|
}
|
||||||
|
p.SetNetworkofferingid(networkofferingid)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we want to associate an ACL
|
||||||
|
if aclid, ok := d.GetOk("acl_id"); ok {
|
||||||
|
// Set the acl ID
|
||||||
|
p.SetAclid(aclid.(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the new private gateway
|
||||||
|
r, err := cs.VPC.CreatePrivateGateway(p)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating private gateway for %s: %s", ipaddress, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(r.Id)
|
||||||
|
|
||||||
|
return resourceCloudStackPrivateGatewayRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceCloudStackPrivateGatewayRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
cs := meta.(*cloudstack.CloudStackClient)
|
||||||
|
|
||||||
|
// Get the private gateway details
|
||||||
|
gw, count, err := cs.VPC.GetPrivateGatewayByID(d.Id())
|
||||||
|
if err != nil {
|
||||||
|
if count == 0 {
|
||||||
|
log.Printf("[DEBUG] Private gateway %s does no longer exist", d.Id())
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("gateway", gw.Gateway)
|
||||||
|
d.Set("ip_address", gw.Ipaddress)
|
||||||
|
d.Set("netmask", gw.Netmask)
|
||||||
|
d.Set("vlan", gw.Vlan)
|
||||||
|
d.Set("acl_id", gw.Aclid)
|
||||||
|
d.Set("vpc_id", gw.Vpcid)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceCloudStackPrivateGatewayUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
cs := meta.(*cloudstack.CloudStackClient)
|
||||||
|
|
||||||
|
// Replace the ACL if the ID has changed
|
||||||
|
if d.HasChange("acl_id") {
|
||||||
|
p := cs.NetworkACL.NewReplaceNetworkACLListParams(d.Get("acl_id").(string))
|
||||||
|
p.SetNetworkid(d.Id())
|
||||||
|
|
||||||
|
_, err := cs.NetworkACL.ReplaceNetworkACLList(p)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error replacing ACL: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resourceCloudStackNetworkRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceCloudStackPrivateGatewayDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
cs := meta.(*cloudstack.CloudStackClient)
|
||||||
|
|
||||||
|
// Create a new parameter struct
|
||||||
|
p := cs.VPC.NewDeletePrivateGatewayParams(d.Id())
|
||||||
|
|
||||||
|
// Delete the private gateway
|
||||||
|
_, err := cs.VPC.DeletePrivateGateway(p)
|
||||||
|
if err != nil {
|
||||||
|
// This is a very poor way to be told the ID does no longer exist :(
|
||||||
|
if strings.Contains(err.Error(), fmt.Sprintf(
|
||||||
|
"Invalid parameter id value=%s due to incorrect long value format, "+
|
||||||
|
"or entity does not exist", d.Id())) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("Error deleting private gateway %s: %s", d.Id(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
package cloudstack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
"github.com/xanzy/go-cloudstack/cloudstack"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccCloudStackPrivateGateway_basic(t *testing.T) {
|
||||||
|
var gateway cloudstack.PrivateGateway
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckCloudStackPrivateGatewayDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccCloudStackPrivateGateway_basic,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckCloudStackPrivateGatewayExists(
|
||||||
|
"cloudstack_private_gateway.foo", &gateway),
|
||||||
|
testAccCheckCloudStackPrivateGatewayAttributes(&gateway),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckCloudStackPrivateGatewayExists(
|
||||||
|
n string, gateway *cloudstack.PrivateGateway) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not found: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No Private Gateway ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
cs := testAccProvider.Meta().(*cloudstack.CloudStackClient)
|
||||||
|
pgw, _, err := cs.VPC.GetPrivateGatewayByID(rs.Primary.ID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if pgw.Id != rs.Primary.ID {
|
||||||
|
return fmt.Errorf("Private Gateway not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
*gateway = *pgw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckCloudStackPrivateGatewayAttributes(
|
||||||
|
gateway *cloudstack.PrivateGateway) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
|
||||||
|
if gateway.Gateway != CLOUDSTACK_PRIVGW_GATEWAY {
|
||||||
|
return fmt.Errorf("Bad Gateway: %s", gateway.Gateway)
|
||||||
|
}
|
||||||
|
|
||||||
|
if gateway.Ipaddress != CLOUDSTACK_PRIVGW_IPADDRESS {
|
||||||
|
return fmt.Errorf("Bad Gateway: %s", gateway.Ipaddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
if gateway.Netmask != CLOUDSTACK_PRIVGW_NETMASK {
|
||||||
|
return fmt.Errorf("Bad Gateway: %s", gateway.Netmask)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckCloudStackPrivateGatewayDestroy(s *terraform.State) error {
|
||||||
|
cs := testAccProvider.Meta().(*cloudstack.CloudStackClient)
|
||||||
|
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "cloudstack_private_gateway" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No private gateway ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
gateway, _, err := cs.VPC.GetPrivateGatewayByID(rs.Primary.ID)
|
||||||
|
if err == nil && gateway.Id != "" {
|
||||||
|
return fmt.Errorf("Private gateway %s still exists", rs.Primary.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var testAccCloudStackPrivateGateway_basic = fmt.Sprintf(`
|
||||||
|
resource "cloudstack_vpc" "foobar" {
|
||||||
|
name = "terraform-vpc"
|
||||||
|
cidr = "%s"
|
||||||
|
vpc_offering = "%s"
|
||||||
|
zone = "%s"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "cloudstack_private_gateway" "foo" {
|
||||||
|
gateway = "%s"
|
||||||
|
ip_address = "%s"
|
||||||
|
netmask = "%s"
|
||||||
|
vlan = "%s"
|
||||||
|
vpc_id = "${cloudstack_vpc.foobar.id}"
|
||||||
|
}`,
|
||||||
|
CLOUDSTACK_VPC_CIDR_1,
|
||||||
|
CLOUDSTACK_VPC_OFFERING,
|
||||||
|
CLOUDSTACK_ZONE,
|
||||||
|
CLOUDSTACK_PRIVGW_GATEWAY,
|
||||||
|
CLOUDSTACK_PRIVGW_IPADDRESS,
|
||||||
|
CLOUDSTACK_PRIVGW_NETMASK,
|
||||||
|
CLOUDSTACK_PRIVGW_VLAN)
|
|
@ -0,0 +1,94 @@
|
||||||
|
package cloudstack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/xanzy/go-cloudstack/cloudstack"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceCloudStackStaticRoute() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceCloudStackStaticRouteCreate,
|
||||||
|
Read: resourceCloudStackStaticRouteRead,
|
||||||
|
Delete: resourceCloudStackStaticRouteDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"cidr": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"gateway_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceCloudStackStaticRouteCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
cs := meta.(*cloudstack.CloudStackClient)
|
||||||
|
|
||||||
|
// Create a new parameter struct
|
||||||
|
p := cs.VPC.NewCreateStaticRouteParams(
|
||||||
|
d.Get("cidr").(string),
|
||||||
|
d.Get("gateway_id").(string),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Create the new private gateway
|
||||||
|
r, err := cs.VPC.CreateStaticRoute(p)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating static route for %s: %s", d.Get("cidr").(string), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(r.Id)
|
||||||
|
|
||||||
|
return resourceCloudStackStaticRouteRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceCloudStackStaticRouteRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
cs := meta.(*cloudstack.CloudStackClient)
|
||||||
|
|
||||||
|
// Get the virtual machine details
|
||||||
|
staticroute, count, err := cs.VPC.GetStaticRouteByID(d.Id())
|
||||||
|
if err != nil {
|
||||||
|
if count == 0 {
|
||||||
|
log.Printf("[DEBUG] Static route %s does no longer exist", d.Id())
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("cidr", staticroute.Cidr)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceCloudStackStaticRouteDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
cs := meta.(*cloudstack.CloudStackClient)
|
||||||
|
|
||||||
|
// Create a new parameter struct
|
||||||
|
p := cs.VPC.NewDeleteStaticRouteParams(d.Id())
|
||||||
|
|
||||||
|
// Delete the private gateway
|
||||||
|
_, err := cs.VPC.DeleteStaticRoute(p)
|
||||||
|
if err != nil {
|
||||||
|
// This is a very poor way to be told the ID does no longer exist :(
|
||||||
|
if strings.Contains(err.Error(), fmt.Sprintf(
|
||||||
|
"Invalid parameter id value=%s due to incorrect long value format, "+
|
||||||
|
"or entity does not exist", d.Id())) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("Error deleting static route for %s: %s", d.Get("cidr").(string), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
package cloudstack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
"github.com/xanzy/go-cloudstack/cloudstack"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccCloudStackStaticRoute_basic(t *testing.T) {
|
||||||
|
var staticroute cloudstack.StaticRoute
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckCloudStackStaticRouteDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccCloudStackStaticRoute_basic,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckCloudStackStaticRouteExists(
|
||||||
|
"cloudstack_static_route.bar", &staticroute),
|
||||||
|
testAccCheckCloudStackStaticRouteAttributes(&staticroute),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckCloudStackStaticRouteExists(
|
||||||
|
n string, staticroute *cloudstack.StaticRoute) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not found: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No Static Route ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
cs := testAccProvider.Meta().(*cloudstack.CloudStackClient)
|
||||||
|
route, _, err := cs.VPC.GetStaticRouteByID(rs.Primary.ID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if route.Id != rs.Primary.ID {
|
||||||
|
return fmt.Errorf("Static Route not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
*staticroute = *route
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckCloudStackStaticRouteAttributes(
|
||||||
|
staticroute *cloudstack.StaticRoute) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
|
||||||
|
if staticroute.Cidr != CLOUDSTACK_STATIC_ROUTE_CIDR {
|
||||||
|
return fmt.Errorf("Bad Cidr: %s", staticroute.Cidr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckCloudStackStaticRouteDestroy(s *terraform.State) error {
|
||||||
|
cs := testAccProvider.Meta().(*cloudstack.CloudStackClient)
|
||||||
|
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "cloudstack_static_route" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No static route ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
staticroute, _, err := cs.VPC.GetStaticRouteByID(rs.Primary.ID)
|
||||||
|
if err == nil && staticroute.Id != "" {
|
||||||
|
return fmt.Errorf("Static route %s still exists", rs.Primary.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var testAccCloudStackStaticRoute_basic = fmt.Sprintf(`
|
||||||
|
resource "cloudstack_vpc" "foobar" {
|
||||||
|
name = "terraform-vpc"
|
||||||
|
cidr = "%s"
|
||||||
|
vpc_offering = "%s"
|
||||||
|
zone = "%s"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "cloudstack_private_gateway" "foo" {
|
||||||
|
gateway = "%s"
|
||||||
|
ip_address = "%s"
|
||||||
|
netmask = "%s"
|
||||||
|
vlan = "%s"
|
||||||
|
vpc_id = "${cloudstack_vpc.foobar.id}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "cloudstack_static_route" "bar" {
|
||||||
|
cidr = "%s"
|
||||||
|
gateway_id = "${cloudstack_private_gateway.foo.id}"
|
||||||
|
}`,
|
||||||
|
CLOUDSTACK_VPC_CIDR_1,
|
||||||
|
CLOUDSTACK_VPC_OFFERING,
|
||||||
|
CLOUDSTACK_ZONE,
|
||||||
|
CLOUDSTACK_PRIVGW_GATEWAY,
|
||||||
|
CLOUDSTACK_PRIVGW_IPADDRESS,
|
||||||
|
CLOUDSTACK_PRIVGW_NETMASK,
|
||||||
|
CLOUDSTACK_PRIVGW_VLAN,
|
||||||
|
CLOUDSTACK_STATIC_ROUTE_CIDR)
|
|
@ -0,0 +1,58 @@
|
||||||
|
---
|
||||||
|
layout: "cloudstack"
|
||||||
|
page_title: "CloudStack: cloudstack_private_gateway"
|
||||||
|
sidebar_current: "docs-cloudstack-resource-private-gateway"
|
||||||
|
description: |-
|
||||||
|
Creates a private gateway.
|
||||||
|
---
|
||||||
|
|
||||||
|
# cloudstack\_private\_gateway
|
||||||
|
|
||||||
|
Creates a private gateway for the given VPC.
|
||||||
|
|
||||||
|
*NOTE: private gateway can only be created using a ROOT account!*
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "cloudstack_private_gateway" "default" {
|
||||||
|
gateway = 10.0.0.1
|
||||||
|
ip_address = "10.0.0.2"
|
||||||
|
netmask = "255.255.255.252"
|
||||||
|
vlan = "200"
|
||||||
|
vpc_id = "76f6e8dc-07e3-4971-b2a2-8831b0cc4cb4"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `gateway` - (Required) the gateway of the Private gateway. Changing this
|
||||||
|
forces a new resource to be created.
|
||||||
|
|
||||||
|
* `ip_address` - (Required) the IP address of the Private gateway. Changing this forces
|
||||||
|
a new resource to be created.
|
||||||
|
|
||||||
|
* `netmask` - (Required) The netmask of the Private gateway. Changing
|
||||||
|
this forces a new resource to be created.
|
||||||
|
|
||||||
|
* `vlan` - (Required) The VLAN number (1-4095) the network will use.
|
||||||
|
|
||||||
|
* `physical_network_id` - (Optional) The ID of the physical network this private
|
||||||
|
gateway belongs to.
|
||||||
|
|
||||||
|
* `network_offering` - (Optional) The name or ID of the network offering to use for
|
||||||
|
the private gateways network connection.
|
||||||
|
|
||||||
|
* `acl_id` - (Required) The ACL ID that should be attached to the network.
|
||||||
|
|
||||||
|
* `vpc_id` - (Required) The VPC ID in which to create this Private gateway. Changing
|
||||||
|
this forces a new resource to be created.
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `id` - The ID of the private gateway.
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
---
|
||||||
|
layout: "cloudstack"
|
||||||
|
page_title: "CloudStack: cloudstack_static_route"
|
||||||
|
sidebar_current: "docs-cloudstack-resource-static-route"
|
||||||
|
description: |-
|
||||||
|
Creates a static route.
|
||||||
|
---
|
||||||
|
|
||||||
|
# cloudstack\_static\_route
|
||||||
|
|
||||||
|
Creates a static route for the given private gateway or VPC.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "cloudstack_static_route" "default" {
|
||||||
|
cidr = "10.0.0.0/16"
|
||||||
|
gateway_id = "76f607e3-e8dc-4971-8831-b2a2b0cc4cb4"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `cidr` - (Required) The CIDR for the static route. Changing this forces
|
||||||
|
a new resource to be created.
|
||||||
|
|
||||||
|
* `gateway_id` - (Required) The ID of the Private gateway. Changing this forces
|
||||||
|
a new resource to be created.
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `id` - The ID of the static route.
|
||||||
|
|
|
@ -61,6 +61,10 @@
|
||||||
<a href="/docs/providers/cloudstack/r/port_forward.html">cloudstack_port_forward</a>
|
<a href="/docs/providers/cloudstack/r/port_forward.html">cloudstack_port_forward</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-cloudstack-resource-private-gateway") %>>
|
||||||
|
<a href="/docs/providers/cloudstack/r/private_gateway.html">cloudstack_private_gateway</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-cloudstack-resource-secondary-ipaddress") %>>
|
<li<%= sidebar_current("docs-cloudstack-resource-secondary-ipaddress") %>>
|
||||||
<a href="/docs/providers/cloudstack/r/secondary_ipaddress.html">cloudstack_secondary_ipaddress</a>
|
<a href="/docs/providers/cloudstack/r/secondary_ipaddress.html">cloudstack_secondary_ipaddress</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -81,6 +85,10 @@
|
||||||
<a href="/docs/providers/cloudstack/r/static_nat.html">cloudstack_static_nat</a>
|
<a href="/docs/providers/cloudstack/r/static_nat.html">cloudstack_static_nat</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-cloudstack-resource-static-route") %>>
|
||||||
|
<a href="/docs/providers/cloudstack/r/static_route.html">cloudstack_static_route</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-cloudstack-resource-template") %>>
|
<li<%= sidebar_current("docs-cloudstack-resource-template") %>>
|
||||||
<a href="/docs/providers/cloudstack/r/template.html">cloudstack_template</a>
|
<a href="/docs/providers/cloudstack/r/template.html">cloudstack_template</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
Loading…
Reference in New Issue