Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add implementation for vapp network static routing rules resource #520

Merged
merged 34 commits into from
Jun 26, 2020
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
524f25b
add changelog
vbauzys Jun 18, 2020
9c91e03
bump govcd
vbauzys Jun 23, 2020
4f40271
bump govcd
vbauzys Jun 23, 2020
344ed7d
Merge branch 'master' into vapp-routing
vbauzys Jun 23, 2020
3cb870b
Fixes after merge
vbauzys Jun 23, 2020
712e752
Fixes
vbauzys Jun 23, 2020
e49e8fa
Improve docs
vbauzys Jun 23, 2020
c6ce55d
Improve docs
vbauzys Jun 23, 2020
e5c094d
bump govcd andremove isVappNetwork
vbauzys Jun 25, 2020
c7a0446
add improvements
vbauzys Jun 25, 2020
f64b29f
improve docs
vbauzys Jun 25, 2020
bb5deaa
improve docs
vbauzys Jun 25, 2020
1aab621
improve docs
vbauzys Jun 25, 2020
a6c890c
improve docs
vbauzys Jun 25, 2020
ebb2800
improve docs
vbauzys Jun 25, 2020
71a6b09
improve docs
vbauzys Jun 25, 2020
686dd9c
improve docs
vbauzys Jun 25, 2020
6b5c19a
improve docs
vbauzys Jun 25, 2020
4856b61
Refactor: move NAT and FW enablement
vbauzys Jun 25, 2020
215fde7
improvements
vbauzys Jun 26, 2020
ff40132
bump govcd
vbauzys Jun 26, 2020
22e0ac6
bump govcd
vbauzys Jun 26, 2020
fd72a74
improve docs
vbauzys Jun 26, 2020
95e1f30
improve docs
vbauzys Jun 26, 2020
c11dfb9
Added warning for read
vbauzys Jun 26, 2020
b6f9337
Improve test
vbauzys Jun 26, 2020
cf0007b
bump govcd
vbauzys Jun 26, 2020
9b33ede
improve documentation
vbauzys Jun 26, 2020
be80a0a
improve documentation
vbauzys Jun 26, 2020
82d516a
improve comment
vbauzys Jun 26, 2020
2e99e6f
improve comment
vbauzys Jun 26, 2020
83ea0d0
improve comment
vbauzys Jun 26, 2020
9144dd2
improve comment
vbauzys Jun 26, 2020
d299703
bump govcd
vbauzys Jun 26, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ FEATURES:
* **New Resource:** `vcd_org_group` Org Group management [GH-513]
* **New Resource:** `resource/vcd_vapp_firewall_rules` vApp network firewall rules [GH-511]
* **New Resource:** `resource/vcd_vapp_nat_rules` vApp network NAT rules [GH-518]
* **New Resource:** `resource/vcd_vapp_static_routing` vApp network static routing rules [GH-520]

IMPROVEMENTS:

Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ require (
github.com/hashicorp/hcl/v2 v2.3.0 // indirect
github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7 // indirect
github.com/hashicorp/terraform-plugin-sdk v1.8.0
github.com/vmware/go-vcloud-director/v2 v2.8.0-beta.1
github.com/vmware/go-vcloud-director/v2 v2.8.0-alpha.8
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 // indirect
)

replace github.com/vmware/go-vcloud-director/v2 => github.com/vbauzysvmware/go-vcloud-director/v2 v2.0.0-20200623143755-b94e1a4fcc78
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,12 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok=
github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
github.com/vbauzysvmware/go-vcloud-director/v2 v2.0.0-20200623143755-b94e1a4fcc78 h1:Wgg0VqoXMVj1fC1srPgLL+8Mjvsz5hp0GsQ+f6jXcZY=
github.com/vbauzysvmware/go-vcloud-director/v2 v2.0.0-20200623143755-b94e1a4fcc78/go.mod h1:QARPFI5EJce4Cs9g0gL5mlHGhdN7C40CyOqvh7c+RrA=
github.com/vmihailenco/msgpack v3.3.3+incompatible h1:wapg9xDUZDzGCNFlwc5SqI1rvcciqcxEHac4CYj89xI=
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmihailenco/msgpack v4.0.1+incompatible h1:RMF1enSPeKTlXrXdOcqjFUElywVZjjC6pqse21bKbEU=
github.com/vmihailenco/msgpack v4.0.1+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmware/go-vcloud-director/v2 v2.8.0-beta.1 h1:hP7wb+9A9jPxL2MYWgQlwyB0bOGzRnqK2q7PL/sa8Vc=
github.com/vmware/go-vcloud-director/v2 v2.8.0-beta.1/go.mod h1:QARPFI5EJce4Cs9g0gL5mlHGhdN7C40CyOqvh7c+RrA=
github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
Expand Down
75 changes: 38 additions & 37 deletions vcd/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,43 +56,44 @@ var globalDataSourceMap = map[string]*schema.Resource{

var globalResourceMap = map[string]*schema.Resource{

"vcd_network": resourceVcdNetwork(), // 1.0 DEPRECATED: replaced by vcd_network_routed
"vcd_network_routed": resourceVcdNetworkRouted(), // 2.0
"vcd_network_direct": resourceVcdNetworkDirect(), // 2.0
"vcd_network_isolated": resourceVcdNetworkIsolated(), // 2.0
"vcd_vapp_network": resourceVcdVappNetwork(), // 2.1
"vcd_vapp": resourceVcdVApp(), // 1.0
"vcd_firewall_rules": resourceVcdFirewallRules(), // 1.0 DEPRECATED: Use only for non-advanced edge gateway. Replaced by vcd_nsxv_firewall_rule
"vcd_dnat": resourceVcdDNAT(), // 1.0 DEPRECATED: Use only for non-advanced edge gateway. Replaced by vcd_nsxv_dnat
"vcd_snat": resourceVcdSNAT(), // 1.0 DEPRECATED: Use only for non-advanced edge gateway. Replaced by vcd_nsxv_snat
"vcd_edgegateway": resourceVcdEdgeGateway(), // 2.4
"vcd_edgegateway_vpn": resourceVcdEdgeGatewayVpn(), // 1.0
"vcd_vapp_vm": resourceVcdVAppVm(), // 1.0
"vcd_org": resourceOrg(), // 2.0
"vcd_org_vdc": resourceVcdOrgVdc(), // 2.2
"vcd_org_user": resourceVcdOrgUser(), // 2.4
"vcd_catalog": resourceVcdCatalog(), // 2.0
"vcd_catalog_item": resourceVcdCatalogItem(), // 2.0
"vcd_catalog_media": resourceVcdCatalogMedia(), // 2.0
"vcd_inserted_media": resourceVcdInsertedMedia(), // 2.1
"vcd_independent_disk": resourceVcdIndependentDisk(), // 2.1
"vcd_external_network": resourceVcdExternalNetwork(), // 2.2
"vcd_lb_service_monitor": resourceVcdLbServiceMonitor(), // 2.4
"vcd_lb_server_pool": resourceVcdLBServerPool(), // 2.4
"vcd_lb_app_profile": resourceVcdLBAppProfile(), // 2.4
"vcd_lb_app_rule": resourceVcdLBAppRule(), // 2.4
"vcd_lb_virtual_server": resourceVcdLBVirtualServer(), // 2.4
"vcd_nsxv_dnat": resourceVcdNsxvDnat(), // 2.5
"vcd_nsxv_snat": resourceVcdNsxvSnat(), // 2.5
"vcd_nsxv_firewall_rule": resourceVcdNsxvFirewallRule(), // 2.5
"vcd_nsxv_dhcp_relay": resourceVcdNsxvDhcpRelay(), // 2.6
"vcd_nsxv_ip_set": resourceVcdIpSet(), // 2.6
"vcd_vm_internal_disk": resourceVmInternalDisk(), // 2.7
"vcd_vapp_org_network": resourceVcdVappOrgNetwork(), // 2.7
"vcd_org_group": resourceVcdOrgGroup(), // 2.9
"vcd_vapp_firewall_rules": resourceVcdVappFirewallRules(), // 2.9
"vcd_vapp_nat_rules": resourceVcdVappNetworkNatRules(), // 2.9
"vcd_vm_affinity_rule": resourceVcdVmAffinityRule(), // 2.9
"vcd_network": resourceVcdNetwork(), // 1.0 DEPRECATED: replaced by vcd_network_routed
"vcd_network_routed": resourceVcdNetworkRouted(), // 2.0
"vcd_network_direct": resourceVcdNetworkDirect(), // 2.0
"vcd_network_isolated": resourceVcdNetworkIsolated(), // 2.0
"vcd_vapp_network": resourceVcdVappNetwork(), // 2.1
"vcd_vapp": resourceVcdVApp(), // 1.0
"vcd_firewall_rules": resourceVcdFirewallRules(), // 1.0 DEPRECATED: Use only for non-advanced edge gateway. Replaced by vcd_nsxv_firewall_rule
"vcd_dnat": resourceVcdDNAT(), // 1.0 DEPRECATED: Use only for non-advanced edge gateway. Replaced by vcd_nsxv_dnat
"vcd_snat": resourceVcdSNAT(), // 1.0 DEPRECATED: Use only for non-advanced edge gateway. Replaced by vcd_nsxv_snat
"vcd_edgegateway": resourceVcdEdgeGateway(), // 2.4
"vcd_edgegateway_vpn": resourceVcdEdgeGatewayVpn(), // 1.0
"vcd_vapp_vm": resourceVcdVAppVm(), // 1.0
"vcd_org": resourceOrg(), // 2.0
"vcd_org_vdc": resourceVcdOrgVdc(), // 2.2
"vcd_org_user": resourceVcdOrgUser(), // 2.4
"vcd_catalog": resourceVcdCatalog(), // 2.0
"vcd_catalog_item": resourceVcdCatalogItem(), // 2.0
"vcd_catalog_media": resourceVcdCatalogMedia(), // 2.0
"vcd_inserted_media": resourceVcdInsertedMedia(), // 2.1
"vcd_independent_disk": resourceVcdIndependentDisk(), // 2.1
"vcd_external_network": resourceVcdExternalNetwork(), // 2.2
"vcd_lb_service_monitor": resourceVcdLbServiceMonitor(), // 2.4
"vcd_lb_server_pool": resourceVcdLBServerPool(), // 2.4
"vcd_lb_app_profile": resourceVcdLBAppProfile(), // 2.4
"vcd_lb_app_rule": resourceVcdLBAppRule(), // 2.4
"vcd_lb_virtual_server": resourceVcdLBVirtualServer(), // 2.4
"vcd_nsxv_dnat": resourceVcdNsxvDnat(), // 2.5
"vcd_nsxv_snat": resourceVcdNsxvSnat(), // 2.5
"vcd_nsxv_firewall_rule": resourceVcdNsxvFirewallRule(), // 2.5
"vcd_nsxv_dhcp_relay": resourceVcdNsxvDhcpRelay(), // 2.6
"vcd_nsxv_ip_set": resourceVcdIpSet(), // 2.6
"vcd_vm_internal_disk": resourceVmInternalDisk(), // 2.7
"vcd_vapp_org_network": resourceVcdVappOrgNetwork(), // 2.7
"vcd_org_group": resourceVcdOrgGroup(), // 2.9
"vcd_vapp_firewall_rules": resourceVcdVappFirewallRules(), // 2.9
"vcd_vapp_nat_rules": resourceVcdVappNetworkNatRules(), // 2.9
"vcd_vapp_static_routing": resourceVcdVappNetworkStaticRouting(), // 2.9
"vcd_vm_affinity_rule": resourceVcdVmAffinityRule(), // 2.9
}

// Provider returns a terraform.ResourceProvider.
Expand Down
211 changes: 211 additions & 0 deletions vcd/resource_vcd_vapp_static_routing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
package vcd

import (
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/vmware/go-vcloud-director/v2/types/v56"
"log"
)

func resourceVcdVappNetworkStaticRouting() *schema.Resource {
return &schema.Resource{
Create: resourceVappNetworkStaticRoutingCreate,
Delete: resourceVAppNetworkStaticRoutingDelete,
Read: resourceVappNetworkStaticRoutingRead,
Update: resourceVappNetworkStaticRoutingUpdate,
Importer: &schema.ResourceImporter{
State: vappNetworkStaticRoutingImport,
},

Schema: map[string]*schema.Schema{
"org": {
Type: schema.TypeString,
Required: false,
Optional: true,
ForceNew: true,
Description: "The name of organization to use, optional if defined at provider " +
"level. Useful when connected as sysadmin working across different organizations",
},
"vdc": {
Type: schema.TypeString,
Required: false,
Optional: true,
ForceNew: true,
Description: "The name of VDC to use, optional if defined at provider level",
},
"vapp_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "vApp identifier",
},
"network_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "vApp network identifier",
},
"enabled": &schema.Schema{
lvirbalas marked this conversation as resolved.
Show resolved Hide resolved
Type: schema.TypeBool,
Optional: true,
Default: true,
Description: "Enable or disable static Routing.",
},
"rule": &schema.Schema{
Type: schema.TypeList,
Optional: true,
dataclouder marked this conversation as resolved.
Show resolved Hide resolved
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
Description: "Name for the static route.",
dataclouder marked this conversation as resolved.
Show resolved Hide resolved
},
"network_cidr": &schema.Schema{
dataclouder marked this conversation as resolved.
Show resolved Hide resolved
Type: schema.TypeString,
Required: true,
Description: "network specification in CIDR.",
},
"next_hop_ip": &schema.Schema{
Type: schema.TypeString,
Required: true,
Description: "IP Address of Next Hop router/gateway.",
},
},
},
},
},
}
}

func resourceVappNetworkStaticRoutingCreate(d *schema.ResourceData, meta interface{}) error {
return resourceVappNetworkStaticRoutingUpdate(d, meta)
}

func resourceVappNetworkStaticRoutingUpdate(d *schema.ResourceData, meta interface{}) error {
vcdClient := meta.(*VCDClient)

_, vdc, err := vcdClient.GetOrgAndVdcFromResource(d)
if err != nil {
return fmt.Errorf(errorRetrievingOrgAndVdc, err)
}

vappId := d.Get("vapp_id").(string)
vapp, err := vdc.GetVAppById(vappId, false)
if err != nil {
return fmt.Errorf("error finding vApp. %s", err)
}
vcdClient.lockParentVappWithName(d, vapp.VApp.Name)
defer vcdClient.unLockParentVappWithName(d, vapp.VApp.Name)

networkId := d.Get("network_id").(string)
staticRouting, err := expandVappNetworkStaticRouting(d)
if err != nil {
return fmt.Errorf("error expanding static routes: %s", err)
}
vappNetwork, err := vapp.UpdateNetworkStaticRouting(networkId, staticRouting, d.Get("enabled").(bool))
if err != nil {
log.Printf("[INFO] Error setting static routing: %s", err)
return fmt.Errorf("error setting static routing: %s", err)
}

d.SetId(vappNetwork.ID)

return resourceVappNetworkStaticRoutingRead(d, meta)
}

func resourceVAppNetworkStaticRoutingDelete(d *schema.ResourceData, meta interface{}) error {
vcdClient := meta.(*VCDClient)

_, vdc, err := vcdClient.GetOrgAndVdcFromResource(d)
if err != nil {
return fmt.Errorf(errorRetrievingOrgAndVdc, err)
}

vappId := d.Get("vapp_id").(string)
vapp, err := vdc.GetVAppById(vappId, false)
if err != nil {
return fmt.Errorf("error finding vApp. %s", err)
}

vcdClient.lockParentVappWithName(d, vapp.VApp.Name)
defer vcdClient.unLockParentVappWithName(d, vapp.VApp.Name)

err = vapp.RemoveAllNetworkStaticRoutes(d.Get("network_id").(string))
if err != nil {
log.Printf("[INFO] Error deleting static routes: %s", err)
return fmt.Errorf("error deleting static routes: %s", err)
}

return nil
}

func resourceVappNetworkStaticRoutingRead(d *schema.ResourceData, meta interface{}) error {
vcdClient := meta.(*VCDClient)

_, vdc, err := vcdClient.GetOrgAndVdcFromResource(d)
if err != nil {
return fmt.Errorf(errorRetrievingOrgAndVdc, err)
}

vappId := d.Get("vapp_id").(string)
vapp, err := vdc.GetVAppById(vappId, false)
if err != nil {
return fmt.Errorf("error finding vApp. %s", err)
}

vappNetwork, err := vapp.GetVappNetworkById(d.Get("network_id").(string), false)
if err != nil {
return fmt.Errorf("error finding vApp network. %s", err)
}

var rules []map[string]interface{}
if vappNetwork.Configuration.Features == nil || vappNetwork.Configuration.Features.StaticRoutingService == nil {
log.Print("no Static routes found.")
Didainius marked this conversation as resolved.
Show resolved Hide resolved
_ = d.Set("rule", nil)
}

for _, rule := range vappNetwork.Configuration.Features.StaticRoutingService.StaticRoute {
singleRule := make(map[string]interface{})

singleRule["name"] = rule.Name
singleRule["network_cidr"] = rule.Network
singleRule["next_hop_ip"] = rule.NextHopIP
rules = append(rules, singleRule)
}
_ = d.Set("enabled", vappNetwork.Configuration.Features.StaticRoutingService.IsEnabled)
lvirbalas marked this conversation as resolved.
Show resolved Hide resolved
_ = d.Set("rule", rules)
dataclouder marked this conversation as resolved.
Show resolved Hide resolved
return nil
}

func expandVappNetworkStaticRouting(d *schema.ResourceData) ([]*types.StaticRoute, error) {
var staticRoutes []*types.StaticRoute
for _, singleRule := range d.Get("rule").([]interface{}) {
configuredRule := singleRule.(map[string]interface{})
rule := &types.StaticRoute{
Network: configuredRule["network_cidr"].(string),
Name: configuredRule["name"].(string),
NextHopIP: configuredRule["next_hop_ip"].(string),
}
staticRoutes = append(staticRoutes, rule)
}

return staticRoutes, nil
}

// vappNetworkStaticRoutingImport is responsible for importing the resource.
// The following steps happen as part of import
// 1. The user supplies `terraform import _resource_name_ _the_id_string_` command
// 2. `_the_id_string_` contains a dot formatted path to resource as in the example below
// 3. The functions splits the dot-formatted path and tries to lookup the object
// 4. If the lookup succeeds it set's the ID field for `_resource_name_` resource in state file
// (the resource must be already defined in .tf config otherwise `terraform import` will complain)
// 5. `terraform refresh` is being implicitly launched. The Read method looks up all other fields
// based on the known ID of object.
//
// Example resource name (_resource_name_): vcd_vapp_static_routing.my_existing_static_routing_rules
// Example import path (_the_id_string_): org.my_existing_vdc.vapp_name.network_name or org.my_existing_vdc.vapp_id.network_id
// Note: the separator can be changed using Provider.import_separator or variable VCD_IMPORT_SEPARATOR
func vappNetworkStaticRoutingImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
return vappNetworkRuleImport(d, meta, "vcd_vapp_static_routing")
}
Loading