diff --git a/.gitignore b/.gitignore index c1d6856e..fd9d0ce1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,12 @@ .DS_Store # test output *.retry +# Eclipse IDE and Pydev Stuff +.project +org.eclipse.* +.settings/* +.pydevproject +.project +#tests/pydbg/* +Pipfile* +tests/pydbg diff --git a/galaxy.yml b/galaxy.yml index 1822b27e..c413f61d 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -2,20 +2,16 @@ namespace: vmware name: ansible_for_nsxt -version: 1.0.0 +version: 1.0.3 readme: README.md authors: -- Gautam Verma @ggverma (https://vmware.slack.com/archives/CTE293BSS) -- Rahul Raghuvanshi @r-raghu (https://vmware.slack.com/archives/CTE293BSS) +- Gautam Verma +- Rahul Raghuvanshi description: Ansible Modules for NSX-t -license: -- GPL-3.0-only -- BSD-2-Clause-FreeBSD - license_file: LICENSE.txt tags: [vmware, ansible, nsxt] diff --git a/plugins/module_utils/common_utils.py b/plugins/module_utils/common_utils.py index 6fbbb92c..ca095bd0 100644 --- a/plugins/module_utils/common_utils.py +++ b/plugins/module_utils/common_utils.py @@ -164,3 +164,82 @@ def get_upgrade_orchestrator_node(module, mgr_hostname, mgr_username, mgr_passwo module.fail_json(changed=True, msg='Error getting ip address of the upgrade' ' orchestrator node. Error: {}'.format(err)) return resp['service_properties']['enabled_on']; + +def build_url_query_string(parm_dict): + ''' + This function just builds up a URL query string of the form: + + ?parm1=val1&bool1=True&bool2=False + + ''' + qstring = "" + qlist = list() + for dkey in parm_dict.keys(): + if parm_dict[dkey] is not None: + if type(parm_dict[dkey]) is bool: + qlist.append("{}={}".format(dkey,str(parm_dict[dkey]))) + else: + qlist.append("{}={}".format(dkey,parm_dict[dkey])) + if qlist: + qstring = "?{}".format("&".join(qlist)) + return qstring + +def build_url_query_dict(params,query_keys): + ''' + The params dict in many of the modules contains a lot of keys. Some keys pertain + to the URL path, some to things like credentials, certificates etc. + We only want to process the ones relating to the query section of a URL. So the whole set of params is passed here + along with a filter defined as the set of keys pertaining to the query section. + The fields are filtered down + ''' + query_params_dict = { k:v for (k,v) in params.items() if k in query_keys } + return query_params_dict + +def do_objects_get(module,manager_url,module_params, + headers=dict(Accept='application/json'), validate_certs=True, ignore_errors=False): + + mgr_username = module_params["username"] + mgr_password = module_params["password"] + nsx_cert_path = module_params["nsx_cert_path"] + nsx_key_path = module_params["nsx_key_path"] + # If a cursor was provided, or a page size then we are making a single call + # If we test for a key that doesn't exist and trap + mp_keys = module_params.keys() + if ('cursor' in mp_keys and module_params['cursor'] is not None ) or ('page_size' in mp_keys and module_params['page_size'] is not None): + try: + (rc, resp) = request(manager_url, headers=dict(Accept='application/json'), + url_username=mgr_username, url_password=mgr_password, validate_certs=validate_certs, ignore_errors=True) + except Exception as err: + module.fail_json(msg='Error retrieving groups. Error [%s]' % (to_native(err))) + else: + # No cursor parameter was provided so all data is being fetched + # This might still require multiple calls if there are more objects than are allowed to be returned in a single call + still_more_groups = True + cursor = None + all_group_data = dict() + # all_group_data["results"] = list() + while still_more_groups: + if cursor: + # Add the cursor to the URL + url_with_cursor = "{}&cursor={}".format(manager_url,cursor) + else: + url_with_cursor = manager_url + try: + (rc, resp) = request(url_with_cursor, headers=dict(Accept='application/json'), + url_username=mgr_username, url_password=mgr_password, validate_certs=validate_certs, ignore_errors=True) + except Exception as err: + module.fail_json(msg='Error retrieving groups. Error [%s]' % (to_native(err))) + if not "cursor" in resp: + still_more_groups = False + else: + cursor = resp["cursor"] + # Add new results to existing results + # If this is the first add, all the other data besides the "results" needs to be added + if not "results" in all_group_data: + all_group_data = resp + else: + # JUst add the additionally fetched results + all_group_data["results"] += resp["results"] + resp = all_group_data + return resp + \ No newline at end of file diff --git a/plugins/module_utils/nsxt_resource_urls.py b/plugins/module_utils/nsxt_resource_urls.py index a8986e36..aa3217d0 100644 --- a/plugins/module_utils/nsxt_resource_urls.py +++ b/plugins/module_utils/nsxt_resource_urls.py @@ -67,3 +67,6 @@ BFD_PROFILE_URL = '/infra/bfd-profiles' GATEWAY_POLICY_URL = _DOMAIN_URL + '/{}/gateway-policies' + +LOCAL_POLICY_URL = '/policy/api/v1/infra' +GLOBAL_POLICY_URL = '/global-manager/api/v1/global-infra' diff --git a/plugins/modules/nsxt_policy_domain_deployment_maps_info.py b/plugins/modules/nsxt_policy_domain_deployment_maps_info.py new file mode 100644 index 00000000..0a0234be --- /dev/null +++ b/plugins/modules/nsxt_policy_domain_deployment_maps_info.py @@ -0,0 +1,180 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: nsxt_policy_domain_deployment_maps_info +short_description: List deployment maps for policy domain +description: Returns paginated list of policy domain deployment maps + Deployment maps relate to the local manager sites associated with a domain + + +version_added: "X.Y" +author: Ed McGuigan +options: + hostname: + description: Deployed NSX manager hostname. + required: true + type: str + username: + description: The username to authenticate with the NSX manager. + required: true + type: str + password: + description: The password to authenticate with the NSX manager. + required: true + type: str + ca_path: + description: Path to the CA bundle to be used to verify host's SSL + certificate + type: str + nsx_cert_path: + description: Path to the certificate created for the Principal + Identity using which the CRUD operations should be + performed + type: str + nsx_key_path: + description: + - Path to the certificate key created for the Principal Identity + using which the CRUD operations should be performed + - Must be specified if nsx_cert_path is specified + type: str + + global_infra: + description: Flag set to True when targeting a Global NSX Manager (Federation) + required: false + type: bool + + domain_id: + description: domain id for domain for which deployment maps + required: true + type: string + + page_size: + description: if there is a desire to fetch the data in chunks rather than all at + once, an integer specifying the maximum number of objects to fetch + required: false + type: integer + + cursor: + description: when a page_size is specified, the returned data includes a "cursor" that + must be provided in a subsequent call in order to carry on where the prior call + left off. User would need to capture the cursor value from one call and provide it + in the next call + required: false + type: string + + include_mark_for_delete_objects: + description: Show groups marked for deletion + required: false + type: bool + default: False + + included_fields: + description: Show groups marked for deletion + required: Comma separated list of fields that should be included in query result + type: string + default: False + + sort_ascending: + description: Used to reverse sort order by setting it to False + required: false + type: bool + default: True + + sort_by: + description: Field to sort on + required: false + type: string + default: + +''' + +EXAMPLES = ''' + - name: List domain deployment maps + vmware.ansible_for_nsxt.nsxt_policy_domain_deployment_maps: + hostname: "{{ inventory_hostname }}" + "username": "{{ username }}" + "password": "{{ password }}" + validate_certs: False + domain_id: "{{ nsxt_domain }}" + register: nsxt_domain_deployment_maps + delegate_to: 127.0.0.1 +''' + +RETURN = '''# ''' +import json +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.vmware_nsxt import vmware_argument_spec, request +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.policy_communicator import PolicyCommunicator +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.common_utils import build_url_query_dict, build_url_query_string, do_objects_get +from ansible.module_utils._text import to_native +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.nsxt_resource_urls import GLOBAL_POLICY_URL, LOCAL_POLICY_URL + +def main(): + # Fetch the specification of the absolute basic arguments needed to connect to the NSX Manager + argument_spec = PolicyCommunicator.get_vmware_argument_spec() + # The URL will need to be specified as being non-global or global and we will need a domain + URL_path_spec = dict( + global_infra=dict(type='bool', required=False, default=False), + domain_id=dict(type='str', required=False, default='default') + ) + ''' + Now add the arguments relating to query field in the URL for this GET method + All the options from the API are offered, including paging. Not sure when a user + might want to use paging but the option is provided. + If no paging specification is provided, I need to make sure that + all data is retrieved, looking for a returned cursor in the response + indicating that there is more data to fetch. + + NOTE: I suspect that the member_types filter parameter is not actually valid + for a Policy Group where membership is described by a series of expressions + and this may be an error when converting from MP ( Management Plane ) Groups + to Policy Groups + ''' + URL_query_spec = dict( + include_mark_for_delete_objects=dict(type='bool', required=False), + included_fields=dict(type='str', required=False), + sort_ascending=dict(type='bool', required=False, default=True), + sort_by=dict(type='str', required=False), + page_size=dict(type='int' , required=False ), + cursor=dict(type='str', required=False ) + ) + # Combine the base URL, URL path spec and URL query argument specs + URL_path_spec.update(URL_query_spec) + argument_spec.update(URL_path_spec) + # Some code to validate the arguments provided with the invocation of the module + # in a playbook versus the defined argument spec. + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) + + mgr_hostname = module.params['hostname'] + validate_certs = module.params['validate_certs'] + domain_id = module.params['domain_id'] + if module.params['global_infra']: + url_path_root = GLOBAL_POLICY_URL + else: + url_path_root = LOCAL_POLICY_URL + + # Need to build up a query string + url_query_string = build_url_query_string( build_url_query_dict(module.params, URL_query_spec.keys() ) ) + manager_url = 'https://{}{}/domains/{}/domain-deployment-maps'.format(mgr_hostname,url_path_root,domain_id,url_query_string) + + changed = False + ''' + We potentially need to loop to fetch all data the code here will be the same for + any object we are doing a GET on, not just Policy Groups, so I have put it into a function and put the function + in the common_utils package. + ''' + resp = do_objects_get(module,manager_url,module.params, + headers=dict(Accept='application/json'),validate_certs=validate_certs, ignore_errors=True) + + module.exit_json(changed=changed, **resp) +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/plugins/modules/nsxt_policy_domain_info.py b/plugins/modules/nsxt_policy_domain_info.py new file mode 100644 index 00000000..04a135a1 --- /dev/null +++ b/plugins/modules/nsxt_policy_domain_info.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: nsxt_policy_domain_info +short_description: List Policy Domains +description: Returns paginated list of policy domains + Policy Domains are associated with policy groups and DFW Policies to determine the sites + where those objects are used ( applied to ). On a local manager, there is only the default domain + + +version_added: "X.Y" +author: Ed McGuigan +options: + hostname: + description: Deployed NSX manager hostname. + required: true + type: str + username: + description: The username to authenticate with the NSX manager. + required: true + type: str + password: + description: The password to authenticate with the NSX manager. + required: true + type: str + ca_path: + description: Path to the CA bundle to be used to verify host's SSL + certificate + type: str + nsx_cert_path: + description: Path to the certificate created for the Principal + Identity using which the CRUD operations should be + performed + type: str + nsx_key_path: + description: + - Path to the certificate key created for the Principal Identity + using which the CRUD operations should be performed + - Must be specified if nsx_cert_path is specified + type: str + + global_infra: + description: Flag set to True when targeting a Global NSX Manager (Federation) + required: false + type: bool + + + page_size: + description: if there is a desire to fetch the data in chunks rather than all at + once, an integer specifying the maximum number of objects to fetch + required: false + type: integer + + cursor: + description: when a page_size is specified, the returned data includes a "cursor" that + must be provided in a subsequent call in order to carry on where the prior call + left off. User would need to capture the cursor value from one call and provide it + in the next call + required: false + type: string + + include_mark_for_delete_objects: + description: Show groups marked for deletion + required: false + type: bool + default: False + + included_fields: + description: Show groups marked for deletion + required: Comma separated list of fields that should be included in query result + type: string + default: False + + sort_ascending: + description: Used to reverse sort order by setting it to False + required: false + type: bool + default: True + + sort_by: + description: Field to sort on + required: false + type: string + default: + +''' + +EXAMPLES = ''' +- name: List Policy Groups + nsxt_policy_group_facts: + hostname: "10.192.167.137" + username: "admin" + password: "Admin!23Admin" + validate_certs: False +''' + +RETURN = '''# ''' +import json +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.vmware_nsxt import vmware_argument_spec, request +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.policy_communicator import PolicyCommunicator +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.common_utils import build_url_query_dict, build_url_query_string, do_objects_get +from ansible.module_utils._text import to_native +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.nsxt_resource_urls import GLOBAL_POLICY_URL, LOCAL_POLICY_URL + +def main(): + # Fetch the specification of the absolute basic arguments needed to connect to the NSX Manager + argument_spec = PolicyCommunicator.get_vmware_argument_spec() + # The URL will need to be specified as being non-global or global and we will need a domain + URL_path_spec = dict( + global_infra=dict(type='bool', required=False, default=False) + ) + ''' + Now add the arguments relating to query field in the URL for this GET method + All the options from the API are offered, including paging. Not sure when a user + might want to use paging but the option is provided. + If no paging specification is provided, I need to make sure that + all data is retrieved, looking for a returned cursor in the response + indicating that there is more data to fetch. + + NOTE: I suspect that the member_types filter parameter is not actually valid + for a Policy Group where membership is described by a series of expressions + and this may be an error when converting from MP ( Management Plane ) Groups + to Policy Groups + ''' + URL_query_spec = dict( + include_mark_for_delete_objects=dict(type='bool', required=False), + included_fields=dict(type='str', required=False), + sort_ascending=dict(type='bool', required=False, default=True), + sort_by=dict(type='str', required=False), + page_size=dict(type='int' , required=False ), + cursor=dict(type='str', required=False ) + ) + # Combine the base URL, URL path spec and URL query argument specs + URL_path_spec.update(URL_query_spec) + argument_spec.update(URL_path_spec) + # Some code to validate the arguments provided with the invocation of the module + # in a playbook versus the defined argument spec. + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) + + mgr_hostname = module.params['hostname'] + validate_certs = module.params['validate_certs'] + if module.params['global_infra']: + url_path_root = GLOBAL_POLICY_URL + else: + url_path_root = LOCAL_POLICY_URL + # Need to build up a query string + url_query_string = build_url_query_string( build_url_query_dict(module.params, URL_query_spec.keys() ) ) + manager_url = 'https://{}{}/domains'.format(mgr_hostname,url_path_root,url_query_string) + + changed = False + ''' + We potentially need to loop to fetch all data the code here will be the same for + any object we are doing a GET on, not just Policy Groups, so I have put it into a function and put the function + in the common_utils package. + ''' + resp = do_objects_get(module,manager_url,module.params, + headers=dict(Accept='application/json'),validate_certs=validate_certs, ignore_errors=True) + + module.exit_json(changed=changed, **resp) +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/plugins/modules/nsxt_policy_group_associations_info.py b/plugins/modules/nsxt_policy_group_associations_info.py new file mode 100644 index 00000000..b2b7c3ab --- /dev/null +++ b/plugins/modules/nsxt_policy_group_associations_info.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: nsxt_policy_group_associations_info +short_description: List policy groups associated with the specified object + + +version_added: "X.Y" +author: Ed McGuigan +options: + hostname: + description: Deployed NSX manager hostname. + required: true + type: str + username: + description: The username to authenticate with the NSX manager. + required: true + type: str + password: + description: The password to authenticate with the NSX manager. + required: true + type: str + ca_path: + description: Path to the CA bundle to be used to verify host's SSL + certificate + type: str + nsx_cert_path: + description: Path to the certificate created for the Principal + Identity using which the CRUD operations should be + performed + type: str + nsx_key_path: + description: + - Path to the certificate key created for the Principal Identity + using which the CRUD operations should be performed + - Must be specified if nsx_cert_path is specified + type: str + + global_infra: + description: Flag set to True when targeting a Global NSX Manager (Federation) + required: false + type: bool + + intent_path: + description: All of these URLs are specific to a single group and an ID is needed + required: true + type: string + + enforcement_point_path: + description: Required for some of the member types ( don't even understand it to be honest ) + required: false + type: string + + page_size: + description: if there is a desire to fetch the data in chunks rather than all at + once, an integer specifying the maximum number of objects to fetch + required: false + type: integer + cursor: + description: when a page_size is specified, the returned data includes a "cursor" that + must be provided in a subsequent call in order to carry on where the prior call + left off. User would need to capture the cursor value from one call and provide it + in the next call + required: false + type: string + sort_ascending: + description: Used to reverse sort order by setting it to False + required: false + type: bool + default: True + sort_by: + description: Field to sort on + required: false + type: string + default: + include_mark_for_delete_objects: + description: Show groups marked for deletion + required: false + type: bool + default: False + +''' +EXAMPLES = ''' + - name: Find referencing groups + vmware.ansible_for_nsxt.nsxt_policy_group_associations_info: + hostname: "{{ inventory_hostname }}" + "username": "{{ username }}" + "password": "{{ password }}" + validate_certs: False + global_infra: "{{ global_infra }}" + intent_path: "{{ item.0 }}" + enforcement_point_path: "{{ item.1 }}" + register: group_associations + delegate_to: 127.0.0.1 + loop: "{{ groups_wo_drs|product(enf_point_paths)|list }}" +''' + +RETURN = '''# ''' +import json +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.vmware_nsxt import vmware_argument_spec, request +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.policy_communicator import PolicyCommunicator +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.common_utils import build_url_query_dict, build_url_query_string, do_objects_get +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.nsxt_resource_urls import GLOBAL_POLICY_URL, LOCAL_POLICY_URL + +from ansible.module_utils._text import to_native + +def main(): + # Fetch the specification of the absolute basic arguments needed to connect to the NSX Manager + argument_spec = PolicyCommunicator.get_vmware_argument_spec() + # The URL will need to be specified as being non-global or global and we will need a domain + URL_path_spec = dict( + global_infra=dict(type='bool', required=False, default=False) + ) + URL_query_spec = dict( + cursor=dict(type='str', required=False ), + intent_path=dict(type='str', required=True ), + enforcement_point_path=dict(type='str', required=False ), + include_mark_for_delete_objects=dict(type='bool', required=False), + included_fields=dict(type='str', required=False), + page_size=dict(type='int' , required=False ), + sort_ascending=dict(type='bool', required=False, default=True), + sort_by=dict(type='str', required=False) + ) + # Combine the base URL and URL path spec + argument_spec.update(URL_path_spec) + argument_spec.update(URL_query_spec) + # Some code to validate the arguments provided with the invocation of the module + # in a playbook versus the defined argument spec and to get the require AnsibleModule object + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) + + mgr_hostname = module.params['hostname'] + mgr_username = module.params['username'] + mgr_password = module.params['password'] + validate_certs = module.params['validate_certs'] + if module.params['global_infra']: + url_path_root = GLOBAL_POLICY_URL + else: + url_path_root = LOCAL_POLICY_URL + + # Need to build up a query string + url_query_string = build_url_query_string( build_url_query_dict(module.params, URL_query_spec.keys() ) ) + manager_url = 'https://{}{}/group-associations{}'.format(mgr_hostname,url_path_root,url_query_string) + + changed = False + ''' + We potentially need to loop to fetch all data the code here will be the same for + any object we are doing a GET on, not just Policy Groups, so I have put it into a function and put the function + in the common_utils package. + ''' + resp = do_objects_get(module,manager_url,module.params, + headers=dict(Accept='application/json'),validate_certs=validate_certs, ignore_errors=True) + + module.exit_json(changed=changed, **resp) +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/plugins/modules/nsxt_policy_group_info.py b/plugins/modules/nsxt_policy_group_info.py new file mode 100644 index 00000000..8324eee4 --- /dev/null +++ b/plugins/modules/nsxt_policy_group_info.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: nsxt_policy_group_facts +short_description: List Policy Groups +description: Returns paginated list of policy groups + Policy Groups are used in Distributed Firewall Policies in three places: + - Source of a network traffic flow - group is resolved to a list of IP addresses + - Destination of a network traffic flow - group is resolved to a list of IP addresses + - Applied To which determines the VM on which a policy will be applied so the group is resolved + to a list of VMs + + Note that there is the potential for a very large number of groups to be returned. + +version_added: "X.Y" +author: Ed McGuigan +options: + hostname: + description: Deployed NSX manager hostname. + required: true + type: str + username: + description: The username to authenticate with the NSX manager. + required: true + type: str + password: + description: The password to authenticate with the NSX manager. + required: true + type: str + ca_path: + description: Path to the CA bundle to be used to verify host's SSL + certificate + type: str + nsx_cert_path: + description: Path to the certificate created for the Principal + Identity using which the CRUD operations should be + performed + type: str + nsx_key_path: + description: + - Path to the certificate key created for the Principal Identity + using which the CRUD operations should be performed + - Must be specified if nsx_cert_path is specified + type: str + + global_infra: + description: Flag set to True when targeting a Global NSX Manager (Federation) + required: false + type: bool + + domain_id: + description: The domain string value to be used in the query, usually "default" + required: false + type: string + default: default + + page_size: + description: if there is a desire to fetch the data in chunks rather than all at + once, an integer specifying the maximum number of objects to fetch + required: false + type: integer + + cursor: + description: when a page_size is specified, the returned data includes a "cursor" that + must be provided in a subsequent call in order to carry on where the prior call + left off. User would need to capture the cursor value from one call and provide it + in the next call + required: false + type: string + + sort_ascending: + description: Used to reverse sort order by setting it to False + required: false + type: bool + default: True + + sort_by: + description: Field to sort on + required: false + type: string + default: + + include_mark_for_delete_objects: + description: Show groups marked for deletion + required: false + type: bool + default: False +''' + +EXAMPLES = ''' +- name: List Policy Groups + nsxt_policy_group_facts: + hostname: "10.192.167.137" + username: "admin" + password: "Admin!23Admin" + validate_certs: False +''' + +RETURN = '''# ''' +import json +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.vmware_nsxt import vmware_argument_spec, request +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.policy_communicator import PolicyCommunicator +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.common_utils import build_url_query_dict, build_url_query_string, do_objects_get +from ansible.module_utils._text import to_native +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.nsxt_resource_urls import GLOBAL_POLICY_URL, LOCAL_POLICY_URL + +def main(): + # Fetch the specification of the absolute basic arguments needed to connect to the NSX Manager + argument_spec = PolicyCommunicator.get_vmware_argument_spec() + # The URL will need to be specified as being non-global or global and we will need a domain + URL_path_spec = dict( + global_infra=dict(type='bool', required=False, default=False), + domain_id=dict(type='str', required=False, default='default') + ) + ''' + Now add the arguments relating to query field in the URL for this GET method + All the options from the API are offered, including paging. Not sure when a user + might want to use paging but the option is provided. + If no paging specification is provided, I need to make sure that + all data is retrieved, looking for a returned cursor in the response + indicating that there is more data to fetch. + + NOTE: I suspect that the member_types filter parameter is not actually valid + for a Policy Group where membership is described by a series of expressions + and this may be an error when converting from MP ( Management Plane ) Groups + to Policy Groups + ''' + URL_query_spec = dict( + include_mark_for_delete_objects=dict(type='bool', required=False), + included_fields=dict(type='str', required=False), + member_types=dict(type='str', required=False), + sort_ascending=dict(type='bool', required=False, default=True), + sort_by=dict(type='str', required=False), + page_size=dict(type='int' , required=False ), + cursor=dict(type='str', required=False ) + ) + # Combine the base URL, URL path spec and URL query argument specs + URL_path_spec.update(URL_query_spec) + argument_spec.update(URL_path_spec) + # Some code to validate the arguments provided with the invocation of the module + # in a playbook versus the defined argument spec. + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) + + mgr_hostname = module.params['hostname'] + validate_certs = module.params['validate_certs'] + domain_id = module.params['domain_id'] + if module.params['global_infra']: + url_path_root = GLOBAL_POLICY_URL + else: + url_path_root = LOCAL_POLICY_URL + + # Need to build up a query string + url_query_string = build_url_query_string( build_url_query_dict(module.params, URL_query_spec.keys() ) ) + manager_url = 'https://{}{}/domains/{}/groups{}'.format(mgr_hostname,url_path_root,domain_id,url_query_string) + + changed = False + ''' + We potentially need to loop to fetch all data the code here will be the same for + any object we are doing a GET on, not just Policy Groups, so I have put it into a function and put the function + in the common_utils package. + ''' + resp = do_objects_get(module,manager_url,module.params, + headers=dict(Accept='application/json'),validate_certs=validate_certs, ignore_errors=True) + + module.exit_json(changed=changed, **resp) +if __name__ == '__main__': + main() diff --git a/plugins/modules/nsxt_policy_group_member_info.py b/plugins/modules/nsxt_policy_group_member_info.py new file mode 100644 index 00000000..074b66ba --- /dev/null +++ b/plugins/modules/nsxt_policy_group_member_info.py @@ -0,0 +1,178 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: nsxt_policy_group_members +short_description: List Policy Group Members +description: Returns member data for policy groups with the exception of +consolidated-effective-ip-addresses because that one has a different +set of parameters for the query section of the GET URL + +version_added: "X.Y" +author: Ed McGuigan +options: + hostname: + description: Deployed NSX manager hostname. + required: true + type: str + username: + description: The username to authenticate with the NSX manager. + required: true + type: str + password: + description: The password to authenticate with the NSX manager. + required: true + type: str + ca_path: + description: Path to the CA bundle to be used to verify host's SSL + certificate + type: str + nsx_cert_path: + description: Path to the certificate created for the Principal + Identity using which the CRUD operations should be + performed + type: str + nsx_key_path: + description: + - Path to the certificate key created for the Principal Identity + using which the CRUD operations should be performed + - Must be specified if nsx_cert_path is specified + type: str + + global_infra: + description: Flag set to True when targeting a Global NSX Manager (Federation) + required: false + type: bool + + domain_id: + description: The domain string value to be used in the query, usually "default" + required: false + type: string + default: default + group_id: + description: All of these URLs are specific to a single group and an ID is needed + member_type: + description: A group can have members of various types and each type can be specified as the one + for which member information is desired: + - member-types + - ip-addresses + - logical-ports + - logical-switches + - segment-ports + - segments + - vifs + - virtual-machines + page_size: + description: if there is a desire to fetch the data in chunks rather than all at + once, an integer specifying the maximum number of objects to fetch + required: false + type: integer + cursor: + description: when a page_size is specified, the returned data includes a "cursor" that + must be provided in a subsequent call in order to carry on where the prior call + left off. User would need to capture the cursor value from one call and provide it + in the next call + required: false + type: string + sort_ascending: + description: Used to reverse sort order by setting it to False + required: false + type: bool + default: True + sort_by: + description: Field to sort on + required: false + type: string + default: + include_mark_for_delete_objects: + description: Show groups marked for deletion + required: false + type: bool + default: False + enforcement_point_path: + description: Required for some of the member types ( don't even understand it to be honest ) +''' +EXAMPLES = ''' +- name: List Group Members - VMs + nsxt_policy_group_members: + hostname: "10.192.167.137" + username: "admin" + password: "Admin!23Admin" + validate_certs: False + domain_id: "default" + group_id: + member_type: "virtual-machines" +''' + +RETURN = '''# ''' +import json +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.vmware_nsxt import vmware_argument_spec, request +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.policy_communicator import PolicyCommunicator +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.common_utils import build_url_query_dict, build_url_query_string, do_objects_get +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.nsxt_resource_urls import GLOBAL_POLICY_URL, LOCAL_POLICY_URL + +from ansible.module_utils._text import to_native + +def main(): + # Fetch the specification of the absolute basic arguments needed to connect to the NSX Manager + argument_spec = PolicyCommunicator.get_vmware_argument_spec() + # The URL will need to be specified as being non-global or global and we will need a domain + URL_path_spec = dict( + global_infra=dict(type='bool', required=False, default=False), + domain_id=dict(type='str', required=False, default='default'), + group_id=dict(type='str', required=False, default='default'), + member_type=dict(type='str', required=True) + ) + URL_query_spec = dict( + cursor=dict(type='str', required=False ), + enforcement_point_path=dict(type='str', required=False ), + include_mark_for_delete_objects=dict(type='bool', required=False), + included_fields=dict(type='str', required=False), + page_size=dict(type='int' , required=False ), + sort_ascending=dict(type='bool', required=False, default=True), + sort_by=dict(type='str', required=False) + ) + # Combine the base URL and URL path spec + argument_spec.update(URL_path_spec) + argument_spec.update(URL_query_spec) + # Some code to validate the arguments provided with the invocation of the module + # in a playbook versus the defined argument spec and to get the require AnsibleModule object + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) + + mgr_hostname = module.params['hostname'] + mgr_username = module.params['username'] + mgr_password = module.params['password'] + validate_certs = module.params['validate_certs'] + member_type = module.params['member_type'] + domain_id = module.params['domain_id'] + group_id = module.params['group_id'] + if module.params['global_infra']: + url_path_root = GLOBAL_POLICY_URL + else: + url_path_root = LOCAL_POLICY_URL + + # Need to build up a query string + url_query_string = build_url_query_string( build_url_query_dict(module.params, URL_query_spec.keys() ) ) + manager_url = 'https://{}{}/domains/{}/groups/{}/members/{}{}'.format(mgr_hostname,url_path_root,domain_id,group_id,member_type,url_query_string) + + changed = False + ''' + We potentially need to loop to fetch all data the code here will be the same for + any object we are doing a GET on, not just Policy Groups, so I have put it into a function and put the function + in the common_utils package. + ''' + resp = do_objects_get(module,manager_url,module.params, + headers=dict(Accept='application/json'),validate_certs=validate_certs, ignore_errors=True) + + module.exit_json(changed=changed, **resp) +if __name__ == '__main__': + main() diff --git a/plugins/modules/nsxt_policy_group_member_types.py b/plugins/modules/nsxt_policy_group_member_types.py new file mode 100644 index 00000000..1e25ecd3 --- /dev/null +++ b/plugins/modules/nsxt_policy_group_member_types.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: nsxt_policy_group_member_types +short_description: List Policy Group Member Types for a specific Policy Grooup ID +description: Returns member types data for a policy group. + +version_added: "X.Y" +author: Ed McGuigan +options: + hostname: + description: Deployed NSX manager hostname. + required: true + type: str + username: + description: The username to authenticate with the NSX manager. + required: true + type: str + password: + description: The password to authenticate with the NSX manager. + required: true + type: str + ca_path: + description: Path to the CA bundle to be used to verify host's SSL + certificate + type: str + nsx_cert_path: + description: Path to the certificate created for the Principal + Identity using which the CRUD operations should be + performed + type: str + nsx_key_path: + description: + - Path to the certificate key created for the Principal Identity + using which the CRUD operations should be performed + - Must be specified if nsx_cert_path is specified + type: str + + global_infra: + description: Flag set to True when targeting a Global NSX Manager (Federation) + required: false + type: bool + + domain_id: + description: The domain string value to be used in the query, usually "default" + required: false + type: string + default: default + group_id: + description: All of these URLs are specific to a single group and an ID is needed + +''' +EXAMPLES = ''' +- name: List Group Members - VMs + nsxt_policy_group_members: + hostname: "10.192.167.137" + username: "admin" + password: "Admin!23Admin" + validate_certs: False + domain_id: "default" + group_id: +''' + +RETURN = '''# ''' +import json +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.vmware_nsxt import vmware_argument_spec, request +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.policy_communicator import PolicyCommunicator +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.common_utils import build_url_query_dict, build_url_query_string, do_objects_get +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.nsxt_resource_urls import GLOBAL_POLICY_URL, LOCAL_POLICY_URL +from ansible.module_utils._text import to_native + +def main(): + # Fetch the specification of the absolute basic arguments needed to connect to the NSX Manager + argument_spec = PolicyCommunicator.get_vmware_argument_spec() + # The URL will need to be specified as being non-global or global and we will need a domain + URL_path_spec = dict( + global_infra=dict(type='bool', required=False, default=False), + domain_id=dict(type='str', required=False, default='default'), + group_id=dict(type='str', required=False, default='default') + ) + # Combine the base URL and URL path spec + argument_spec.update(URL_path_spec) + # Some code to validate the arguments provided with the invocation of the module + # in a playbook versus the defined argument spec and to get the require AnsibleModule object + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) + + mgr_hostname = module.params['hostname'] + mgr_username = module.params['username'] + mgr_password = module.params['password'] + validate_certs = module.params['validate_certs'] + domain_id = module.params['domain_id'] + group_id = module.params['group_id'] + if module.params['global_infra']: + url_path_root = GLOBAL_POLICY_URL + else: + url_path_root = LOCAL_POLICY_URL + + manager_url = 'https://{}{}/domains/{}/groups/{}/member-types'.format(mgr_hostname,url_path_root,domain_id,group_id) + + changed = False + ''' + With member types we have no cursor or paging and all data should be retrieved with a single + request + ''' + try: + (rc, resp) = request(manager_url, headers=dict(Accept='application/json'), + url_username=mgr_username, url_password=mgr_password, validate_certs=validate_certs, ignore_errors=True) + except Exception as err: + module.fail_json(msg='Error retrieving groups. Error [%s]' % (to_native(err))) + + module.exit_json(changed=changed, **resp) + +if __name__ == '__main__': + main() diff --git a/plugins/modules/nsxt_policy_security_policy_facts.py b/plugins/modules/nsxt_policy_security_policy_facts.py new file mode 100644 index 00000000..bbae785b --- /dev/null +++ b/plugins/modules/nsxt_policy_security_policy_facts.py @@ -0,0 +1,181 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: nsxt_policy_security_policy_facts +short_description: List Policy Security Policies +description: Returns paginated list of policy security policies + Security Policies are collections of firewall rules + +version_added: "X.Y" +author: Ed McGuigan +options: + hostname: + description: Deployed NSX manager hostname. + required: true + type: str + username: + description: The username to authenticate with the NSX manager. + required: true + type: str + password: + description: The password to authenticate with the NSX manager. + required: true + type: str + ca_path: + description: Path to the CA bundle to be used to verify host's SSL + certificate + type: str + nsx_cert_path: + description: Path to the certificate created for the Principal + Identity using which the CRUD operations should be + performed + type: str + nsx_key_path: + description: + - Path to the certificate key created for the Principal Identity + using which the CRUD operations should be performed + - Must be specified if nsx_cert_path is specified + type: str + + global_infra: + description: Flag set to True when targeting a Global NSX Manager (Federation) + required: false + type: bool + + domain_id: + description: The domain string value to be used in the query, usually "default" + required: false + type: string + default: default + + page_size: + description: if there is a desire to fetch the data in chunks rather than all at + once, an integer specifying the maximum number of objects to fetch + required: false + type: integer + + cursor: + description: when a page_size is specified, the returned data includes a "cursor" that + must be provided in a subsequent call in order to carry on where the prior call + left off. User would need to capture the cursor value from one call and provide it + in the next call + required: false + type: string + + sort_ascending: + description: Used to reverse sort order by setting it to False + required: false + type: bool + default: True + + sort_by: + description: Field to sort on + required: false + type: string + default: + + include_mark_for_delete_objects: + description: Show groups marked for deletion + required: false + type: bool + default: False + + included_fields: + description: Comma separated list of fields that should be included in query result + required: false + type: string + default: undef + + include_rule_count: + type: bool + default: False +''' + +EXAMPLES = ''' +- name: List Policy Security Policies + nsxt_policy_security_policy_facts: + hostname: "10.192.167.137" + username: "admin" + password: "Admin!23Admin" + validate_certs: False +''' + +RETURN = '''# ''' +import json +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.vmware_nsxt import vmware_argument_spec, request +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.policy_communicator import PolicyCommunicator +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.common_utils import build_url_query_dict, build_url_query_string, do_objects_get +from ansible.module_utils._text import to_native +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.nsxt_resource_urls import GLOBAL_POLICY_URL, LOCAL_POLICY_URL + +def main(): + # Fetch the specification of the absolute basic arguments needed to connect to the NSX Manager + argument_spec = PolicyCommunicator.get_vmware_argument_spec() + # The URL will need to be specified as being non-global or global and we will need a domain + URL_path_spec = dict( + global_infra=dict(type='bool', required=False, default=False), + domain_id=dict(type='str', required=False, default='default') + ) + ''' + Now add the arguments relating to query field in the URL for this GET method + All the options from the API are offered, including paging. Not sure when a user + might want to use paging but the option is provided. + If no paging specification is provided, I need to make sure that + all data is retrieved, looking for a returned cursor in the response + indicating that there is more data to fetch. + + NOTE: I suspect that the member_types filter parameter is not actually valid + for a Policy Group where membership is described by a series of expressions + and this may be an error when converting from MP ( Management Plane ) Groups + to Policy Groups + ''' + URL_query_spec = dict( + include_mark_for_delete_objects=dict(type='bool', required=False), + included_fields=dict(type='str', required=False), + include_rule_count=dict(type='bool',required=False), + sort_ascending=dict(type='bool', required=False, default=True), + sort_by=dict(type='str', required=False), + page_size=dict(type='int' , required=False ), + cursor=dict(type='str', required=False ) + ) + # Combine the base URL, URL path spec and URL query argument specs + URL_path_spec.update(URL_query_spec) + argument_spec.update(URL_path_spec) + # Some code to validate the arguments provided with the invocation of the module + # in a playbook versus the defined argument spec. + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) + + mgr_hostname = module.params['hostname'] + validate_certs = module.params['validate_certs'] + domain_id = module.params['domain_id'] + if module.params['global_infra']: + url_path_root = GLOBAL_POLICY_URL + else: + url_path_root = LOCAL_POLICY_URL + + # Need to build up a query string + url_query_string = build_url_query_string( build_url_query_dict(module.params, URL_query_spec.keys() ) ) + manager_url = 'https://{}{}/domains/{}/security-policies{}'.format(mgr_hostname,url_path_root,domain_id,url_query_string) + + changed = False + ''' + We potentially need to loop to fetch all data the code here will be the same for + any object we are doing a GET on, not just Policy Groups, so I have put it into a function and put the function + in the common_utils package. + ''' + resp = do_objects_get(module,manager_url,module.params, + headers=dict(Accept='application/json'),validate_certs=validate_certs, ignore_errors=True) + + module.exit_json(changed=changed, **resp) +if __name__ == '__main__': + main() diff --git a/plugins/modules/nsxt_policy_security_policy_rule_stats.py b/plugins/modules/nsxt_policy_security_policy_rule_stats.py new file mode 100644 index 00000000..823fdcfb --- /dev/null +++ b/plugins/modules/nsxt_policy_security_policy_rule_stats.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: nsxt_policy_security_policy_rules_stats +short_description: List Policy Security Policy rule stats +description: Returns statistics for a security policy rule + +version_added: "X.Y" +author: Ed McGuigan +options: + hostname: + description: Deployed NSX manager hostname. + required: true + type: str + username: + description: The username to authenticate with the NSX manager. + required: true + type: str + password: + description: The password to authenticate with the NSX manager. + required: true + type: str + ca_path: + description: Path to the CA bundle to be used to verify host's SSL + certificate + type: str + nsx_cert_path: + description: Path to the certificate created for the Principal + Identity using which the CRUD operations should be + performed + type: str + nsx_key_path: + description: + - Path to the certificate key created for the Principal Identity + using which the CRUD operations should be performed + - Must be specified if nsx_cert_path is specified + type: str + + global_infra: + description: Flag set to True when targeting a Global NSX Manager (Federation) + required: false + type: bool + + domain_id: + description: The domain string value to be used in the query, usually "default" + required: false + type: string + default: default + + policy_id: + description: ID for a specific security policy + required: true + type: string + default: NONE + + rule_id: + description: id for the rule + required: true + type: string + default: NONE + + enforcement_point_path: + description: enforcement point + required: False + type: string + default: NONE + +''' + +EXAMPLES = ''' +- name: List Policy Security Policies + nsxt_policy_security_policy_facts: + hostname: "10.192.167.137" + username: "admin" + password: "Admin!23Admin" + validate_certs: False +''' + +RETURN = '''# ''' +import json +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.vmware_nsxt import vmware_argument_spec, request +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.policy_communicator import PolicyCommunicator +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.common_utils import build_url_query_dict, build_url_query_string, do_objects_get +from ansible.module_utils._text import to_native + +def main(): + # Fetch the specification of the absolute basic arguments needed to connect to the NSX Manager + argument_spec = PolicyCommunicator.get_vmware_argument_spec() + # The URL will need to be specified as being non-global or global and we will need a domain + URL_path_spec = dict( + global_infra=dict(type='bool', required=False, default=False), + domain_id=dict(type='str', required=False, default='default'), + policy_id=dict(type='str', required=True), + rule_id=dict(type='str', required=True) + ) + ''' + Now add the arguments relating to query field in the URL for this GET method + All the options from the API are offered, including paging. Not sure when a user + might want to use paging but the option is provided. + If no paging specification is provided, I need to make sure that + all data is retrieved, looking for a returned cursor in the response + indicating that there is more data to fetch. + + NOTE: I suspect that the member_types filter parameter is not actually valid + for a Policy Group where membership is described by a series of expressions + and this may be an error when converting from MP ( Management Plane ) Groups + to Policy Groups + ''' + URL_query_spec = dict( + enforcement_point_path=dict(type='str', required=False) + ) + # Combine the base URL, URL path spec and URL query argument specs + URL_path_spec.update(URL_query_spec) + argument_spec.update(URL_path_spec) + # Some code to validate the arguments provided with the invocation of the module + # in a playbook versus the defined argument spec. + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) + + mgr_hostname = module.params['hostname'] + validate_certs = module.params['validate_certs'] + domain_id = module.params['domain_id'] + policy_id = module.params['policy_id'] + rule_id = module.params['rule_id'] + if module.params['global_infra']: + infra_string = 'global-infra' + else: + infra_string = 'infra' + + # Need to build up a query string + url_query_string = build_url_query_string( build_url_query_dict(module.params, URL_query_spec.keys() ) ) + manager_url = 'https://{}/policy/api/v1/{}/domains/{}/security-policies/{}/rules/{}/statistics{}'.format(mgr_hostname,infra_string,domain_id,policy_id,rule_id,url_query_string) + print("**** Manager URL {}".format(manager_url)) + + changed = False + ''' + We potentially need to loop to fetch all data the code here will be the same for + any object we are doing a GET on, not just Policy Groups, so I have put it into a function and put the function + in the common_utils package. + ''' + resp = do_objects_get(module,manager_url,module.params, + headers=dict(Accept='application/json'),validate_certs=validate_certs, ignore_errors=True) + + module.exit_json(changed=changed, **resp) +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/plugins/modules/nsxt_policy_security_policy_rules_facts.py b/plugins/modules/nsxt_policy_security_policy_rules_facts.py new file mode 100644 index 00000000..11da9722 --- /dev/null +++ b/plugins/modules/nsxt_policy_security_policy_rules_facts.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: nsxt_policy_security_policy_rules_facts +short_description: List Policy Security Policy rules +description: Returns paginated list of firewall rules for a policy security policy + Security Policies are collections of firewall rules + +version_added: "X.Y" +author: Ed McGuigan +options: + hostname: + description: Deployed NSX manager hostname. + required: true + type: str + username: + description: The username to authenticate with the NSX manager. + required: true + type: str + password: + description: The password to authenticate with the NSX manager. + required: true + type: str + ca_path: + description: Path to the CA bundle to be used to verify host's SSL + certificate + type: str + nsx_cert_path: + description: Path to the certificate created for the Principal + Identity using which the CRUD operations should be + performed + type: str + nsx_key_path: + description: + - Path to the certificate key created for the Principal Identity + using which the CRUD operations should be performed + - Must be specified if nsx_cert_path is specified + type: str + + global_infra: + description: Flag set to True when targeting a Global NSX Manager (Federation) + required: false + type: bool + + domain_id: + description: The domain string value to be used in the query, usually "default" + required: false + type: string + default: default + + policy_id: + description: the UUID for a specific security policy + required: true + type: string + default: NONE + + page_size: + description: if there is a desire to fetch the data in chunks rather than all at + once, an integer specifying the maximum number of objects to fetch + required: false + type: integer + + cursor: + description: when a page_size is specified, the returned data includes a "cursor" that + must be provided in a subsequent call in order to carry on where the prior call + left off. User would need to capture the cursor value from one call and provide it + in the next call + required: false + type: string + + sort_ascending: + description: Used to reverse sort order by setting it to False + required: false + type: bool + default: True + + sort_by: + description: Field to sort on + required: false + type: string + default: + + include_mark_for_delete_objects: + description: Show groups marked for deletion + required: false + type: bool + default: False + + included_fields: + description: Comma separated list of fields that should be included in query result + required: false + type: string + default: undef + +<<<<<<< HEAD + +======= +>>>>>>> Added modules to retrieve policy group and security policy objects +''' + +EXAMPLES = ''' +- name: List Policy Security Policies + nsxt_policy_security_policy_facts: + hostname: "10.192.167.137" + username: "admin" + password: "Admin!23Admin" + validate_certs: False +<<<<<<< HEAD + domain_id: default +======= +>>>>>>> Added modules to retrieve policy group and security policy objects +''' + +RETURN = '''# ''' +import json +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.vmware_nsxt import vmware_argument_spec, request +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.policy_communicator import PolicyCommunicator +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.common_utils import build_url_query_dict, build_url_query_string, do_objects_get +from ansible.module_utils._text import to_native +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.nsxt_resource_urls import GLOBAL_POLICY_URL, LOCAL_POLICY_URL + +def main(): + # Fetch the specification of the absolute basic arguments needed to connect to the NSX Manager + argument_spec = PolicyCommunicator.get_vmware_argument_spec() + # The URL will need to be specified as being non-global or global and we will need a domain + URL_path_spec = dict( + global_infra=dict(type='bool', required=False, default=False), + domain_id=dict(type='str', required=False, default='default'), + policy_id=dict(type='str', required=True) + ) + ''' + Now add the arguments relating to query field in the URL for this GET method + All the options from the API are offered, including paging. Not sure when a user + might want to use paging but the option is provided. + If no paging specification is provided, I need to make sure that + all data is retrieved, looking for a returned cursor in the response + indicating that there is more data to fetch. + + NOTE: I suspect that the member_types filter parameter is not actually valid + for a Policy Group where membership is described by a series of expressions + and this may be an error when converting from MP ( Management Plane ) Groups + to Policy Groups + ''' + URL_query_spec = dict( + include_mark_for_delete_objects=dict(type='bool', required=False), + included_fields=dict(type='str', required=False), + sort_ascending=dict(type='bool', required=False, default=True), + sort_by=dict(type='str', required=False), + page_size=dict(type='int' , required=False ), + cursor=dict(type='str', required=False ) + ) + # Combine the base URL, URL path spec and URL query argument specs + URL_path_spec.update(URL_query_spec) + argument_spec.update(URL_path_spec) + # Some code to validate the arguments provided with the invocation of the module + # in a playbook versus the defined argument spec. + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) + + mgr_hostname = module.params['hostname'] + validate_certs = module.params['validate_certs'] + domain_id = module.params['domain_id'] + policy_id = module.params['policy_id'] + if module.params['global_infra']: + url_path_root = GLOBAL_POLICY_URL + else: + url_path_root = LOCAL_POLICY_URL + + # Need to build up a query string + url_query_string = build_url_query_string( build_url_query_dict(module.params, URL_query_spec.keys() ) ) + manager_url = 'https://{}{}/domains/{}/security-policies/{}/rules{}'.format(mgr_hostname,url_path_root,domain_id,policy_id,url_query_string) + + changed = False + ''' + We potentially need to loop to fetch all data the code here will be the same for + any object we are doing a GET on, not just Policy Groups, so I have put it into a function and put the function + in the common_utils package. + ''' + resp = do_objects_get(module,manager_url,module.params, + headers=dict(Accept='application/json'),validate_certs=validate_certs, ignore_errors=True) + + module.exit_json(changed=changed, **resp) +if __name__ == '__main__': + main() diff --git a/plugins/modules/nsxt_vm_facts.py b/plugins/modules/nsxt_vm_facts.py new file mode 100644 index 00000000..72fa6e42 --- /dev/null +++ b/plugins/modules/nsxt_vm_facts.py @@ -0,0 +1,161 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: nsxt_vm_facts +short_description: List VMs +description: Returns paginated list of VMs + + Note that there is the potential for a very large number of VMs to be returned. + +version_added: "X.Y" +author: Ed McGuigan +options: + hostname: + description: Deployed NSX manager hostname. + required: true + type: str + username: + description: The username to authenticate with the NSX manager. + required: true + type: str + password: + description: The password to authenticate with the NSX manager. + required: true + type: str + ca_path: + description: Path to the CA bundle to be used to verify host's SSL + certificate + type: str + nsx_cert_path: + description: Path to the certificate created for the Principal + Identity using which the CRUD operations should be + performed + type: str + nsx_key_path: + description: + - Path to the certificate key created for the Principal Identity + using which the CRUD operations should be performed + - Must be specified if nsx_cert_path is specified + type: str + + global_infra: + description: Flag set to True when targeting a Global NSX Manager (Federation) + required: false + type: bool + + domain_id: + description: The domain string value to be used in the query, usually "default" + required: false + type: string + default: default + + page_size: + description: if there is a desire to fetch the data in chunks rather than all at + once, an integer specifying the maximum number of objects to fetch + required: false + type: integer + + cursor: + description: when a page_size is specified, the returned data includes a "cursor" that + must be provided in a subsequent call in order to carry on where the prior call + left off. User would need to capture the cursor value from one call and provide it + in the next call + required: false + type: string + + sort_ascending: + description: Used to reverse sort order by setting it to False + required: false + type: bool + default: True + + sort_by: + description: Field to sort on + required: false + type: string + default: + + include_mark_for_delete_objects: + description: Show groups marked for deletion + required: false + type: bool + default: False +''' + +EXAMPLES = ''' +- name: List VMs + nsxt_policy_group_facts: + hostname: "10.192.167.137" + username: "admin" + password: "Admin!23Admin" + validate_certs: False +''' + +RETURN = '''# ''' +import json +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.vmware_nsxt import vmware_argument_spec, request +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.policy_communicator import PolicyCommunicator +from ansible_collections.vmware.ansible_for_nsxt.plugins.module_utils.common_utils import build_url_query_dict, build_url_query_string, do_objects_get +from ansible.module_utils._text import to_native + +def main(): + # Fetch the specification of the absolute basic arguments needed to connect to the NSX Manager + argument_spec = PolicyCommunicator.get_vmware_argument_spec() + ''' + Now add the arguments relating to query field in the URL for this GET method + All the options from the API are offered, including paging. Not sure when a user + might want to use paging but the option is provided. + If no paging specification is provided, I need to make sure that + all data is retrieved, looking for a returned cursor in the response + indicating that there is more data to fetch. + + NOTE: I suspect that the member_types filter parameter is not actually valid + for a Policy Group where membership is described by a series of expressions + and this may be an error when converting from MP ( Management Plane ) Groups + to Policy Groups + ''' + URL_query_spec = dict( + included_fields=dict(type='str', required=False), + display_name=dict(type='str', required=False), + external_id=dict(type='str', required=False), + host_id=dict(type='str', required=False), + sort_ascending=dict(type='bool', required=False, default=True), + sort_by=dict(type='str', required=False), + page_size=dict(type='int' , required=False ), + cursor=dict(type='str', required=False ) + ) + # Combine the base URL and URL query argument specs + argument_spec.update(URL_query_spec) + # Some code to validate the arguments provided with the invocation of the module + # in a playbook versus the defined argument spec. + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) + + mgr_hostname = module.params['hostname'] + validate_certs = module.params['validate_certs'] + + # Need to build up a query string + url_query_string = build_url_query_string( build_url_query_dict(module.params, URL_query_spec.keys() ) ) + manager_url = 'https://{}/api/v1/fabric/virtual-machines{}'.format(mgr_hostname,url_query_string) + + changed = False + ''' + We potentially need to loop to fetch all data the code here will be the same for + any object we are doing a GET on, not just Policy Groups, so I have put it into a function and put the function + in the common_utils package. + ''' + resp = do_objects_get(module,manager_url,module.params, + headers=dict(Accept='application/json'),validate_certs=validate_certs, ignore_errors=True) + + module.exit_json(changed=changed, **resp) +if __name__ == '__main__': + main() \ No newline at end of file