From bad3a876cabdf56d767b1e447286e032fc273982 Mon Sep 17 00:00:00 2001 From: Sander van Harmelen Date: Mon, 12 Dec 2016 10:06:42 +0100 Subject: [PATCH] provider/cloudstack: add support for multiple NICs with port forwards and set network_domain for networks (#10638) * Add support for multiple NICs with port forwards * Fix issue #9801 --- .../cloudstack/resource_cloudstack_network.go | 17 ++++++++++ .../resource_cloudstack_port_forward.go | 32 +++++++++++++++++-- .../cloudstack/r/network.html.markdown | 11 ++++--- .../cloudstack/r/port_forward.html.markdown | 7 +++- .../cloudstack/r/static_nat.html.markdown | 8 ++--- .../providers/cloudstack/r/vpc.html.markdown | 4 +-- 6 files changed, 65 insertions(+), 14 deletions(-) diff --git a/builtin/providers/cloudstack/resource_cloudstack_network.go b/builtin/providers/cloudstack/resource_cloudstack_network.go index 2b58b5bef..e5e110b04 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_network.go +++ b/builtin/providers/cloudstack/resource_cloudstack_network.go @@ -77,6 +77,12 @@ func resourceCloudStackNetwork() *schema.Resource { ForceNew: true, }, + "network_domain": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "network_offering": &schema.Schema{ Type: schema.TypeString, Required: true, @@ -165,6 +171,11 @@ func resourceCloudStackNetworkCreate(d *schema.ResourceData, meta interface{}) e p.SetEndip(endip) } + // Set the network domain if we have one + if networkDomain, ok := d.GetOk("network_domain"); ok { + p.SetNetworkdomain(networkDomain.(string)) + } + if vlan, ok := d.GetOk("vlan"); ok { p.SetVlan(strconv.Itoa(vlan.(int))) } @@ -225,6 +236,7 @@ func resourceCloudStackNetworkRead(d *schema.ResourceData, meta interface{}) err d.Set("display_text", n.Displaytext) d.Set("cidr", n.Cidr) d.Set("gateway", n.Gateway) + d.Set("network_domain", n.Networkdomain) d.Set("vpc_id", n.Vpcid) if n.Aclid == "" { @@ -270,6 +282,11 @@ func resourceCloudStackNetworkUpdate(d *schema.ResourceData, meta interface{}) e p.SetGuestvmcidr(d.Get("cidr").(string)) } + // Check if the network domain is changed + if d.HasChange("network_domain") { + p.SetNetworkdomain(d.Get("network_domain").(string)) + } + // Check if the network offering is changed if d.HasChange("network_offering") { // Retrieve the network_offering ID diff --git a/builtin/providers/cloudstack/resource_cloudstack_port_forward.go b/builtin/providers/cloudstack/resource_cloudstack_port_forward.go index 00479aea8..5d9c1c412 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_port_forward.go +++ b/builtin/providers/cloudstack/resource_cloudstack_port_forward.go @@ -65,6 +65,12 @@ func resourceCloudStackPortForward() *schema.Resource { Required: true, }, + "vm_guest_ip": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "uuid": &schema.Schema{ Type: schema.TypeString, Computed: true, @@ -154,9 +160,28 @@ func createPortForward(d *schema.ResourceData, meta interface{}, forward map[str p := cs.Firewall.NewCreatePortForwardingRuleParams(d.Id(), forward["private_port"].(int), forward["protocol"].(string), forward["public_port"].(int), vm.Id) - // Set the network ID, needed when the public IP address - // is not associated with any network yet (VPC case) - p.SetNetworkid(vm.Nic[0].Networkid) + if vmGuestIP, ok := forward["vm_guest_ip"]; ok { + p.SetVmguestip(vmGuestIP.(string)) + + // Set the network ID based on the guest IP, needed when the public IP address + // is not associated with any network yet + NICS: + for _, nic := range vm.Nic { + if vmGuestIP.(string) == nic.Ipaddress { + p.SetNetworkid(nic.Networkid) + break NICS + } + for _, ip := range nic.Secondaryip { + if vmGuestIP.(string) == ip.Ipaddress { + p.SetNetworkid(nic.Networkid) + break NICS + } + } + } + } else { + // If no guest IP is configured, use the primary NIC + p.SetNetworkid(vm.Nic[0].Networkid) + } // Do not open the firewall automatically in any case p.SetOpenfirewall(false) @@ -248,6 +273,7 @@ func resourceCloudStackPortForwardRead(d *schema.ResourceData, meta interface{}) forward["private_port"] = privPort forward["public_port"] = pubPort forward["virtual_machine_id"] = f.Virtualmachineid + forward["vm_guest_ip"] = f.Vmguestip forwards.Add(forward) } diff --git a/website/source/docs/providers/cloudstack/r/network.html.markdown b/website/source/docs/providers/cloudstack/r/network.html.markdown index 961edf4b1..2a2e21195 100644 --- a/website/source/docs/providers/cloudstack/r/network.html.markdown +++ b/website/source/docs/providers/cloudstack/r/network.html.markdown @@ -37,17 +37,19 @@ The following arguments are supported: * `gateway` - (Optional) Gateway that will be provided to the instances in this network. Defaults to the first usable IP in the range. -* `startip` - (Optional) Start of the IP block that will be available on the +* `startip` - (Optional) Start of the IP block that will be available on the network. Defaults to the second available IP in the range. -* `endip` - (Optional) End of the IP block that will be available on the +* `endip` - (Optional) End of the IP block that will be available on the network. Defaults to the last available IP in the range. +* `network_domain` - (Optional) DNS domain for the network. + * `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. Only the ROOT + required by the Network Offering if specifyVlan=true is set. Only the ROOT admin can set this value. * `vpc_id` - (Optional) The VPC ID in which to create this network. Changing @@ -64,7 +66,7 @@ The following arguments are supported: * `zone` - (Required) The name or ID of the zone where this network will be available. Changing this forces a new resource to be created. -* `tags` - (Optional) A mapping of tags to assign to the resource. +* `tags` - (Optional) A mapping of tags to assign to the resource. ## Attributes Reference @@ -72,3 +74,4 @@ The following attributes are exported: * `id` - The ID of the network. * `display_text` - The display text of the network. +* `network_domain` - DNS domain for the network. diff --git a/website/source/docs/providers/cloudstack/r/port_forward.html.markdown b/website/source/docs/providers/cloudstack/r/port_forward.html.markdown index 00102d278..25ad2de73 100644 --- a/website/source/docs/providers/cloudstack/r/port_forward.html.markdown +++ b/website/source/docs/providers/cloudstack/r/port_forward.html.markdown @@ -50,9 +50,14 @@ The `forward` block supports: * `virtual_machine_id` - (Required) The ID of the virtual machine to forward to. +* `vm_guest_ip` - (Optional) The virtual machine IP address for the port + forwarding rule (useful when the virtual machine has secondairy NICs + or IP addresses). + ## Attributes Reference The following attributes are exported: * `id` - The ID of the IP address for which the port forwards are created. - +* `vm_guest_ip` - The IP address of the virtual machine that is used + for the port forwarding rule. diff --git a/website/source/docs/providers/cloudstack/r/static_nat.html.markdown b/website/source/docs/providers/cloudstack/r/static_nat.html.markdown index 43f6fe7d0..095702ce5 100644 --- a/website/source/docs/providers/cloudstack/r/static_nat.html.markdown +++ b/website/source/docs/providers/cloudstack/r/static_nat.html.markdown @@ -29,9 +29,9 @@ The following arguments are supported: * `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). - Changing this forces a new resource to be created. +* `vm_guest_ip` - (Optional) The virtual machine IP address to forward the + static NAT traffic to (useful when the virtual machine has secondary + NICs or IP addresses). 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. @@ -42,4 +42,4 @@ The following attributes are exported: * `id` - The static nat ID. * `vm_guest_ip` - The IP address of the virtual machine that is used - for the port forwarding rule. + to forward the static NAT traffic to. diff --git a/website/source/docs/providers/cloudstack/r/vpc.html.markdown b/website/source/docs/providers/cloudstack/r/vpc.html.markdown index e1c4c6209..3129e3525 100644 --- a/website/source/docs/providers/cloudstack/r/vpc.html.markdown +++ b/website/source/docs/providers/cloudstack/r/vpc.html.markdown @@ -37,8 +37,8 @@ The following arguments are supported: * `vpc_offering` - (Required) The name or ID of the VPC offering to use for this VPC. Changing this forces a new resource to be created. -* `network_domain` - (Optional) DNS domain for guest - networks. Changing this forces a new resource to be created. +* `network_domain` - (Optional) The default DNS domain for networks created in + this VPC. 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.