diff --git a/builtin/providers/cloudstack/resource_cloudstack_network.go b/builtin/providers/cloudstack/resource_cloudstack_network.go index a76beae325..7c45154ae8 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_network.go +++ b/builtin/providers/cloudstack/resource_cloudstack_network.go @@ -4,6 +4,7 @@ import ( "fmt" "log" "net" + "strconv" "strings" "github.com/hashicorp/terraform/helper/schema" @@ -35,11 +36,38 @@ func resourceCloudStackNetwork() *schema.Resource { ForceNew: true, }, + "gateway": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + + "startip": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + + "endip": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + "network_offering": &schema.Schema{ Type: schema.TypeString, Required: true, }, + "vlan": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + "vpc": &schema.Schema{ Type: schema.TypeString, Optional: true, @@ -94,17 +122,34 @@ func resourceCloudStackNetworkCreate(d *schema.ResourceData, meta interface{}) e p := cs.Network.NewCreateNetworkParams(displaytext.(string), name, networkofferingid, zoneid) // Get the network details from the CIDR - m, err := parseCIDR(d.Get("cidr").(string)) + m := make(map[string]string, 4) + cidr := d.Get("cidr").(string) + m["cidr"] = cidr + if startip, ok := d.GetOk("startip"); ok { + m["startip"] = startip.(string) + } + if endip, ok := d.GetOk("endip"); ok { + m["endip"] = endip.(string) + } + if gateway, ok := d.GetOk("gateway"); ok { + m["gateway"] = gateway.(string) + } + + m, err := parseCIDR(m) if err != nil { return err } // Set the needed IP config - p.SetStartip(m["start"]) + p.SetStartip(m["startip"]) p.SetGateway(m["gateway"]) - p.SetEndip(m["end"]) + p.SetEndip(m["endip"]) p.SetNetmask(m["netmask"]) + if vlan, ok := d.GetOk("vlan"); ok { + p.SetVlan(strconv.Itoa(vlan.(int))) + } + // Check is this network needs to be created in a VPC vpc := d.Get("vpc").(string) if vpc != "" { @@ -240,22 +285,36 @@ func resourceCloudStackNetworkDelete(d *schema.ResourceData, meta interface{}) e return nil } -func parseCIDR(cidr string) (map[string]string, error) { +func parseCIDR(m_in map[string]string) (map[string]string, error) { m := make(map[string]string, 4) - ip, ipnet, err := net.ParseCIDR(cidr) + ip, ipnet, err := net.ParseCIDR(m_in["cidr"]) if err != nil { - return nil, fmt.Errorf("Unable to parse cidr %s: %s", cidr, err) + return nil, fmt.Errorf("Unable to parse cidr %s: %s", m_in["cidr"], err) } msk := ipnet.Mask sub := ip.Mask(msk) m["netmask"] = fmt.Sprintf("%d.%d.%d.%d", msk[0], msk[1], msk[2], msk[3]) - m["gateway"] = fmt.Sprintf("%d.%d.%d.%d", sub[0], sub[1], sub[2], sub[3]+1) - m["start"] = fmt.Sprintf("%d.%d.%d.%d", sub[0], sub[1], sub[2], sub[3]+2) - m["end"] = fmt.Sprintf("%d.%d.%d.%d", - sub[0]+(0xff-msk[0]), sub[1]+(0xff-msk[1]), sub[2]+(0xff-msk[2]), sub[3]+(0xff-msk[3]-1)) + if gateway, ok := m_in["gateway"]; ok { + m["gateway"] = gateway + } else { + m["gateway"] = fmt.Sprintf("%d.%d.%d.%d", sub[0], sub[1], sub[2], sub[3]+1) + } + + if startip, ok := m_in["startip"]; ok { + m["startip"] = startip + } else { + m["startip"] = fmt.Sprintf("%d.%d.%d.%d", sub[0], sub[1], sub[2], sub[3]+2) + } + + if endip, ok := m_in["endip"]; ok { + m["endip"] = endip + } else { + m["endip"] = fmt.Sprintf("%d.%d.%d.%d", + sub[0]+(0xff-msk[0]), sub[1]+(0xff-msk[1]), sub[2]+(0xff-msk[2]), sub[3]+(0xff-msk[3]-1)) + } return m, nil } diff --git a/website/source/docs/providers/cloudstack/r/network.html.markdown b/website/source/docs/providers/cloudstack/r/network.html.markdown index 4feb566b9b..91b90f86e8 100644 --- a/website/source/docs/providers/cloudstack/r/network.html.markdown +++ b/website/source/docs/providers/cloudstack/r/network.html.markdown @@ -34,9 +34,23 @@ The following arguments are supported: * `cidr` - (Required) The CIDR block for the network. Changing this forces a new resource to be created. +* `startip` - (Optional) Start of the IP block that will be available on the + network. It will be autocalculated to the second available IP in the range + if it's left out. + +* `endip` - (Optional) End of the IP block that will be available on the + network. It will be autocalculated to the last available IP in the range + if it's left out. + +* `gateway` - (Optional) Gateway that will be provided to the instances in this + network. It defaults to the first usable IP if it's left empty. + * `network_offering` - (Required) The name or ID of the network offering to use for this network. +* `vlan` - (Optional) The VLAN number (1-4095) the network will use. This might be + required by the Network Offering if specifyVlan=true is set. + * `vpc` - (Optional) The name or ID of the VPC to create this network for. Changing this forces a new resource to be created.