Skip to content
This repository was archived by the owner on Jan 20, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
79 changes: 61 additions & 18 deletions plugins/module_utils/nsxt_base_resource.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2018 VMware, Inc.
Expand All @@ -25,6 +25,8 @@
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_native

import collections

import sys
if sys.version_info[0] < 3:
raise Exception("Must be using Python 3")
Expand Down Expand Up @@ -257,6 +259,18 @@ def update_resource_params(self, nsx_resource_params):
# Should be overridden in the subclass if needed
pass

def convert_to_ordered_data(self, data):
if isinstance(data, list):
data = sorted([self.convert_to_ordered_data(d) for d in data],
key=str)
elif isinstance(data, dict):
# sort dict with keys
data = collections.OrderedDict(
sorted(data.items(), key=lambda d: d[0]))
for key in data:
data[key] = self.convert_to_ordered_data(data[key])
return data

def check_for_update(self, existing_params, resource_params):
"""
resource_params: dict
Expand All @@ -274,22 +288,23 @@ def check_for_update(self, existing_params, resource_params):
for k, v in resource_params.items():
if k not in existing_params:
return True
elif type(v).__name__ == 'dict':
elif isinstance(v, collections.OrderedDict):
if self.check_for_update(existing_params[k], v):
return True
elif v != existing_params[k]:
def compare_lists(list1, list2):
def do_lists_differ(list1, list2):
# Returns True if list1 and list2 differ
try:
# If the lists can be converted into sets, do so and
# compare lists as sets.
set1 = set(list1)
set2 = set(list2)
return set1 != set2
except Exception:
if len(list1) != len(list2):
return True
if type(v).__name__ == 'list':
if compare_lists(v, existing_params[k]):
for e1, e2 in zip(list1, list2):
if isinstance(e1, collections.OrderedDict):
return self.check_for_update(e1, e2)
elif isinstance(e1, list):
return do_lists_differ(e1, e2)
else:
return e1 != e2
if isinstance(v, list):
if do_lists_differ(existing_params[k], v):
return True
continue
return True
Expand Down Expand Up @@ -549,19 +564,47 @@ def _get_base_arg_spec_of_resource(self):
def _extract_nsx_resource_params(self, resource_params):
# extract the params belonging to this resource only.
filtered_params = {}

def filter_with_spec(spec):
def filter_with_spec(spec, filtered_params, resource_params):
for key in spec.keys():
if (key in resource_params and
resource_params[key] is not None):
filtered_params[key] = resource_params[key]
v = resource_params[key]
current_spec = spec[key]
current_spec_type = current_spec.get("type")
if current_spec_type == 'dict':
params = filter_with_spec(
current_spec, {}, v)
if params:
filtered_params[key] = params
elif current_spec_type == 'list' and v:
if current_spec.get("elements") == "dict":
all_params = []
for element in v:
params = filter_with_spec(
current_spec['options'], {}, element)
if params:
all_params.append(params)
if all_params:
filtered_params[key] = all_params
else:
filtered_params[key] = v
else:
filtered_params[key] = v
return filtered_params

filter_with_spec(self.get_resource_spec())
filter_with_spec(self._get_base_arg_spec_of_nsx_resource())
filtered_params = filter_with_spec(
self.get_resource_spec(), filtered_params, resource_params)
filtered_params = filter_with_spec(
self._get_base_arg_spec_of_nsx_resource(), filtered_params,
resource_params)
return filtered_params

def _achieve_present_state(self, successful_resource_exec_logs):
self.update_resource_params(self.nsx_resource_params)
self.nsx_resource_params = self.convert_to_ordered_data(
self.nsx_resource_params)
self.existing_resource = self.convert_to_ordered_data(
self.existing_resource)
is_resource_updated = self.check_for_update(
self.existing_resource, self.nsx_resource_params)
if not is_resource_updated:
Expand Down Expand Up @@ -872,4 +915,4 @@ def _clean_none_resource_params(self, existing_params, resource_params):
resource_params.pop(key)
for k, v in resource_params.items():
if type(v).__name__ == 'dict':
self._clean_none_resource_params(existing_params, v)
self._clean_none_resource_params(existing_params, v)
91 changes: 51 additions & 40 deletions plugins/modules/nsxt_policy_tier0.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2018 VMware, Inc.
Expand Down Expand Up @@ -683,6 +683,16 @@
IPSec VPN local-endpoint subnets
advertised by TIER1.
type: list
destinations:
description:
- List of destinations for a given
redistribution rule
- Each rule can have more than one
destination. If destinations not
specified for a given rule, default
destination will be BGP
default: ["BGP"]
choices: ["BGP", "OSPF"]
ha_vip_configs:
type: list
elements: dict
Expand Down Expand Up @@ -1452,23 +1462,19 @@ def update_resource_params(self, nsx_resource_params):
DHCP_RELAY_CONFIG_URL + "/" + dhcp_config_id]

if 'vrf_config' in nsx_resource_params:
# vrf config is attached
vrf_config = nsx_resource_params['vrf_config']

vrf_id = vrf_config.get('id')
vrf_display_name = vrf_config.get('display_name')
if not (vrf_display_name or vrf_id):
self.exit_with_failure(msg="Please specify either the ID or "
"display_name of the VRF in the "
"vrf_config using id or display_name")

# Only perform actions related to tier0 if tier0_id or tier0_display_name is provided
tier0_id = vrf_config.pop('tier0_id', None)
if not tier0_id:
tier0_id = self.get_id_using_attr_name_else_fail(
'tier0', vrf_config, NSXTTier0.get_resource_base_url(),
'Tier0')
vrf_config['tier0_path'] = (
NSXTTier0.get_resource_base_url() + "/" + tier0_id)
tier0_display_name = vrf_config.pop('tier0_display_name', None)

if tier0_id or tier0_display_name:
if not tier0_id:
tier0_id = self.get_id_using_attr_name_else_fail(
'tier0', vrf_config, NSXTTier0.get_resource_base_url(),
'Tier0')
vrf_config['tier0_path'] = (
NSXTTier0.get_resource_base_url() + "/" + tier0_id)

vrf_config['resource_type'] = 'Tier0VrfConfig'

Expand Down Expand Up @@ -1690,6 +1696,12 @@ def get_resource_spec():
elements='str',
required=False
),
destinations=dict(
type='list',
elements='str',
required=False,
default=["BGP"],
),
)
)
)
Expand Down Expand Up @@ -1905,39 +1917,38 @@ def update_resource_params(self, nsx_resource_params):
ipv6_profile_paths = []
if self.do_resource_params_have_attr_with_id_or_display_name(
"ipv6_ndra_profile"):
ipv6_ndra_profile_id = (
self.get_id_using_attr_name_else_fail(
"ipv6_ndra_profile", nsx_resource_params,
IPV6_NDRA_PROFILE_URL, "Ipv6NdraProfile"))
ipv6_ndra_profile_id = self.get_id_using_attr_name_else_fail(
"ipv6_ndra_profile", nsx_resource_params,
IPV6_NDRA_PROFILE_URL, "Ipv6NdraProfile")
ipv6_profile_paths.append(
IPV6_NDRA_PROFILE_URL + "/" + ipv6_ndra_profile_id)
if ipv6_profile_paths:
nsx_resource_params[
"ipv6_profile_paths"] = ipv6_profile_paths
nsx_resource_params["ipv6_profile_paths"] = ipv6_profile_paths

# segment_id is a required attr
# Ensure segment_id is set correctly
segment_id = self.get_id_using_attr_name_else_fail(
"segment", nsx_resource_params, SEGMENT_URL, "Segment")
nsx_resource_params["segment_path"] = (
SEGMENT_URL + "/" + segment_id)

# edge_node_info is a required attr
edge_node_info = nsx_resource_params.pop("edge_node_info")
site_id = edge_node_info.get("site_id", "default")
enforcementpoint_id = edge_node_info.get(
"enforcementpoint_id", "default")
edge_cluster_base_url = (
EDGE_CLUSTER_URL.format(site_id, enforcementpoint_id))
edge_cluster_id = self.get_id_using_attr_name_else_fail(
"edge_cluster", edge_node_info,
edge_cluster_base_url, "Edge Cluster")
edge_node_base_url = EDGE_NODE_URL.format(
site_id, enforcementpoint_id, edge_cluster_id)
edge_node_id = self.get_id_using_attr_name_else_fail(
"edge_node", edge_node_info, edge_node_base_url,
'Edge Node')
nsx_resource_params["edge_path"] = (
edge_node_base_url + "/" + edge_node_id)
# Check if edge_node_info exists before using it
edge_node_info = nsx_resource_params.get("edge_node_info")
if edge_node_info:
site_id = edge_node_info.get("site_id", "default")
enforcementpoint_id = edge_node_info.get(
"enforcementpoint_id", "default")
edge_cluster_base_url = (
EDGE_CLUSTER_URL.format(site_id, enforcementpoint_id))
edge_cluster_id = self.get_id_using_attr_name_else_fail(
"edge_cluster", edge_node_info,
edge_cluster_base_url, "Edge Cluster")
edge_node_base_url = EDGE_NODE_URL.format(
site_id, enforcementpoint_id, edge_cluster_id)
edge_node_id = self.get_id_using_attr_name_else_fail(
"edge_node", edge_node_info, edge_node_base_url,
'Edge Node')
nsx_resource_params["edge_path"] = (
edge_node_base_url + "/" + edge_node_id)

class NSXTTier0LocaleServiceBGP(NSXTBaseRealizableResource):
def __init__(self):
Expand Down Expand Up @@ -2149,4 +2160,4 @@ def get_resource_base_url(parent_info):

if __name__ == '__main__':
nsxt_tier0 = NSXTTier0()
nsxt_tier0.realize()
nsxt_tier0.realize()
20 changes: 18 additions & 2 deletions plugins/modules/nsxt_policy_tier1.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2018 VMware, Inc.
Expand Down Expand Up @@ -579,6 +579,16 @@
IPSec VPN local-endpoint subnets
advertised by TIER1.
type: list
destinations:
description:
- List of destinations for a given
redistribution rule
- Each rule can have more than one
destination. If destinations not
specified for a given rule, default
destination will be BGP
default: ["BGP"]
choices: ["BGP", "OSPF"]
ha_vip_configs:
type: list
elements: dict
Expand Down Expand Up @@ -1130,6 +1140,12 @@ def get_resource_spec():
elements='str',
required=False
),
destinations=dict(
type='list',
elements='str',
required=False,
default=["BGP"],
),
)
)
)
Expand Down Expand Up @@ -1342,4 +1358,4 @@ def update_resource_params(self, nsx_resource_params):

if __name__ == '__main__':
nsxt_tier1 = NSXTTier1()
nsxt_tier1.realize()
nsxt_tier1.realize()