From 47758bca8b3bc6eafc536ccd853189ed14e559ae Mon Sep 17 00:00:00 2001 From: "Xander de Kreij (Europe)" Date: Tue, 21 Jul 2020 13:33:02 +0200 Subject: [PATCH 1/2] added ddns_protected support --- .../plugins/modules/nios_host_record.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_host_record.py b/ansible_collection/infoblox/nios_modules/plugins/modules/nios_host_record.py index b936779a..0dd2edcd 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_host_record.py +++ b/ansible_collection/infoblox/nios_modules/plugins/modules/nios_host_record.py @@ -50,6 +50,12 @@ default: true aliases: - dns + ddns_protected: + description: + - Protect your DNS record from being overwritten by a dynamic dns update + type: bool + required: false + default: false ipv4addrs: description: - Configures the IPv4 addresses for this host record. This argument @@ -131,6 +137,20 @@ ''' EXAMPLES = ''' +- name: configure an ipv4 host record + nios_host_record: + name: host.ansible.com + ipv4: + - address: 192.168.10.1 + aliases: + - cname.ansible.com + state: present + ddns_protected: True + provider: + host: "{{ inventory_hostname_short }}" + username: admin + password: admin + connection: local - name: configure an ipv4 host record nios_host_record: name: host.ansible.com @@ -271,6 +291,7 @@ def main(): ipv6addrs=dict(type='list', aliases=['ipv6'], elements='dict', options=ipv6addr_spec, transform=ipv6addrs), configure_for_dns=dict(type='bool', default=True, required=False, aliases=['dns'], ib_req=True), aliases=dict(type='list'), + ddns_protected=dict(type='bool', default=False, required=False), ttl=dict(type='int'), From 3e88b11b4e7d23e91a2c7c4c5ee5fbd6943d2a90 Mon Sep 17 00:00:00 2001 From: xander Date: Tue, 24 Jan 2023 11:19:18 +0100 Subject: [PATCH 2/2] Merged with infoblox-ansible repository --- CHANGELOG.rst | 251 ++++++++ CONTRIBUTING.md | 31 + README.md | 191 +++--- .../infoblox/nios_modules/plugins/.DS_Store | Bin 10244 -> 0 bytes .../plugins/module_utils/network.py | 17 - changelogs/.plugin-cache.yaml | 131 +++++ changelogs/changelog.yaml | 200 +++++++ changelogs/config.yaml | 32 + galaxy.yml | 63 ++ meta/runtime.yml | 2 + obsolete/LICENSE | 201 ------- obsolete/library/infoblox_network.py | 264 --------- .../create_a_record.yaml | 0 .../create_cname_record.yaml | 0 .../create_dns_view.yml | 0 playbooks/create_dtc_lbdn.yml | 29 + playbooks/create_dtc_pool.yml | 25 + playbooks/create_dtc_server.yml | 19 + .../create_mx_record.yaml | 0 .../create_network.yml | 0 .../create_network_view.yml | 0 .../create_txt_record.yaml | 0 .../playbooks => playbooks}/create_zone.yml | 0 .../delete_cname_record.yaml | 0 .../delete_dnsview.yml | 0 .../delete_mx_record.yaml | 0 .../delete_network.yml | 0 .../delete_network_view.yml | 0 .../delete_txt_record.yaml | 0 .../playbooks => playbooks}/delete_zone.yml | 0 playbooks/restart_services.yml | 15 + .../update_a_record.yml | 0 .../plugins => plugins}/README.md | 0 plugins/doc_fragments/nios.py | 113 ++++ .../inventory/nios_inventory.py | 61 +- .../plugins => plugins}/lookup/nios_lookup.py | 49 +- .../lookup/nios_next_ip.py | 59 +- .../lookup/nios_next_network.py | 47 +- .../plugins => plugins}/module_utils/api.py | 257 +++++++- plugins/module_utils/network.py | 19 + .../modules/nios_a_record.py | 57 +- .../modules/nios_aaaa_record.py | 50 +- .../modules/nios_cname_record.py | 44 +- .../modules/nios_dns_view.py | 43 +- plugins/modules/nios_dtc_lbdn.py | 242 ++++++++ plugins/modules/nios_dtc_pool.py | 235 ++++++++ plugins/modules/nios_dtc_server.py | 144 +++++ .../modules/nios_fixed_address.py | 104 +++- .../modules/nios_host_record.py | 175 ++++-- .../modules/nios_member.py | 127 +++- .../modules/nios_mx_record.py | 45 +- .../modules/nios_naptr_record.py | 52 +- .../modules/nios_network.py | 78 ++- .../modules/nios_network_view.py | 37 +- .../modules/nios_nsgroup.py | 137 ++++- .../modules/nios_ptr_record.py | 38 +- plugins/modules/nios_restartservices.py | 144 +++++ .../modules/nios_srv_record.py | 49 +- .../modules/nios_txt_record.py | 35 +- .../plugins => plugins}/modules/nios_zone.py | 71 ++- requirements.txt | 1 + tests/ignore-2.10.txt | 114 ---- tests/ignore-2.9.txt | 114 ---- .../incidental_nios_prepare_tests/aliases | 1 - .../incidental_nios_txt_record/aliases | 3 - .../defaults/main.yaml | 3 - .../incidental_nios_txt_record/meta/main.yaml | 2 - .../incidental_nios_txt_record/tasks/main.yml | 1 - .../tasks/nios_txt_record_idempotence.yml | 80 --- .../{nios => targets}/nios_a_record/aliases | 0 .../nios_a_record/defaults/main.yaml | 0 .../nios_a_record/meta/main.yaml | 0 .../nios_a_record/tasks/main.yml | 0 .../tasks/nios_a_record_idempotence.yml | 0 .../nios_aaaa_record/aliases | 0 .../nios_aaaa_record/defaults/main.yaml | 0 .../nios_aaaa_record/meta/main.yaml | 0 .../nios_aaaa_record/tasks/main.yml | 0 .../tasks/nios_aaaa_record_idempotence.yml | 0 .../nios_cname_record/aliases | 0 .../nios_cname_record/defaults/main.yaml | 0 .../nios_cname_record/meta/main.yaml | 0 .../nios_cname_record/tasks/main.yml | 0 .../tasks/nios_cname_record_idempotence.yml | 0 .../{nios => targets}/nios_dns_view/aliases | 0 .../nios_dns_view/defaults/main.yaml | 0 .../nios_dns_view/meta/main.yaml | 0 .../nios_dns_view/tasks/main.yml | 0 .../tasks/nios_dns_view_idempotence.yml | 0 .../nios_host_record/aliases | 0 .../nios_host_record/defaults/main.yaml | 0 .../nios_host_record/meta/main.yaml | 0 .../nios_host_record/tasks/main.yml | 0 .../tasks/nios_host_record_idempotence.yml | 0 .../{nios => targets}/nios_mx_record/aliases | 0 .../nios_mx_record/defaults/main.yaml | 0 .../nios_mx_record/meta/main.yaml | 0 .../nios_mx_record/tasks/main.yml | 0 .../tasks/nios_mx_record_idempotence.yml | 0 .../nios_naptr_record/aliases | 0 .../nios_naptr_record/defaults/main.yaml | 0 .../nios_naptr_record/meta/main.yaml | 0 .../nios_naptr_record/tasks/main.yml | 0 .../tasks/nios_naptr_record_idempotence.yml | 0 .../{nios => targets}/nios_network/aliases | 0 .../nios_network/defaults/main.yaml | 0 .../nios_network/meta/main.yaml | 0 .../nios_network/tasks/main.yml | 0 .../tasks/nios_network_idempotence.yml | 0 .../nios_network_view/aliases | 0 .../nios_network_view/defaults/main.yaml | 0 .../nios_network_view/meta/main.yaml | 0 .../nios_network_view/tasks/main.yml | 0 .../tasks/nios_network_view_idempotence.yml | 0 .../{nios => targets}/nios_ptr_record/aliases | 0 .../nios_ptr_record/defaults/main.yaml | 0 .../nios_ptr_record/meta/main.yaml | 0 .../nios_ptr_record/tasks/main.yml | 0 .../tasks/nios_ptr_record_idempotence.yml | 0 .../{nios => targets}/nios_srv_record/aliases | 0 .../nios_srv_record/defaults/main.yaml | 0 .../nios_srv_record/meta/main.yaml | 0 .../nios_srv_record/tasks/main.yml | 0 .../tasks/nios_srv_record_idempotence.yml | 0 .../{nios => targets}/nios_txt_record/aliases | 0 .../nios_txt_record/defaults/main.yaml | 0 .../nios_txt_record/meta/main.yaml | 0 .../nios_txt_record/tasks/main.yml | 0 .../tasks/nios_txt_record_idempotence.yml | 2 + .../{nios => targets}/nios_zone/aliases | 0 .../nios_zone/defaults/main.yaml | 0 .../nios_zone/meta/main.yaml | 0 .../nios_zone/tasks/main.yml | 0 .../nios_zone/tasks/nios_zone_idempotence.yml | 0 .../targets/prepare_nios_tests/tasks/main.yml | 1 + .../tasks/prepare_nios_tests_idempotence.yml | 2 + tests/requirements.txt | 9 + tests/sanity/ignore.txt | 552 ------------------ .../tasks/main.yml => unit/__init__.py} | 0 .../main.yml => unit/compat/__init__.py} | 0 tests/unit/compat/mock.py | 120 ++++ tests/unit/plugins/__init__.py | 0 tests/unit/plugins/module_utils/__init__.py | 0 tests/unit/plugins/module_utils/test_api.py | 255 ++++++++ tests/unit/plugins/modules/__init__.py | 0 .../plugins/modules/fixtures/nios_result.txt | 0 .../plugins/modules/test_nios_a_record.py | 163 ++++++ .../plugins/modules/test_nios_aaaa_record.py | 163 ++++++ .../plugins/modules/test_nios_cname_record.py | 137 +++++ .../plugins/modules/test_nios_dns_view.py | 131 +++++ .../modules/test_nios_fixed_address.py | 201 +++++++ .../plugins/modules/test_nios_host_record.py | 156 +++++ .../unit/plugins/modules/test_nios_member.py | 162 +++++ .../unit/plugins/modules/test_nios_module.py | 88 +++ .../plugins/modules/test_nios_mx_record.py | 141 +++++ .../plugins/modules/test_nios_naptr_record.py | 151 +++++ .../unit/plugins/modules/test_nios_network.py | 248 ++++++++ .../plugins/modules/test_nios_network_view.py | 160 +++++ .../unit/plugins/modules/test_nios_nsgroup.py | 130 +++++ .../plugins/modules/test_nios_ptr_record.py | 184 ++++++ .../plugins/modules/test_nios_srv_record.py | 157 +++++ tests/unit/plugins/modules/test_nios_zone.py | 287 +++++++++ tests/unit/plugins/modules/utils.py | 52 ++ tests/unit/requirements.txt | 8 + 164 files changed, 6041 insertions(+), 1921 deletions(-) create mode 100644 CHANGELOG.rst create mode 100644 CONTRIBUTING.md delete mode 100644 ansible_collection/infoblox/nios_modules/plugins/.DS_Store delete mode 100644 ansible_collection/infoblox/nios_modules/plugins/module_utils/network.py create mode 100644 changelogs/.plugin-cache.yaml create mode 100644 changelogs/changelog.yaml create mode 100644 changelogs/config.yaml create mode 100644 galaxy.yml create mode 100644 meta/runtime.yml delete mode 100644 obsolete/LICENSE delete mode 100644 obsolete/library/infoblox_network.py rename {ansible_collection/infoblox/nios_modules/playbooks => playbooks}/create_a_record.yaml (100%) rename {ansible_collection/infoblox/nios_modules/playbooks => playbooks}/create_cname_record.yaml (100%) rename {ansible_collection/infoblox/nios_modules/playbooks => playbooks}/create_dns_view.yml (100%) create mode 100644 playbooks/create_dtc_lbdn.yml create mode 100644 playbooks/create_dtc_pool.yml create mode 100644 playbooks/create_dtc_server.yml rename {ansible_collection/infoblox/nios_modules/playbooks => playbooks}/create_mx_record.yaml (100%) rename {ansible_collection/infoblox/nios_modules/playbooks => playbooks}/create_network.yml (100%) rename {ansible_collection/infoblox/nios_modules/playbooks => playbooks}/create_network_view.yml (100%) rename {ansible_collection/infoblox/nios_modules/playbooks => playbooks}/create_txt_record.yaml (100%) rename {ansible_collection/infoblox/nios_modules/playbooks => playbooks}/create_zone.yml (100%) rename {ansible_collection/infoblox/nios_modules/playbooks => playbooks}/delete_cname_record.yaml (100%) rename {ansible_collection/infoblox/nios_modules/playbooks => playbooks}/delete_dnsview.yml (100%) rename {ansible_collection/infoblox/nios_modules/playbooks => playbooks}/delete_mx_record.yaml (100%) rename {ansible_collection/infoblox/nios_modules/playbooks => playbooks}/delete_network.yml (100%) rename {ansible_collection/infoblox/nios_modules/playbooks => playbooks}/delete_network_view.yml (100%) rename {ansible_collection/infoblox/nios_modules/playbooks => playbooks}/delete_txt_record.yaml (100%) rename {ansible_collection/infoblox/nios_modules/playbooks => playbooks}/delete_zone.yml (100%) create mode 100644 playbooks/restart_services.yml rename {ansible_collection/infoblox/nios_modules/playbooks => playbooks}/update_a_record.yml (100%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/README.md (100%) create mode 100644 plugins/doc_fragments/nios.py rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/inventory/nios_inventory.py (51%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/lookup/nios_lookup.py (63%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/lookup/nios_next_ip.py (51%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/lookup/nios_next_network.py (66%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/module_utils/api.py (62%) create mode 100644 plugins/module_utils/network.py rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/modules/nios_a_record.py (79%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/modules/nios_aaaa_record.py (82%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/modules/nios_cname_record.py (82%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/modules/nios_dns_view.py (85%) create mode 100644 plugins/modules/nios_dtc_lbdn.py create mode 100644 plugins/modules/nios_dtc_pool.py create mode 100644 plugins/modules/nios_dtc_server.py rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/modules/nios_fixed_address.py (76%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/modules/nios_host_record.py (68%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/modules/nios_member.py (85%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/modules/nios_mx_record.py (82%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/modules/nios_naptr_record.py (87%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/modules/nios_network.py (86%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/modules/nios_network_view.py (84%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/modules/nios_nsgroup.py (77%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/modules/nios_ptr_record.py (86%) create mode 100644 plugins/modules/nios_restartservices.py rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/modules/nios_srv_record.py (85%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/modules/nios_txt_record.py (84%) rename {ansible_collection/infoblox/nios_modules/plugins => plugins}/modules/nios_zone.py (82%) create mode 100644 requirements.txt delete mode 100644 tests/ignore-2.10.txt delete mode 100644 tests/ignore-2.9.txt delete mode 100644 tests/integration/targets/incidental_nios_prepare_tests/aliases delete mode 100644 tests/integration/targets/incidental_nios_txt_record/aliases delete mode 100644 tests/integration/targets/incidental_nios_txt_record/defaults/main.yaml delete mode 100644 tests/integration/targets/incidental_nios_txt_record/meta/main.yaml delete mode 100644 tests/integration/targets/incidental_nios_txt_record/tasks/main.yml delete mode 100644 tests/integration/targets/incidental_nios_txt_record/tasks/nios_txt_record_idempotence.yml rename tests/integration/{nios => targets}/nios_a_record/aliases (100%) rename tests/integration/{nios => targets}/nios_a_record/defaults/main.yaml (100%) rename tests/integration/{nios => targets}/nios_a_record/meta/main.yaml (100%) rename tests/integration/{nios => targets}/nios_a_record/tasks/main.yml (100%) rename tests/integration/{nios => targets}/nios_a_record/tasks/nios_a_record_idempotence.yml (100%) rename tests/integration/{nios => targets}/nios_aaaa_record/aliases (100%) rename tests/integration/{nios => targets}/nios_aaaa_record/defaults/main.yaml (100%) rename tests/integration/{nios => targets}/nios_aaaa_record/meta/main.yaml (100%) rename tests/integration/{nios => targets}/nios_aaaa_record/tasks/main.yml (100%) rename tests/integration/{nios => targets}/nios_aaaa_record/tasks/nios_aaaa_record_idempotence.yml (100%) rename tests/integration/{nios => targets}/nios_cname_record/aliases (100%) rename tests/integration/{nios => targets}/nios_cname_record/defaults/main.yaml (100%) rename tests/integration/{nios => targets}/nios_cname_record/meta/main.yaml (100%) rename tests/integration/{nios => targets}/nios_cname_record/tasks/main.yml (100%) rename tests/integration/{nios => targets}/nios_cname_record/tasks/nios_cname_record_idempotence.yml (100%) rename tests/integration/{nios => targets}/nios_dns_view/aliases (100%) rename tests/integration/{nios => targets}/nios_dns_view/defaults/main.yaml (100%) rename tests/integration/{nios => targets}/nios_dns_view/meta/main.yaml (100%) rename tests/integration/{nios => targets}/nios_dns_view/tasks/main.yml (100%) rename tests/integration/{nios => targets}/nios_dns_view/tasks/nios_dns_view_idempotence.yml (100%) rename tests/integration/{nios => targets}/nios_host_record/aliases (100%) rename tests/integration/{nios => targets}/nios_host_record/defaults/main.yaml (100%) rename tests/integration/{nios => targets}/nios_host_record/meta/main.yaml (100%) rename tests/integration/{nios => targets}/nios_host_record/tasks/main.yml (100%) rename tests/integration/{nios => targets}/nios_host_record/tasks/nios_host_record_idempotence.yml (100%) rename tests/integration/{nios => targets}/nios_mx_record/aliases (100%) rename tests/integration/{nios => targets}/nios_mx_record/defaults/main.yaml (100%) rename tests/integration/{nios => targets}/nios_mx_record/meta/main.yaml (100%) rename tests/integration/{nios => targets}/nios_mx_record/tasks/main.yml (100%) rename tests/integration/{nios => targets}/nios_mx_record/tasks/nios_mx_record_idempotence.yml (100%) rename tests/integration/{nios => targets}/nios_naptr_record/aliases (100%) rename tests/integration/{nios => targets}/nios_naptr_record/defaults/main.yaml (100%) rename tests/integration/{nios => targets}/nios_naptr_record/meta/main.yaml (100%) rename tests/integration/{nios => targets}/nios_naptr_record/tasks/main.yml (100%) rename tests/integration/{nios => targets}/nios_naptr_record/tasks/nios_naptr_record_idempotence.yml (100%) rename tests/integration/{nios => targets}/nios_network/aliases (100%) rename tests/integration/{nios => targets}/nios_network/defaults/main.yaml (100%) rename tests/integration/{nios => targets}/nios_network/meta/main.yaml (100%) rename tests/integration/{nios => targets}/nios_network/tasks/main.yml (100%) rename tests/integration/{nios => targets}/nios_network/tasks/nios_network_idempotence.yml (100%) rename tests/integration/{nios => targets}/nios_network_view/aliases (100%) rename tests/integration/{nios => targets}/nios_network_view/defaults/main.yaml (100%) rename tests/integration/{nios => targets}/nios_network_view/meta/main.yaml (100%) rename tests/integration/{nios => targets}/nios_network_view/tasks/main.yml (100%) rename tests/integration/{nios => targets}/nios_network_view/tasks/nios_network_view_idempotence.yml (100%) rename tests/integration/{nios => targets}/nios_ptr_record/aliases (100%) rename tests/integration/{nios => targets}/nios_ptr_record/defaults/main.yaml (100%) rename tests/integration/{nios => targets}/nios_ptr_record/meta/main.yaml (100%) rename tests/integration/{nios => targets}/nios_ptr_record/tasks/main.yml (100%) rename tests/integration/{nios => targets}/nios_ptr_record/tasks/nios_ptr_record_idempotence.yml (100%) rename tests/integration/{nios => targets}/nios_srv_record/aliases (100%) rename tests/integration/{nios => targets}/nios_srv_record/defaults/main.yaml (100%) rename tests/integration/{nios => targets}/nios_srv_record/meta/main.yaml (100%) rename tests/integration/{nios => targets}/nios_srv_record/tasks/main.yml (100%) rename tests/integration/{nios => targets}/nios_srv_record/tasks/nios_srv_record_idempotence.yml (100%) rename tests/integration/{nios => targets}/nios_txt_record/aliases (100%) rename tests/integration/{nios => targets}/nios_txt_record/defaults/main.yaml (100%) rename tests/integration/{nios => targets}/nios_txt_record/meta/main.yaml (100%) rename tests/integration/{nios => targets}/nios_txt_record/tasks/main.yml (100%) rename tests/integration/{nios => targets}/nios_txt_record/tasks/nios_txt_record_idempotence.yml (98%) rename tests/integration/{nios => targets}/nios_zone/aliases (100%) rename tests/integration/{nios => targets}/nios_zone/defaults/main.yaml (100%) rename tests/integration/{nios => targets}/nios_zone/meta/main.yaml (100%) rename tests/integration/{nios => targets}/nios_zone/tasks/main.yml (100%) rename tests/integration/{nios => targets}/nios_zone/tasks/nios_zone_idempotence.yml (100%) create mode 100644 tests/integration/targets/prepare_nios_tests/tasks/main.yml create mode 100644 tests/integration/targets/prepare_nios_tests/tasks/prepare_nios_tests_idempotence.yml create mode 100644 tests/requirements.txt delete mode 100644 tests/sanity/ignore.txt rename tests/{integration/nios/prepare_nios_tests/tasks/main.yml => unit/__init__.py} (100%) rename tests/{integration/targets/incidental_nios_prepare_tests/tasks/main.yml => unit/compat/__init__.py} (100%) create mode 100644 tests/unit/compat/mock.py create mode 100644 tests/unit/plugins/__init__.py create mode 100644 tests/unit/plugins/module_utils/__init__.py create mode 100644 tests/unit/plugins/module_utils/test_api.py create mode 100644 tests/unit/plugins/modules/__init__.py create mode 100644 tests/unit/plugins/modules/fixtures/nios_result.txt create mode 100644 tests/unit/plugins/modules/test_nios_a_record.py create mode 100644 tests/unit/plugins/modules/test_nios_aaaa_record.py create mode 100644 tests/unit/plugins/modules/test_nios_cname_record.py create mode 100644 tests/unit/plugins/modules/test_nios_dns_view.py create mode 100644 tests/unit/plugins/modules/test_nios_fixed_address.py create mode 100644 tests/unit/plugins/modules/test_nios_host_record.py create mode 100644 tests/unit/plugins/modules/test_nios_member.py create mode 100644 tests/unit/plugins/modules/test_nios_module.py create mode 100644 tests/unit/plugins/modules/test_nios_mx_record.py create mode 100644 tests/unit/plugins/modules/test_nios_naptr_record.py create mode 100644 tests/unit/plugins/modules/test_nios_network.py create mode 100644 tests/unit/plugins/modules/test_nios_network_view.py create mode 100644 tests/unit/plugins/modules/test_nios_nsgroup.py create mode 100644 tests/unit/plugins/modules/test_nios_ptr_record.py create mode 100644 tests/unit/plugins/modules/test_nios_srv_record.py create mode 100644 tests/unit/plugins/modules/test_nios_zone.py create mode 100644 tests/unit/plugins/modules/utils.py create mode 100644 tests/unit/requirements.txt diff --git a/CHANGELOG.rst b/CHANGELOG.rst new file mode 100644 index 00000000..1ad355cb --- /dev/null +++ b/CHANGELOG.rst @@ -0,0 +1,251 @@ +=================================== +Infoblox.Nios_Modules Release Notes +=================================== + +.. contents:: Topics + +v1.4.1 +====== + +Release Summary +--------------- +- Ansible Lookup modules can specify network_view to which a network/ip belongs +- Fixes camelCase issue while updating 'nios_network_view' with 'new_name' +- Fixes issue to allocate ip to a_record dynamically +- Updates 'nios_a_record' name with multiple ips having same name + +Minor Changes +------------- +- Fix to specify network_view in lookup modules to return absolute network/ip `#157 `_ +- Fix to camelcase issue for updating 'nios_network_view' name `#163 `_ +- Fix to allocate ip to a_record dynamically `#163 `_ +- Fix to update 'nios_a_record' name with multiple ips having same name `#164 `_ +- Fix to changelog yaml file with linting issues `#161 `_ + + +v1.4.0 +====== + +Release Summary +--------------- +- For ansible module, added certificate authentication feature +- Few bug fixes in ansible module nios network + +Major Changes +------------- +- Feature for extra layer security, with `cert` and `key` parameters in playbooks for authenticating using certificate and key .pem file absolute path `#154 ` +- Fix to remove issue causing due to template attr in deleting network using Ansible module nios network `#147 `_ + + +v1.3.0 +====== + +Release Summary +--------------- +- Issue fixes to create TXT record with equals sign +- For nonexistent record, update operation creates the new record +- For nonexistent IPv4Address, update operation creates a new A record with new_ipv4addr + +Major Changes +------------- +- Update operation using `old_name` and `new_name` for the object with dummy name in `old_name` (which does not exist in system) will not create a new object in the system. An error will be thrown stating the object does not exist in the system `#129 `_ +- Update `text` field of TXT Record `#128 `_ + +Bugfixes +--------- +- Fix to create TXT record with equals sign `#128 `_ + + +v1.2.2 +====== + +Release Summary +--------------- +- Issue fixes to create PTR record in different network views +- Support extended to determine whether the DTC server is disabled or not + +Minor Changes +------------- +- Fix to create PTR record in different network views `#103 `_ +- Remove use_option for DHCP option 60 `#104 `_ +- Allow specifying a template when creating a network `#105 `_ +- Fix unit and sanity test issues `#117 `_ +- Expanding for disable value `#119 `_ + + +v1.2.1 +====== + +Release Summary +--------------- +Added tags to support release on Ansible Automation Hub + +Minor Changes +------------- +Added tags 'cloud' and 'networking' in 'galaxy.yaml' + + +v1.2.0 +====== +Release Summary +--------------- +- Issue fixes to update A Record using 'next_available_ip' function +- Added a new feature - Update canonical name of the CNAME Record +- Updated the 'required' fields in modules + +Minor Changes +------------- +- Updated 'required' field in modules `#99 `_ +- Following options are made required in the modules + +.. list-table:: + :widths: 25 25 + :header-rows: 1 + + * - Record + - Option made required + * - A + - ipv4addr + * - AAAA + - ipv6addr + * - CNAME + - canonical + * - MX + - mail_exchanger, preference + * - PTR + - ptrdname + +Bugfixes +------------- +- nios_a_record module - KeyError: 'old_ipv4addr' `#79 `_ +- Ansible playbook fails to update canonical name of CName Record `#97 `_ + + +v1.1.2 +====== +Release Summary +--------------- +- Issue fixes and standardization of inventory plugin and lookup modules as per Ansible guidelines +- Directory restructure and added integration & unit tests + +Minor Changes +------------- +- Changes in inventory and lookup plugins documentation `#85 `_ +- Directory restructure and added integration & unit tests `#87 `_ + +Bugfixes +------------- +- Handle NoneType parsing in nios_inventory.py `#81 `_ +- Check all dhcp options, not just first one `#83 `_ + + +v1.1.1 +====== +Release Summary +--------------- +- Support for creating IPv6 Fixed Address with DUID +- Support added to return the next available IP address for an IPv6 network +- Modules made compatible to work with ansible-core 2.11 +- Issue fixes and standardization of modules as per Ansible guidelines + +Minor Changes +------------- +- The modules are standardized as per Ansible guidelines + +Bugfixes +------------- +- Implemented the bugfixes provided by Ansible `community.general` +- Update the name of existing A and AAAA records `#70 `_ +- Update of comment field of SRV, PTR and NAPTR records failing with the following error: + ```[Err: fatal: [localhost]: FAILED! => {"changed": false, "code": "Client.Ibap.Proto", "msg": "Field is not allowed for update: view", "operation": "update_object", "type": "AdmConProtoError"}]``` + `#70 `_ +- PTR Record failed to update and raises KeyError for view field `#70 `_ +- Update comment field and delete an existing Fixed Address `#73 `_ +- GitHub issue fix - Lookup module for next available IPV6 `#31 `_ +- GitHub issue fix - [nios_zone] changing a nios_zone does not work `#60 `_ +- GitHub issue fix - Getting an error, running every module `#67 `_ +- GitHub issue fix - Error - Dictionary Issues `#68 `_ +- GitHub issue fix - Examples for lookups don't work as written `#72 `_ +- Sanity fixes as per Ansible guidelines to all modules + + +v1.1.0 +====== + +Release Summary +--------------- + +This release provides plugins for NIOS DTC + +New Modules +----------- + +- infoblox.nios_modules.nios_dtc_lbdn - Configure Infoblox NIOS DTC LBDN +- infoblox.nios_modules.nios_dtc_pool - Configure Infoblox NIOS DTC Pool +- infoblox.nios_modules.nios_dtc_server - Configure Infoblox NIOS DTC Server +- infoblox.nios_modules.nios_restartservices - Restart grid services. + +v1.0.2 +====== + +Release Summary +--------------- + +This release provides compatibilty for Ansible v3.0.0 + +Minor Changes +------------- + +- Fixed the ignored sanity errors required for Ansible 3.0.0 collection +- Made it compatible for Ansible v3.0.0 + +v1.0.1 +====== + +Release Summary +--------------- + +This release provides compatibilty for Ansible v3.0.0 + +Minor Changes +------------- + +- Made it compatible for Ansible v3.0.0 + +v1.0.0 +====== + +Release Summary +--------------- + +First release of the `nios_modules` collection! This release includes multiple plugins:- an `api` plugin, a `network` plugin, a `nios` plugin, a `nios_inventory` plugin, a `lookup plugin`, a `nios_next_ip` plugin, a `nios_next_network` plugin + +New Plugins +----------- + +Lookup +~~~~~~ + +- infoblox.nios_modules.nios - Query Infoblox NIOS objects +- infoblox.nios_modules.nios_next_ip - Return the next available IP address for a network +- infoblox.nios_modules.nios_next_network - Return the next available network range for a network-container + +New Modules +----------- + +- infoblox.nios_modules.nios_a_record - Configure Infoblox NIOS A records +- infoblox.nios_modules.nios_aaaa_record - Configure Infoblox NIOS AAAA records +- infoblox.nios_modules.nios_cname_record - Configure Infoblox NIOS CNAME records +- infoblox.nios_modules.nios_dns_view - Configure Infoblox NIOS DNS views +- infoblox.nios_modules.nios_fixed_address - Configure Infoblox NIOS DHCP Fixed Address +- infoblox.nios_modules.nios_host_record - Configure Infoblox NIOS host records +- infoblox.nios_modules.nios_member - Configure Infoblox NIOS members +- infoblox.nios_modules.nios_mx_record - Configure Infoblox NIOS MX records +- infoblox.nios_modules.nios_naptr_record - Configure Infoblox NIOS NAPTR records +- infoblox.nios_modules.nios_network - Configure Infoblox NIOS network object +- infoblox.nios_modules.nios_network_view - Configure Infoblox NIOS network views +- infoblox.nios_modules.nios_nsgroup - Configure Infoblox NIOS Nameserver Groups +- infoblox.nios_modules.nios_ptr_record - Configure Infoblox NIOS PTR records +- infoblox.nios_modules.nios_srv_record - Configure Infoblox NIOS SRV records +- infoblox.nios_modules.nios_txt_record - Configure Infoblox NIOS txt records +- infoblox.nios_modules.nios_zone - Configure Infoblox NIOS DNS zones diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..436410b8 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,31 @@ +# Contributing + +Hello and welcome! Thank you for being interested in contributing to this project. + +First of all get confident with the [Ansible Collections Overview](https://github.com/ansible-collections/overview). + +We accept pull requests for bugfixes, new features, and other improvements, assuming they pass our review. If you are planning a larger feature or refactoring, please create an issue first to discuss it with us. + +## :bug: Reporting an issue + +Please [search in the issue list](https://github.com/infobloxopen/infoblox-ansible/issues) and if has not been already reported, [open a new issue](https://github.com/infobloxopen/infoblox-ansible/issues/new) + +## 🏗 To contribute + +A more extensive walk-through can be found in [Ansible's Contributing to collections](https://docs.ansible.com/ansible/latest/dev_guide/developing_collections.html#hacking-collections). + +1. Fork this repo (when checking it out, see [here](https://docs.ansible.com/ansible/latest/dev_guide/developing_collections.html#contributing-to-collections) for how to place the checkout correctly) +1. Create a feature branch +1. Commit and push your code. To make the process faster, please ensure: + + - the tests are green. Tests runs using [GitHub Actions](https://help.github.com/en/actions) + - you added a [changelog fragment](https://docs.ansible.com/ansible/latest/community/development_process.html#changelogs-how-to) + +Please note that all PRs that are not strictly documentation, testing, or add a new plugin or module, require a changelog fragment. See [Creating a changelog fragment](https://docs.ansible.com/ansible/latest/community/development_process.html#changelogs-how-to) for information on that. + +Further resources: + +- [Ansible Developer guide: developing collections](https://docs.ansible.com/ansible/latest/dev_guide/developing_collections.html) +- [Ansible Developer guide](https://docs.ansible.com/ansible/latest/dev_guide/index.html) + +This repository adheres to the [Ansible Community code of conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html) diff --git a/README.md b/README.md index a0cf1044..131aaa2b 100644 --- a/README.md +++ b/README.md @@ -1,66 +1,74 @@ -**Infoblox Ansible Collections for vNIOS** +# Infoblox NIOS Modules for Ansible Collections About ====== -Infoblox Ansible Collection for vNIOS allows managing your NIOS objects -through APIs.\ +Infoblox NIOS Modules for Ansible Collections allows managing your NIOS objects +through APIs. It, thus, enables the DNS and IPAM automation of VM workloads that are -deployed across multiple platforms. The nios\_modules collection +deployed across multiple platforms. The `nios_modules` collection provides modules and plugins for managing the networks, IP addresses, and DNS records in NIOS. This collection is hosted on Ansible Galaxy -under infoblox.nios\_modules. +under `infoblox.nios_modules`. -Modules Overview: +Modules Overview ================= -The infoblox.nios\_modules collection has the following content: +The `infoblox.nios_modules` collection has the following content: -Modules: +Modules -------- -- nios\_a\_record – Configure Infoblox NIOS A records +- `nios_a_record` – Configure Infoblox NIOS A records -- nios\_aaaa\_record – Configure Infoblox NIOS AAAA records +- `nios_aaaa_record` – Configure Infoblox NIOS AAAA records -- nios\_cname\_record – Configure Infoblox NIOS CNAME records +- `nios_cname_record` – Configure Infoblox NIOS CNAME records -- nios\_dns\_view – Configure Infoblox NIOS DNS views +- `nios_dns_view` – Configure Infoblox NIOS DNS views -- nios\_fixed\_address – Configure Infoblox NIOS DHCP Fixed Address +- `nios_dtc_lbdn` – Configure Infoblox NIOS DTC LBDN records -- nios\_host\_record – Configure Infoblox NIOS host records +- `nios_dtc_pool` – Configure Infoblox NIOS DTC pools -- nios\_member – Configure Infoblox NIOS members +- `nios_dtc_server` – Configure Infoblox NIOS DTC server records -- nios\_mx\_record – Configure Infoblox NIOS MX records +- `nios_fixed_address` – Configure Infoblox NIOS DHCP Fixed Address -- nios\_naptr\_record – Configure Infoblox NIOS NAPTR records +- `nios_host_record` – Configure Infoblox NIOS host records -- nios\_network – Configure Infoblox NIOS network object +- `nios_member` – Configure Infoblox NIOS members -- nios\_network\_view – Configure Infoblox NIOS network views +- `nios_mx_record` – Configure Infoblox NIOS MX records -- nios\_nsgroup – Configure Infoblox DNS Nameserver Groups +- `nios_naptr_record` – Configure Infoblox NIOS NAPTR records -- nios\_ptr\_record – Configure Infoblox NIOS PTR records +- `nios_network` – Configure Infoblox NIOS network object -- nios\_srv\_record – Configure Infoblox NIOS SRV records +- `nios_network_view` – Configure Infoblox NIOS network views -- nios\_txt\_record – Configure Infoblox NIOS txt records +- `nios_nsgroup` – Configure Infoblox DNS Nameserver Groups -- nios\_zone – Configure Infoblox NIOS DNS zones +- `nios_ptr_record` – Configure Infoblox NIOS PTR records -Plugins: +- `nios_restartservices` - Controlled restart of Infoblox NIOS services + +- `nios_srv_record` – Configure Infoblox NIOS SRV records + +- `nios_txt_record` – Configure Infoblox NIOS txt records + +- `nios_zone` – Configure Infoblox NIOS DNS zones + +Plugins -------- -- nios\_inventory: List all the hosts with records created in NIOS +- `nios_inventory`: List all the hosts with records created in NIOS -- nios\_lookup: Look up queries for NIOS database objects +- `nios_lookup`: Look up queries for NIOS database objects -- nios\_next\_ip: Returns the next available IP address for a network +- `nios_next_ip`: Returns the next available IP address for a network -- nios\_next\_network: Returns the next available network addresses +- `nios_next_network`: Returns the next available network addresses for a given network CIDR Installation @@ -69,64 +77,111 @@ Installation Dependencies ------------ -- Python version 2.7 and above +- Python version 2.7 or later -- Ansible version 2.9.0 or above +- Ansible version 2.9.0 or later -- NIOS 8.2.4 and above +- NIOS 8.2.4 or later Prerequisites ------------- -You need to install the infoblox-client package. To install -infoblox-client WAPI package, run the following command: +Install the infoblox-client WAPI package. To install, run the following command: -\$ pip install infoblox-client +```shell +$ pip install infoblox-client +``` -Installation of nios\_modules Collection +Installation of nios_modules Collection ---------------------------------------- -The nios\_modules collection can be installed either from Ansible Galaxy +The `nios_modules` collection can be installed either from Ansible Galaxy or directly from git. It is recommended to install collections from -Ansible Galaxy are those are more stable than the ones in the git +Ansible Galaxy as those are more stable than the ones in the git branch. ### Installation from Ansible Galaxy +- To directly install the `nios_modules` collection from [Ansible Galaxy](https://galaxy.ansible.com/infoblox/nios_modules), run the following command: + - ``` + $ ansible-galaxy collection install infoblox.nios_modules + ``` + - The collection folder would be installed at + ``` + ~/.ansible/collections/ansible_collections/infoblox/nios_modules + ``` + +- For offline installation on the Ansible control machine, download the required tar archive version of the collection from [Infoblox Nios Modules collections](https://galaxy.ansible.com/infoblox/nios_modules) and run the command given below in `~/.ansible` directory: + - ``` + $ ansible-galaxy collection install infoblox-nios_modules-.tar.gz -p ./collections + ``` + +### Installation from GitHub +- Install the collection directly from the [GitHub](https://github.com/infobloxopen/infoblox-ansible) repository using the latest commit on the master branch: + - ``` + $ ansible-galaxy collection install git+https://github.com/infobloxopen/infoblox-ansible.git,master + ``` + +- For offline installation on the Ansible control machine, to git clone and install from this repo, follow these steps: + + - **Clone the repo:** + + ``` + $ git clone https://github.com/infobloxopen/infoblox-ansible.git + ``` + + - **Build the collection:** + + To build a collection, run the following command from inside the + root directory of the collection: + ``` + $ ansible-galaxy collection build + ``` + This creates a tarball of the built collection in the current directory. + + - **Install the collection:** + + ``` + $ ansible-galaxy collection install infoblox-nios_modules-.tar.gz -p ./collections + ``` + +Please refer to our Ansible [deployment +guide](https://www.infoblox.com/wp-content/uploads/infoblox-deployment-guide-automate-infoblox-infrastructure-using-ansible.pdf) +for more details. -To directly install the nios\_modules collection from Ansible Galaxy, -run the following command: - -\$ ansible-galaxy collection install infoblox.nios\_modules - -The collection folder would be installed at -\~/.ansible/collections/ansible\_collections/infoblox/nios\_modules - -### Installation from Git +Playbooks +========= +Latest sample playbooks and examples are available at [playbooks](https://github.com/infobloxopen/infoblox-ansible/tree/master/playbooks). -To git clone and install from this repo, follow these steps: -- **Clone the repo:** +Releasing +========= -\$ git clone -https://github.com/infobloxopen/infoblox-ansible/nios\_modules.git +Next release +--------------- -- **Build the collection: ** +Dates TBD - To build a collection, run the following command from inside the - root directory of the collection: +Current release +--------------- -\$ ansible-galaxy collection build +1.4.1 on 24 November 2022 -This creates a tarball of the built collection in the current directory. +Versioning +========= -- **Install the collection:** +- galaxy.yml in the master branch will always contain the version of the current major or minor release. It will be updated right after a release. +- version_added needs to be used for every new feature and module/plugin, and needs to coincide with the next minor/major release version. (This will eventually be enforced by CI.) -\$ ansible-galaxy collection install <collection-name>.tar.gz -p -./collections +Deprecation +=========== +- Deprecations are done by version number (not by date). +- New deprecations can be added during every minor release, under the condition that they do not break backward compatibility. -Please refer to our Ansible [deployment -guide](https://www.infoblox.com/wp-content/uploads/infoblox-deployment-guide-infoblox-and-ansible-integration.pdf) -for more details. +Contributing +============ +We welcome your contributions to Infoblox Nios Modules. See +[CONTRIBUTING.md](https://github.com/infobloxopen/infoblox-ansible/blob/master/CONTRIBUTING.md) for +more details. Resources ========= @@ -139,18 +194,16 @@ Resources Galaxy - Infoblox Ansible [deployment - guide](https://www.infoblox.com/wp-content/uploads/infoblox-deployment-guide-infoblox-and-ansible-integration.pdf) + guide](https://www.infoblox.com/wp-content/uploads/infoblox-deployment-guide-automate-infoblox-infrastructure-using-ansible.pdf) License ======= -This code is published under GPL v3.0 +This code is published under `GPL v3.0` [COPYING](https://github.com/infobloxopen/infoblox-ansible/blob/master/COPYING) -Support -======= - -Infoblox supports the existing modules in the collections. You can open -an issue or request for enhancement +Issues or RFEs +=============== +You can open an issue or request for enhancement [here](https://github.com/infobloxopen/infoblox-ansible/issues) diff --git a/ansible_collection/infoblox/nios_modules/plugins/.DS_Store b/ansible_collection/infoblox/nios_modules/plugins/.DS_Store deleted file mode 100644 index a3e4274c06adedb126e7bbe2d664830e59e2ac85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10244 zcmeHMU2GIp6h3EL;LcFmDL=Ac7uL1}ghjixYz3-re}LAX(6B8nP+4YoMmlkJX4#qD z0<~I1qYnh*Ph!-V7&I{ozL@BP@?EMSqKdBAoP5-!JLQNg+izpuhP*zi0G!DCqT0?MFR# zz@(5t9Uu@OFcSejU1}f)HfXeOpSpiH!O4s{`HX32$mfep-ZUJyrR7@;RaGxoxQH>C z$xGyiQ=|4+%2nN>)1?*;@TY#&9nJXn1Ga5mxmPoL4Sg)FEbq20S2ZlX-~}6+PA(%u zhNanKU3SsZ9Iu^}Ffb-DDXoOZ$6FIEv1n^zA{HHwwX#1AL#Dv6Fu8ZH(cPMx4 z`1oTJkG~?ui2gbObroZNb*=%MhvTWNoy&`u5p_;qr_?RL2^}kgbEyoDBrgu{+$Hy= zm8B&b^X|NB*p{Z)ez`=D3@J(%G67tJgMd*xcIQ(Rp!6ZJi=7 zm6s2d49Ccr`rw$Mxug43C#zeUVIAI2Fk7zih@lsx`l`330ZYy47nRz&CAX{$hlh(9 z<4DnPk10)ziMATTYb50ZHlk6t57`=z)I3YLA>7E=0j}>Z=u``}ye_<6QdBnJ(A$Y7 zHp($caioDq>6?qtJLNc2G-=ROGrB2MZE}Js4@g5LftpZmmAA8cj7h`vnR4{rj!@ql zPBP^JJIMQfP<7nhdEKJ!`6#*?!r^^f->GT3#u#f#ZV=zs8>!TkY!Q!?fmXpCl<9h5 zgwC<@a1u_zX?PA^gSX%uybtH$bGQIs!dLJ$d=EduPw+GR0>8s$_yhh#L>U)j4TkYH zY{X_D^R<5T!FK7-HV%lHPqi)Zm1 zzK0*;$9P`6S*T3r`~5fd1%5_1v(8@ADfzQEbnt2fjqKPd_ud?Wepka;S-*7I@)c{E z)^BRrvhBVrAGG2dPNUgWZh3SPeDQcx=851had*|~Tjj_gF-$*N$@%hJP!@46v5VY$ zZ8Q>5IElog)EtqC<&tOH&`h?FZ;5RtOBE4X*y62nL|H)G6>*7nSyrlv+`_uOgRBdQ z#=@HHBrEV~CS5xZ&%jyuh&cEST!J5nf4>s<{(`@80oLJ4T!jr7!8N!ZZ^um-!_CCJ zyKyUS!)}j#yRaYk-~bNdUQDBkSz@4049pV)9dvO5pTHCNB%Z`mcp9I_7w|=V317!E z_+|wQ`zly?ZY~z)?4BM!hp?d&wY43MpLEXcuU(UWest=R?XBFi&WKW~V41dcnEK~4 zYSFa3H{Y^dqBRzcw{89J*{))k({dcXb9p8Zv~UEOEy!#)J+oC3H^^r}KD$x*tb%(} zv)Hmve>3Wuy(~7v>)+fpyVtag73!z;w=xq|;)VN73h9MV#a+1GJC3IZejM)|vyiTQ jzQXNE-)~Y#(onhKe+C5m|6u<=<5$-_JMI3T_y7L@9WEnQ diff --git a/ansible_collection/infoblox/nios_modules/plugins/module_utils/network.py b/ansible_collection/infoblox/nios_modules/plugins/module_utils/network.py deleted file mode 100644 index dbe80a1e..00000000 --- a/ansible_collection/infoblox/nios_modules/plugins/module_utils/network.py +++ /dev/null @@ -1,17 +0,0 @@ - -import socket - -def validate_ip_address(address): - try: - socket.inet_aton(address) - except socket.error: - return False - return address.count('.') == 3 - - -def validate_ip_v6_address(address): - try: - socket.inet_pton(socket.AF_INET6, address) - except socket.error: - return False - return True diff --git a/changelogs/.plugin-cache.yaml b/changelogs/.plugin-cache.yaml new file mode 100644 index 00000000..4eba71a2 --- /dev/null +++ b/changelogs/.plugin-cache.yaml @@ -0,0 +1,131 @@ +plugins: + become: {} + cache: {} + callback: {} + cliconf: {} + connection: {} + httpapi: {} + inventory: + nios_inventory: + description: Infoblox inventory plugin + name: nios_inventory + version_added: 1.0.0 + lookup: + nios_lookup: + description: Query Infoblox NIOS objects + name: nios_lookup + version_added: 1.0.0 + nios_next_ip: + description: Return the next available IP address for a network + name: nios_next_ip + version_added: 1.0.0 + nios_next_network: + description: Return the next available network range for a network-container + name: nios_next_network + version_added: 1.0.0 + module: + nios_a_record: + description: Configure Infoblox NIOS A records + name: nios_a_record + namespace: '' + version_added: 1.0.0 + nios_aaaa_record: + description: Configure Infoblox NIOS AAAA records + name: nios_aaaa_record + namespace: '' + version_added: 1.0.0 + nios_cname_record: + description: Configure Infoblox NIOS CNAME records + name: nios_cname_record + namespace: '' + version_added: 1.0.0 + nios_dns_view: + description: Configure Infoblox NIOS DNS views + name: nios_dns_view + namespace: '' + version_added: 1.0.0 + nios_dtc_lbdn: + description: Configure Infoblox NIOS DTC LBDN + name: nios_dtc_lbdn + namespace: '' + version_added: 1.1.0 + nios_dtc_pool: + description: Configure Infoblox NIOS DTC Pool + name: nios_dtc_pool + namespace: '' + version_added: 1.1.0 + nios_dtc_server: + description: Configure Infoblox NIOS DTC Server + name: nios_dtc_server + namespace: '' + version_added: 1.1.0 + nios_fixed_address: + description: Configure Infoblox NIOS DHCP Fixed Address + name: nios_fixed_address + namespace: '' + version_added: 1.0.0 + nios_host_record: + description: Configure Infoblox NIOS host records + name: nios_host_record + namespace: '' + version_added: 1.0.0 + nios_member: + description: Configure Infoblox NIOS members + name: nios_member + namespace: '' + version_added: 1.0.0 + nios_mx_record: + description: Configure Infoblox NIOS MX records + name: nios_mx_record + namespace: '' + version_added: 1.0.0 + nios_naptr_record: + description: Configure Infoblox NIOS NAPTR records + name: nios_naptr_record + namespace: '' + version_added: 1.0.0 + nios_network: + description: Configure Infoblox NIOS network object + name: nios_network + namespace: '' + version_added: 1.0.0 + nios_network_view: + description: Configure Infoblox NIOS network views + name: nios_network_view + namespace: '' + version_added: 1.0.0 + nios_nsgroup: + description: Configure InfoBlox DNS Nameserver Groups + name: nios_nsgroup + namespace: '' + version_added: 1.0.0 + nios_ptr_record: + description: Configure Infoblox NIOS PTR records + name: nios_ptr_record + namespace: '' + version_added: 1.0.0 + nios_restartservices: + description: Restart grid services. + name: nios_restartservices + namespace: '' + version_added: 1.1.0 + nios_srv_record: + description: Configure Infoblox NIOS SRV records + name: nios_srv_record + namespace: '' + version_added: 1.0.0 + nios_txt_record: + description: Configure Infoblox NIOS txt records + name: nios_txt_record + namespace: '' + version_added: 1.0.0 + nios_zone: + description: Configure Infoblox NIOS DNS zones + name: nios_zone + namespace: '' + version_added: 1.0.0 + netconf: {} + shell: {} + strategy: {} + vars: {} +version: 1.4.1 diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml new file mode 100644 index 00000000..7c752c2c --- /dev/null +++ b/changelogs/changelog.yaml @@ -0,0 +1,200 @@ +ancestor: null +releases: + 1.0.0: + changes: + release_summary: 'First release of the `nios_modules` collection! This release + includes multiple plugins:- an `api` plugin, a `network` plugin, a `nios` + plugin, a `nios_inventory` plugin, a `lookup plugin`, a `nios_next_ip` plugin, + a `nios_next_network` plugin ' + modules: + - description: Configure Infoblox NIOS A records + name: nios_a_record + namespace: '' + - description: Configure Infoblox NIOS AAAA records + name: nios_aaaa_record + namespace: '' + - description: Configure Infoblox NIOS CNAME records + name: nios_cname_record + namespace: '' + - description: Configure Infoblox NIOS DNS views + name: nios_dns_view + namespace: '' + - description: Configure Infoblox NIOS DHCP Fixed Address + name: nios_fixed_address + namespace: '' + - description: Configure Infoblox NIOS host records + name: nios_host_record + namespace: '' + - description: Configure Infoblox NIOS members + name: nios_member + namespace: '' + - description: Configure Infoblox NIOS MX records + name: nios_mx_record + namespace: '' + - description: Configure Infoblox NIOS NAPTR records + name: nios_naptr_record + namespace: '' + - description: Configure Infoblox NIOS network object + name: nios_network + namespace: '' + - description: Configure Infoblox NIOS network views + name: nios_network_view + namespace: '' + - description: Configure Infoblox NIOS Nameserver Groups + name: nios_nsgroup + namespace: '' + - description: Configure Infoblox NIOS PTR records + name: nios_ptr_record + namespace: '' + - description: Configure Infoblox NIOS SRV records + name: nios_srv_record + namespace: '' + - description: Configure Infoblox NIOS txt records + name: nios_txt_record + namespace: '' + - description: Configure Infoblox NIOS DNS zones + name: nios_zone + namespace: '' + plugins: + lookup: + - description: Query Infoblox NIOS objects + name: nios + namespace: null + - description: Return the next available IP address for a network + name: nios_next_ip + namespace: null + - description: Return the next available network range for a network-container + name: nios_next_network + namespace: null + release_date: '2020-10-23' + 1.0.1: + changes: + minor_changes: + - Made it compatible for Ansible v3.0.0 + release_summary: This release provides compatibilty for Ansible v3.0.0 + release_date: '2021-01-25' + 1.0.2: + changes: + minor_changes: + - Fixed the ignored sanity errors required for Ansible 3.0.0 collection + - Made it compatible for Ansible v3.0.0 + release_summary: This release provides compatibilty for Ansible v3.0.0 + release_date: '2021-01-27' + 1.1.0: + changes: + release_summary: This release provides plugins for NIOS DTC + modules: + - description: Configure Infoblox NIOS DTC LBDN + name: nios_dtc_lbdn + namespace: '' + - description: Configure Infoblox NIOS DTC Pool + name: nios_dtc_pool + namespace: '' + - description: Configure Infoblox NIOS DTC Server + name: nios_dtc_server + namespace: '' + - description: Restart grid services. + name: nios_restartservices + namespace: '' + release_date: '2021-04-12' + 1.1.1: + changes: + bugfixes: + - Implemented the bugfixes provided by Ansible `community.general` + - Update the name of existing A and AAAA records `#70 `_ + - Update of comment field of SRV, PTR and NAPTR records failing with the following error `#70 `_ + - PTR Record failed to update and raises KeyError for view field `#70 `_ + - Update comment field and delete an existing Fixed Address `#73 `_ + - GitHub issue fix - Lookup module for next available IPV6 `#31 `_ + - GitHub issue fix - [nios_zone] changing a nios_zone does not work `#60 `_ + - GitHub issue fix - Getting an error, running every module `#67 `_ + - GitHub issue fix - Error - Dictionary Issues `#68 `_ + - GitHub issue fix - Examples for lookups don't work as written `#72 `_ + - Sanity fixes as per Ansible guidelines to all modules + minor_changes: + - The modules are standardized as per Ansible guidelines + release_summary: 'Support for creating IPv6 Fixed Address with DUID, + Support added to return the next available IP address for an IPv6 network, + Modules made compatible to work with ansible-core 2.11, + Issue fixes and standardization of modules as per Ansible guidelines' + release_date: '2021-09-07' + 1.1.2: + changes: + bugfixes: + - Handle NoneType parsing in nios_inventory.py `#81 `_ + - Check all dhcp options, not just first one `#83 `_ + minor_changes: + - Changes in inventory and lookup plugins documentation `#85 `_ + - Directory restructure and added integration & unit tests `#87 `_ + release_summary: 'Issue fixes and standardization of inventory plugin and lookup modules as per Ansible guidelines, + Directory restructure and added integration & unit tests' + release_date: '2021-10-12' + 1.2.0: + changes: + bugfixes: + - nios_a_record module - KeyError 'old_ipv4addr' `#79 `_ + - Ansible playbook fails to update canonical name of CName Record `#97 `_ + minor_changes: + - Updated 'required' field in modules `#99 `_ + - Following options are made required in the modules + | Record | Option made required | + | ------ | -------------------- | + | A | ipv4addr | + | AAAA | ipv6addr | + | CNAME | canonical | + | MX | mail_exchanger, preference | + | PTR | ptrdname | + release_summary: 'Issue fixes to update A Record using `next_available_ip` function, + Added a new feature - Update canonical name of the CNAME Record, + Updated the `required` fields in modules' + release_date: '2021-12-13' + 1.2.1: + changes: + minor_changes: + - Added tags 'cloud' and 'networking' in 'galaxy.yaml' + release_summary: 'Added tags to support release on Ansible Automation Hub' + release_date: '2021-12-20' + + 1.2.2: + changes: + minor_changes: + - Fix to create PTR record in different network views `#103 `_ + - Remove use_option for DHCP option 60 `#104 `_ + - Allow specifying a template when creating a network `#105 `_ + - Fix unit and sanity test issues `#117 `_ + - Expanding for disable value `#119 `_ + release_summary: 'Issue fixes to create PTR record in different network views, + Support extended to determine whether the DTC server is disabled or not' + release_date: '2022-05-23' + 1.3.0: + changes: + major_changes: + - Update operation using `old_name` and `new_name` for the object with dummy name in `old_name` (which does not exist in system) will not create a new object in the system. An error will be thrown stating the object does not exist in the system `#129 `_ + - Update `text` field of TXT Record `#128 `_ + bugfixes: + - Fix to create TXT record with equals sign `#128 `_ + release_summary: 'Issue fixes to create TXT record with equals sign, + For nonexistent record, update operation creates the new record, + For nonexistent IPv4Address, update operation creates a new A record with new_ipv4addr' + release_date: '2022-07-01' + 1.4.0: + changes: + major_changes: + - Feature for extra layer security , with `cert` and `key` parameters in playbooks for authenticating using certificate and key ``*.pem`` file absolute path `#154 `_ + - Fix to remove issue causing due to template attr in deleting network using Ansible module nios network `#147 `_ + release_summary: 'For ansible module, added certificate authentication feature, + Few bugs fix in ansible module nios network' + release_date: '2022-10-12' + 1.4.1: + changes: + minor_changes: + - Fix to specify network_view in lookup modules to return absolute network and ip `#157 `_ + - Fix to camelcase issue for updating 'nios_network_view' name `#163 `_ + - Fix to allocate ip to a_record dynamically `#163 `_ + - Fix to update 'nios_a_record' name with multiple ips having same name `#164 `_ + - Fix to changelog yaml file with linting issues `#161 `_ + release_summary: 'Ansible Lookup modules can specify network_view to which a network/ip belongs, + Fixes camelCase issue while updating `nios_network_view` with `new_name`, + Fixes issue to allocate ip to a_record dynamically, + Updates `nios_a_record` name with multiple ips having same name' + release_date: '2022-11-24' diff --git a/changelogs/config.yaml b/changelogs/config.yaml new file mode 100644 index 00000000..09a1f378 --- /dev/null +++ b/changelogs/config.yaml @@ -0,0 +1,32 @@ +changelog_filename_template: ../CHANGELOG.rst +changelog_filename_version_depth: 0 +changes_file: changelog.yaml +changes_format: combined +ignore_other_fragment_extensions: true +keep_fragments: false +mention_ancestor: true +new_plugins_after_name: removed_features +notesdir: fragments +prelude_section_name: release_summary +prelude_section_title: Release Summary +sanitize_changelog: true +sections: +- - major_changes + - Major Changes +- - minor_changes + - Minor Changes +- - breaking_changes + - Breaking Changes / Porting Guide +- - deprecated_features + - Deprecated Features +- - removed_features + - Removed Features (previously deprecated) +- - security_fixes + - Security Fixes +- - bugfixes + - Bugfixes +- - known_issues + - Known Issues +title: Infoblox.Nios_Modules +trivial_section_name: trivial +use_fqcn: true diff --git a/galaxy.yml b/galaxy.yml new file mode 100644 index 00000000..8b734fba --- /dev/null +++ b/galaxy.yml @@ -0,0 +1,63 @@ +### REQUIRED + +# The namespace of the collection. This can be a company/brand/organization or product namespace under which all +# content lives. May only contain alphanumeric lowercase characters and underscores. Namespaces cannot start with +# underscores or numbers and cannot contain consecutive underscores +namespace: infoblox + +# The name of the collection. Has the same character restrictions as 'namespace' +name: nios_modules + +# The version of the collection. Must be compatible with semantic versioning +version: 1.4.1 + +# The path to the Markdown (.md) readme file. This path is relative to the root of the collection +readme: README.md + +# A list of the collection's content authors. Can be just the name or in the format 'Full Name (url) +# @nicks:irc/im.site#channel' +authors: +- Sailesh Giri (sgiri@infoblox.com) +- Vaishnavi TR (vtr@infoblox.com) +- Anagha KH (akh@infoblox.com) +- Shankar Ganesh (sganesh@infoblox.com) + +### OPTIONAL but strongly recommended + +# A short summary description of the collection +description: Infoblox Ansible Collection for vNIOS allows managing your NIOS objects through APIs. + +# Either a single license or a list of licenses for content inside of a collection. Ansible Galaxy currently only +# accepts L(SPDX,https://spdx.org/licenses/) licenses. This key is mutually exclusive with 'license_file' +license: +- GPL-3.0-only + +# The path to the license file for the collection. This path is relative to the root of the collection. This key is +# mutually exclusive with 'license' +license_file: '' + +# A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character +# requirements as 'namespace' and 'name' +tags: +- infoblox +- nios +- cloud +- networking + +# Collections that this collection requires to be installed for it to be usable. The key of the dict is the +# collection label 'namespace.name'. The value is a version range +# L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version +# range specifiers can be set and are separated by ',' +#dependencies: {} + +# The URL of the originating SCM repository +repository: https://github.com/infobloxopen/infoblox-ansible/tree/master + +# The URL to any online docs +documentation: https://github.com/infobloxopen/infoblox-ansible/blob/master/README.md + +# The URL to the homepage of the collection/project +homepage: https://github.com/infobloxopen/infoblox-ansible + +# The URL to the collection issue tracker +issues: https://github.com/infobloxopen/infoblox-ansible/issues diff --git a/meta/runtime.yml b/meta/runtime.yml new file mode 100644 index 00000000..2ee3c9fa --- /dev/null +++ b/meta/runtime.yml @@ -0,0 +1,2 @@ +--- +requires_ansible: '>=2.9.10' diff --git a/obsolete/LICENSE b/obsolete/LICENSE deleted file mode 100644 index 8dada3ed..00000000 --- a/obsolete/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/obsolete/library/infoblox_network.py b/obsolete/library/infoblox_network.py deleted file mode 100644 index faf3f972..00000000 --- a/obsolete/library/infoblox_network.py +++ /dev/null @@ -1,264 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2017 Ken Celenza -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -try: - from infoblox_client import objects - from infoblox_client import connector - HAS_INFOBLOX_CLIENT = True -except ImportError: - HAS_INFOBLOX_CLIENT = False - - -DOCUMENTATION = """ -module: infoblox_network -short_description: Manage Infoblox Networks -description: - - Manage InfoBlox Networks using infblox-client Python library -version_added: "2.4" -author: "Ken Celenza (https://github.com/itdependsnetworks)" -options: - provider: - description: - - A dict object containing connection details. - default: null - suboptions: - host: - description: - - Specifies the DNS host name or address for connecting to the remote - device over the specified transport. The value of host is used as - the destination address for the transport. - required: true - username: - description: - - Configures the username to use to authenticate the connection to - the remote device. This value is used to authenticate - to NIOS - required: true - password: - description: - - Specifies the password to use to authenticate the connection to - the remote device. - required: true - validate_certs: - description: - - Validate SSL certs. Note, if running on python without SSLContext - support (typically, python < 2.7.9) you will have to set this to C(no) - as pysphere does not support validating certificates on older python. - Prior to 2.1, this module would always validate on python >= 2.7.9 and - never validate on python <= 2.7.8. - required: false - default: no - choices: ['yes', 'no'] - wapi_version: - description: - - The wapi version using to connect to NIOS - required: false - default: '2.2' - network_view: - description: - - The network view where the network object exists - required: false - default: default - state: - description: - - If the object should be added, removed or found. - required: true - default: present - choices: [ "present", "absent", "get" ] - comment: - description: - - NIOS default network view - required: false - extattrs: - description: - - A dict of key Value pairs that define the extensible attributes configured - for the object - - Example: {"Building": "Empire", "Country": "USA"} - required: false - members: - description: - - Not yet implemented - required: false - dhcp_options: - description: - - A list of dict representing the dhcp options of the subnet - - Example: [{"name": "dhcp-lease-time", "num": 52,"use_option": - False,"value": "43200", "vendor_class": "DHCP"} ] - required: false -""" - -EXAMPLES = ''' -vars: - provider: - host: "{{ inventory_hostname }}" - username: "ntc" - password: "ntc123" - validate_certs: False - wapi: "2.2.2" -- name: CONFIGURE NETWORK OF 10.10.0.0/24 AND UPDATE IF EXIST" - infoblox_network: - provider: "{{ provider }}" - state: "present" - network: "10.10.0.0/24" - network_view: "default" - comment: "Last Verified 08/2017" -- name: "ENSURE NETWORK 10.10.1.0/24 DOES NOT EXIST" - infoblox_network: - provider: "{{ provider }}" - state: "absent" - network: "10.10.0.0/24" - network_view: "default" -''' - -from ansible.module_utils.basic import AnsibleModule, return_values -STATE = ['get', 'present', 'absent'] -BASE_WAPI = '2.2' - - -def get_network(module, conn, network_view, **kwargs): - network = kwargs.get('network') - return_fields = objects.Network._return_fields - obj = conn.get_object('network', {'network': network, 'network_view': network_view}, return_fields) - return obj - - -def compare_fields(module, conn, param, obj): - fields = ['dhcp_options', 'members', 'extattrs', 'comment'] - build_fields = {} - for field in fields: - if param.get(field) is None: - pass - elif param.get(field) != obj.get(field): - return False - return True - - -def build_extattrs(module, conn, extattrs): - out_extattrs = {} - if extattrs is None: - return None - if isinstance(extattrs, dict): - for key, value in extattrs.items(): - if isinstance(value, str) and isinstance(value, str): - out_extattrs[key] = {"value": value} - else: - module.fail_json(msg="A propter key/value pair was not a string {}.".format(str(key), str(value))) - return out_extattrs - module.fail_json(msg="A propter extattrs dict was not found {}.".format(str(extattrs))) - - -def main(): - module = AnsibleModule( - argument_spec=dict( - provider=dict(type='dict', required=True), - state=dict(type='str', required=True), - network_view=dict(type='str', required=True), - network=dict(type='str', required=False), - extattrs=dict(type='dict', required=False), - comment=dict(type='str', required=False), - filters=dict(type='str', required=False), - dhcp_options=dict(type='list', required=False), - members=dict(type='list', required=False), - ), - required_one_of=( - ['network', 'filters'], - ), - supports_check_mode=False - ) - - if not HAS_INFOBLOX_CLIENT: - raise Exception('infoblox-client is not installed. Please see details here: https://github.com/infobloxopen/infoblox-client') - - provider = module.params['provider'] or {} - no_log = ['password'] - for param in no_log: - if provider.get(param): - module.no_log_values.update(return_values(provider[param])) - else: - module.fail_json(msg="Invalid item found in provider.") - - valid_provider = ['host', 'username', 'password', 'validate_certs', 'wapi_version'] - for param, pvalue in provider.items(): - if param in valid_provider: - module.params[param] = module.params.get(param) or pvalue - - required_params = ['host', 'username', 'password'] - for param in required_params: - if not module.params.get(param): - module.fail_json(msg="Provider option {} is required.".format(provider)) - - host = module.params['host'] - username = module.params['username'] - password = module.params['password'] - validate_certs = module.params.get('validate_certs', False) - wapi_version = module.params.get('wapi_version', BASE_WAPI) - state = module.params['state'] - network_view = module.params.get('network_view', 'default') - network = module.params['network'] - extattrs = module.params['extattrs'] - comment = module.params['comment'] - filters = module.params['filters'] - dhcp_options = module.params.get('dhcp_options', None) - members = module.params['members'] - - if members is not None: - module.fail_json(msg="Members has not yet been implemented.") - - opts = {'host': host, 'username': username, 'password': password, 'ssl_verify': validate_certs, - 'silent_ssl_warnings': validate_certs is False, wapi_version: wapi_version} - conn = connector.Connector(opts) - - extattrs = build_extattrs(module, conn, extattrs) - - if state == 'get': - if network: - obj = get_network(module, conn, network_view, network=network) - if isinstance(obj, list): - module.exit_json(changed=False, results=obj) - else: - module.fail_json(msg="Network {} was not found".format(network)) - elif filters: - # TODO - pass - get_network(module, conn, network_view, filters=filters) - elif state == 'present': - return_fields = objects.Network._return_fields - obj = get_network(module, conn, network_view, network=network) - if isinstance(obj, list): - if compare_fields(module, conn, module.params, obj[0]) is False: - results = objects.Network.create(conn, update_if_exists=True, - network_view=network_view, cidr=network, - comment=comment, options=dhcp_options, extattrs=extattrs) - obj = get_network(module, conn, network_view, network=network) - module.exit_json(changed=True, results=str(obj)) - else: - module.exit_json(changed=False, results=obj) - else: - results = objects.Network.create(conn, - network_view=network_view, cidr=network, - comment=comment, options=dhcp_options, extattrs=extattrs) - obj = get_network(module, conn, network_view, network=network) - module.exit_json(changed=True, results=str(obj)) - elif state == 'absent': - find_network = objects.Network.search(conn, network_view=network_view, cidr=network) - if find_network is None: - module.exit_json(changed=False, results="Network {} did not exit".format(network)) - find_network.delete() - module.exit_json(changed=True, results="Network {} has been deleted".format(network)) - - -if __name__ == "__main__": - main() diff --git a/ansible_collection/infoblox/nios_modules/playbooks/create_a_record.yaml b/playbooks/create_a_record.yaml similarity index 100% rename from ansible_collection/infoblox/nios_modules/playbooks/create_a_record.yaml rename to playbooks/create_a_record.yaml diff --git a/ansible_collection/infoblox/nios_modules/playbooks/create_cname_record.yaml b/playbooks/create_cname_record.yaml similarity index 100% rename from ansible_collection/infoblox/nios_modules/playbooks/create_cname_record.yaml rename to playbooks/create_cname_record.yaml diff --git a/ansible_collection/infoblox/nios_modules/playbooks/create_dns_view.yml b/playbooks/create_dns_view.yml similarity index 100% rename from ansible_collection/infoblox/nios_modules/playbooks/create_dns_view.yml rename to playbooks/create_dns_view.yml diff --git a/playbooks/create_dtc_lbdn.yml b/playbooks/create_dtc_lbdn.yml new file mode 100644 index 00000000..9cbf3ad2 --- /dev/null +++ b/playbooks/create_dtc_lbdn.yml @@ -0,0 +1,29 @@ +--- +- hosts: localhost + vars: + nios_provider: + host: 10.196.205.10 + username: cloudadmin + password: infoblox + wapi_version: "2.12" + + connection: local + tasks: + - name: 'create DTC LBDN' + infoblox.nios_modules.nios_dtc_lbdn: + name: LBDN1 + lb_method: GLOBAL_AVAILABILITY + pools: + - pool: Pool1 + ratio: 2 + ttl: 100 + auth_zones: + - 'demo.com' + patterns: + - '*.demo.com' + types: + - A + comment: Created with Ansible + state: present + provider: "{{ nios_provider }}" +... diff --git a/playbooks/create_dtc_pool.yml b/playbooks/create_dtc_pool.yml new file mode 100644 index 00000000..96a59f29 --- /dev/null +++ b/playbooks/create_dtc_pool.yml @@ -0,0 +1,25 @@ +--- +- hosts: localhost + vars: + nios_provider: + host: 10.196.205.10 + username: cloudadmin + password: infoblox + wapi_version: "2.12" + + connection: local + tasks: + - name: 'create DTC Pool' + infoblox.nios_modules.nios_dtc_pool: + name: Pool1 + lb_preferred_method: ROUND_ROBIN + servers: + - server: Server1 + ratio: 1 + monitors: + - name: monitor1 + type: icmp + comment: Created with Ansible + state: present + provider: "{{ nios_provider }}" +... diff --git a/playbooks/create_dtc_server.yml b/playbooks/create_dtc_server.yml new file mode 100644 index 00000000..dd0c0388 --- /dev/null +++ b/playbooks/create_dtc_server.yml @@ -0,0 +1,19 @@ +--- +- hosts: localhost + vars: + nios_provider: + host: 10.196.205.10 + username: cloudadmin + password: infoblox + wapi_version: "2.12" + + connection: local + tasks: + - name: 'create DTC server' + infoblox.nios_modules.nios_dtc_server: + name: Server1 + host: 10.196.200.74 + comment: Created with Ansible + state: present + provider: "{{ nios_provider }}" +... diff --git a/ansible_collection/infoblox/nios_modules/playbooks/create_mx_record.yaml b/playbooks/create_mx_record.yaml similarity index 100% rename from ansible_collection/infoblox/nios_modules/playbooks/create_mx_record.yaml rename to playbooks/create_mx_record.yaml diff --git a/ansible_collection/infoblox/nios_modules/playbooks/create_network.yml b/playbooks/create_network.yml similarity index 100% rename from ansible_collection/infoblox/nios_modules/playbooks/create_network.yml rename to playbooks/create_network.yml diff --git a/ansible_collection/infoblox/nios_modules/playbooks/create_network_view.yml b/playbooks/create_network_view.yml similarity index 100% rename from ansible_collection/infoblox/nios_modules/playbooks/create_network_view.yml rename to playbooks/create_network_view.yml diff --git a/ansible_collection/infoblox/nios_modules/playbooks/create_txt_record.yaml b/playbooks/create_txt_record.yaml similarity index 100% rename from ansible_collection/infoblox/nios_modules/playbooks/create_txt_record.yaml rename to playbooks/create_txt_record.yaml diff --git a/ansible_collection/infoblox/nios_modules/playbooks/create_zone.yml b/playbooks/create_zone.yml similarity index 100% rename from ansible_collection/infoblox/nios_modules/playbooks/create_zone.yml rename to playbooks/create_zone.yml diff --git a/ansible_collection/infoblox/nios_modules/playbooks/delete_cname_record.yaml b/playbooks/delete_cname_record.yaml similarity index 100% rename from ansible_collection/infoblox/nios_modules/playbooks/delete_cname_record.yaml rename to playbooks/delete_cname_record.yaml diff --git a/ansible_collection/infoblox/nios_modules/playbooks/delete_dnsview.yml b/playbooks/delete_dnsview.yml similarity index 100% rename from ansible_collection/infoblox/nios_modules/playbooks/delete_dnsview.yml rename to playbooks/delete_dnsview.yml diff --git a/ansible_collection/infoblox/nios_modules/playbooks/delete_mx_record.yaml b/playbooks/delete_mx_record.yaml similarity index 100% rename from ansible_collection/infoblox/nios_modules/playbooks/delete_mx_record.yaml rename to playbooks/delete_mx_record.yaml diff --git a/ansible_collection/infoblox/nios_modules/playbooks/delete_network.yml b/playbooks/delete_network.yml similarity index 100% rename from ansible_collection/infoblox/nios_modules/playbooks/delete_network.yml rename to playbooks/delete_network.yml diff --git a/ansible_collection/infoblox/nios_modules/playbooks/delete_network_view.yml b/playbooks/delete_network_view.yml similarity index 100% rename from ansible_collection/infoblox/nios_modules/playbooks/delete_network_view.yml rename to playbooks/delete_network_view.yml diff --git a/ansible_collection/infoblox/nios_modules/playbooks/delete_txt_record.yaml b/playbooks/delete_txt_record.yaml similarity index 100% rename from ansible_collection/infoblox/nios_modules/playbooks/delete_txt_record.yaml rename to playbooks/delete_txt_record.yaml diff --git a/ansible_collection/infoblox/nios_modules/playbooks/delete_zone.yml b/playbooks/delete_zone.yml similarity index 100% rename from ansible_collection/infoblox/nios_modules/playbooks/delete_zone.yml rename to playbooks/delete_zone.yml diff --git a/playbooks/restart_services.yml b/playbooks/restart_services.yml new file mode 100644 index 00000000..23bbe590 --- /dev/null +++ b/playbooks/restart_services.yml @@ -0,0 +1,15 @@ +--- +- hosts: localhost + vars: + nios_provider: + host: 10.196.205.10 + username: cloudadmin + password: infoblox + wapi_version: "2.12" + + connection: local + tasks: + - name: Restart Services + nios_restartservices: + provider: "{{ nios_provider }}" +... diff --git a/ansible_collection/infoblox/nios_modules/playbooks/update_a_record.yml b/playbooks/update_a_record.yml similarity index 100% rename from ansible_collection/infoblox/nios_modules/playbooks/update_a_record.yml rename to playbooks/update_a_record.yml diff --git a/ansible_collection/infoblox/nios_modules/plugins/README.md b/plugins/README.md similarity index 100% rename from ansible_collection/infoblox/nios_modules/plugins/README.md rename to plugins/README.md diff --git a/plugins/doc_fragments/nios.py b/plugins/doc_fragments/nios.py new file mode 100644 index 00000000..b0cf764a --- /dev/null +++ b/plugins/doc_fragments/nios.py @@ -0,0 +1,113 @@ +# -*- coding: utf-8 -*- + +# Copyright: (c) 2015, Peter Sprygada +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +class ModuleDocFragment(object): + + # Standard files documentation fragment + DOCUMENTATION = r''' +options: + provider: + description: + - A dict object containing connection details. + type: dict + suboptions: + host: + description: + - Specifies the DNS host name or address for connecting to the remote + instance of NIOS WAPI over REST + - Value can also be specified using C(INFOBLOX_HOST) environment + variable. + type: str + username: + description: + - Configures the username to use to authenticate the connection to + the remote instance of NIOS. + - Value can also be specified using C(INFOBLOX_USERNAME) environment + variable. + type: str + password: + description: + - Specifies the password to use to authenticate the connection to + the remote instance of NIOS. + - Value can also be specified using C(INFOBLOX_PASSWORD) environment + variable. + type: str + cert: + description: + - Specifies the client certificate file with digest of x509 config + for extra layer secure connection the remote instance of NIOS. + - Value can also be specified using C(INFOBLOX_CERT) environment + variable. + type: str + key: + description: + - Specifies private key file for encryption with the certificate + in order to connect with remote instance of NIOS. + - Value can also be specified using C(INFOBLOX_KEY) environment + variable. + type: str + validate_certs: + description: + - Boolean value to enable or disable verifying SSL certificates + - Value can also be specified using C(INFOBLOX_SSL_VERIFY) environment + variable. + type: bool + default: no + aliases: [ ssl_verify ] + http_request_timeout: + description: + - The amount of time before to wait before receiving a response + - Value can also be specified using C(INFOBLOX_HTTP_REQUEST_TIMEOUT) environment + variable. + type: int + default: 10 + max_retries: + description: + - Configures the number of attempted retries before the connection + is declared usable + - Value can also be specified using C(INFOBLOX_MAX_RETRIES) environment + variable. + type: int + default: 3 + wapi_version: + description: + - Specifies the version of WAPI to use + - Value can also be specified using C(INFOBLOX_WAP_VERSION) environment + variable. + - Until ansible 2.8 the default WAPI was 1.4 + type: str + default: '2.1' + max_results: + description: + - Specifies the maximum number of objects to be returned, + if set to a negative number the appliance will return an error when the + number of returned objects would exceed the setting. + - Value can also be specified using C(INFOBLOX_MAX_RESULTS) environment + variable. + type: int + default: 1000 + http_pool_maxsize: + description: + - Insert description here + type: int + default: 10 + http_pool_connections: + description: + - Insert decription here + type: int + default: 10 + silent_ssl_warnings: + description: + - Insert description here + type: bool + default: True +notes: + - "This module must be run locally, which can be achieved by specifying C(connection: local)." + - Please read the :ref:`nios_guide` for more detailed information on how to use Infoblox with Ansible. + +''' diff --git a/ansible_collection/infoblox/nios_modules/plugins/inventory/nios_inventory.py b/plugins/inventory/nios_inventory.py similarity index 51% rename from ansible_collection/infoblox/nios_modules/plugins/inventory/nios_inventory.py rename to plugins/inventory/nios_inventory.py index ac10a635..f23c0273 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/inventory/nios_inventory.py +++ b/plugins/inventory/nios_inventory.py @@ -1,70 +1,89 @@ -#!/usr/bin/python +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type # Copyright (c) 2018-2019 Red Hat, Inc. # Copyright (c) 2020 Infoblox, Inc. # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) DOCUMENTATION = r''' - name: Infoblox - plugin_type: inventory + name: nios_inventory author: - Will Tome (@willtome) short_description: Infoblox inventory plugin - version_added: "2.10" + version_added: "1.0.0" description: - - Infoblox inventory plugin + - This plugin allows you to query the Infoblox Grid for host records and + use the response data to populate the inventory file. options: host: - description: Infoblox server + description: + - Specifies the DNS host name or address for connecting to the remote + instance of NIOS WAPI over REST. + - Value can also be specified using C(INFOBLOX_HOST) environment + variable. type: string required: True env: - name: INFOBLOX_HOST username: - description: username + description: + - Configures the username to use to authenticate the connection to + the remote instance of NIOS. + - Value can also be specified using C(INFOBLOX_USERNAME) environment + variable. type: string required: True env: - name: INFOBLOX_USERNAME password: - description: password + description: + - Specifies the password to use to authenticate the connection to + the remote instance of NIOS. + - Value can also be specified using C(INFOBLOX_PASSWORD) environment + variable. type: string - secret: true env: - name: INFOBLOX_PASSWORD extattrs: - description: restrict returned hosts by extensible attributes + description: + - Allows you to filter the returned host record based on the + extensible attributes assigned to them. default: {} + type: dict hostfilter: - description: restrict returned hosts + description: + - Accepts a key/value pair and uses it to filter the + host records to be returned. default: {} + type: dict requirements: - python >= 3.4 - infoblox-client ''' EXAMPLES = r''' -plugin: infoblox +plugin: infoblox.nios_modules.nios_inventory host: blox.example.com username: admin ''' + from ansible.plugins.inventory import BaseInventoryPlugin from ..module_utils.api import WapiInventory from ..module_utils.api import normalize_extattrs, flatten_extattrs from ansible.module_utils.six import iteritems +from ansible.errors import AnsibleError class InventoryModule(BaseInventoryPlugin): - - NAME = 'infoblox' + NAME = 'nios_inventory' def parse(self, inventory, loader, path, cache=True): # Plugin interface (2) super(InventoryModule, self).parse(inventory, loader, path) self._read_config_data(path) - provider = { 'host': self.get_option('host'), - 'username': self.get_option('username'), - 'password': self.get_option('password')} + provider = {'host': self.get_option('host'), + 'username': self.get_option('username'), + 'password': self.get_option('password')} wapi = WapiInventory(provider) @@ -72,12 +91,10 @@ def parse(self, inventory, loader, path, cache=True): # Plugin interface (2) extattrs = normalize_extattrs(self.get_option('extattrs')) return_fields = ['name', 'view', 'extattrs', 'ipv4addrs'] - print(host_filter) + hosts = wapi.get_object('record:host', host_filter, extattrs=extattrs, return_fields=return_fields) or [] - hosts = wapi.get_object('record:host', - host_filter, - extattrs=extattrs, - return_fields=return_fields) + if not hosts: + raise AnsibleError("host record is not present") for host in hosts: group_name = self.inventory.add_group(host['view']) diff --git a/ansible_collection/infoblox/nios_modules/plugins/lookup/nios_lookup.py b/plugins/lookup/nios_lookup.py similarity index 63% rename from ansible_collection/infoblox/nios_modules/plugins/lookup/nios_lookup.py rename to plugins/lookup/nios_lookup.py index 5b3694b3..c33b212f 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/lookup/nios_lookup.py +++ b/plugins/lookup/nios_lookup.py @@ -1,4 +1,3 @@ -#!/usr/bin/python # Copyright (c) 2018-2019 Red Hat, Inc. # Copyright (c) 2020 Infoblox, Inc. # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) @@ -10,37 +9,43 @@ DOCUMENTATION = ''' --- -lookup: nios +name: nios_lookup short_description: Query Infoblox NIOS objects +version_added: "1.0.0" description: - Uses the Infoblox WAPI API to fetch NIOS specified objects. This lookup supports adding additional keywords to filter the return data and specify the desired set of returned fields. requirements: - infoblox-client -extends_documentation_fragment: -- community.general.nios options: _terms: - description: The name of the object to return from NIOS + description: + - The name of the network object to be returned from the Infoblox appliance. required: True + type: str return_fields: description: The list of field names to return for the specified object. + type: list + elements: str filter: - description: a dict object that is used to filter the return objects + description: A dict object that is used to filter the returned objects. + type: dict extattrs: - description: a dict object that is used to filter on extattrs + description: A dict object that is used to filter based on extensible attributes. + type: dict ''' EXAMPLES = """ - name: fetch all networkview objects - set_fact: - networkviews: "{{ lookup('nios', 'networkview', provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}" + ansible.builtin.set_fact: + networkviews: "{{ lookup('infoblox.nios_modules.nios_lookup', 'networkview', provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}" - name: fetch the default dns view - set_fact: - dns_views: "{{ lookup('nios', 'view', filter={'name': 'default'}, provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}" + ansible.builtin.set_fact: + dns_views: "{{ lookup('infoblox.nios_modules.nios_lookup', 'view', filter={'name': 'default'}, + provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}" # all of the examples below use credentials that are set using env variables # export INFOBLOX_HOST=nios01 @@ -48,21 +53,21 @@ # export INFOBLOX_PASSWORD=admin - name: fetch all host records and include extended attributes - set_fact: - host_records: "{{ lookup('nios', 'record:host', return_fields=['extattrs', 'name', 'view', 'comment']}) }}" + ansible.builtin.set_fact: + host_records: "{{ lookup('infoblox.nios_modules.nios_lookup', 'record:host', return_fields=['extattrs', 'name', 'view', 'comment']}) }}" - name: use env variables to pass credentials - set_fact: - networkviews: "{{ lookup('nios', 'networkview') }}" + ansible.builtin.set_fact: + networkviews: "{{ lookup('infoblox.nios_modules.nios_lookup', 'networkview') }}" - name: get a host record - set_fact: - host: "{{ lookup('nios', 'record:host', filter={'name': 'hostname.ansible.com'}) }}" + ansible.builtin.set_fact: + host: "{{ lookup('infoblox.nios_modules.nios_lookup', 'record:host', filter={'name': 'hostname.ansible.com'}) }}" - name: get the authoritative zone from a non default dns view - set_fact: - host: "{{ lookup('nios', 'zone_auth', filter={'fqdn': 'ansible.com', 'view': 'ansible-dns'}) }}" + ansible.builtin.set_fact: + host: "{{ lookup('infoblox.nios_modules.nios_lookup', 'zone_auth', filter={'fqdn': 'ansible.com', 'view': 'ansible-dns'}) }}" """ RETURN = """ @@ -70,20 +75,20 @@ description: - The object type specified in the terms argument returned: always - type: complex + type: list contains: obj_field: + description: - One or more obj_type fields as specified by return_fields argument or the default set of fields as per the object type """ from ansible.plugins.lookup import LookupBase -#from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiLookup -#from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_extattrs, flatten_extattrs from ansible.errors import AnsibleError from ..module_utils.api import WapiLookup from ..module_utils.api import normalize_extattrs, flatten_extattrs + class LookupModule(LookupBase): def run(self, terms, variables=None, **kwargs): diff --git a/ansible_collection/infoblox/nios_modules/plugins/lookup/nios_next_ip.py b/plugins/lookup/nios_next_ip.py similarity index 51% rename from ansible_collection/infoblox/nios_modules/plugins/lookup/nios_next_ip.py rename to plugins/lookup/nios_next_ip.py index 69003d2e..e2fa076d 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/lookup/nios_next_ip.py +++ b/plugins/lookup/nios_next_ip.py @@ -1,4 +1,3 @@ -#!/usr/bin/python # Copyright (c) 2018-2019 Red Hat, Inc. # Copyright (c) 2020 Infoblox, Inc. # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) @@ -10,42 +9,60 @@ DOCUMENTATION = ''' --- -lookup: nios_next_ip +name: nios_next_ip short_description: Return the next available IP address for a network +version_added: "1.0.0" description: - Uses the Infoblox WAPI API to return the next available IP addresses for a given network CIDR requirements: - infoblox-client -extends_documentation_fragment: -- community.general.nios options: _terms: - description: The CIDR network to retrieve the next addresses from + description: The CIDR network to retrieve the next address(es) from. required: True + type: str num: - description: The number of IP addresses to return + description: The number of IP address(es) to return. required: false default: 1 + type: int exclude: - description: List of IP's that need to be excluded from returned IP addresses + description: List of IP's that need to be excluded from returned IP addresses. required: false + type: list + elements: str + network_view: + description: The network view to retrieve the CIDR network from. + required: false + default: default + type: str ''' EXAMPLES = """ - name: return next available IP address for network 192.168.10.0/24 - set_fact: - ipaddr: "{{ lookup('nios_next_ip', '192.168.10.0/24', provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}" + ansible.builtin.set_fact: + ipaddr: "{{ lookup('infoblox.nios_modules.nios_next_ip', '192.168.10.0/24', provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}" + +- name: return next available IP address for network 192.168.10.0/24 in a non-default network view + ansible.builtin.set_fact: + ipaddr: "{{ lookup('infoblox.nios_modules.nios_next_ip', '192.168.10.0/24', network_view='ansible', \ + provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}" - name: return the next 3 available IP addresses for network 192.168.10.0/24 - set_fact: - ipaddr: "{{ lookup('nios_next_ip', '192.168.10.0/24', num=3, provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}" + ansible.builtin.set_fact: + ipaddr: "{{ lookup('infoblox.nios_modules.nios_next_ip', '192.168.10.0/24', num=3, + provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}" - name: return the next 3 available IP addresses for network 192.168.10.0/24 excluding ip addresses - ['192.168.10.1', '192.168.10.2'] - set_fact: - ipaddr: "{{ lookup('nios_next_ip', '192.168.10.0/24', num=3, exclude=['192.168.10.1', '192.168.10.2'], + ansible.builtin.set_fact: + ipaddr: "{{ lookup('infoblox.nios_modules.nios_next_ip', '192.168.10.0/24', num=3, exclude=['192.168.10.1', '192.168.10.2'], provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}" + +- name: return next available IP address for network fd30:f52:2:12::/64 + ansible.builtin.set_fact: + ipaddr: "{{ lookup('infoblox.nios_modules.nios_next_ip', 'fd30:f52:2:12::/64', provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}" """ RETURN = """ @@ -57,11 +74,10 @@ """ from ansible.plugins.lookup import LookupBase -#from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiLookup from ansible.module_utils._text import to_text from ansible.errors import AnsibleError from ..module_utils.api import WapiLookup - +import ipaddress class LookupModule(LookupBase): @@ -75,15 +91,24 @@ def run(self, terms, variables=None, **kwargs): provider = kwargs.pop('provider', {}) wapi = WapiLookup(provider) - network_obj = wapi.get_object('network', {'network': network}) + if isinstance(ipaddress.ip_network(network), ipaddress.IPv6Network): + network_obj = wapi.get_object('ipv6network', {'network': network}) + else: + network_obj = wapi.get_object('network', {'network': network}) + if network_obj is None: raise AnsibleError('unable to find network object %s' % network) num = kwargs.get('num', 1) exclude_ip = kwargs.get('exclude', []) + network_view = kwargs.get('network_view', 'default') try: - ref = network_obj[0]['_ref'] + ref_list = [network['_ref'] for network in network_obj if network['network_view'] == network_view] + if not ref_list: + raise AnsibleError('no records found') + else: + ref = ref_list[0] avail_ips = wapi.call_func('next_available_ip', ref, {'num': num, 'exclude': exclude_ip}) return [avail_ips['ips']] except Exception as exc: diff --git a/ansible_collection/infoblox/nios_modules/plugins/lookup/nios_next_network.py b/plugins/lookup/nios_next_network.py similarity index 66% rename from ansible_collection/infoblox/nios_modules/plugins/lookup/nios_next_network.py rename to plugins/lookup/nios_next_network.py index 1d4ec622..af3dbf65 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/lookup/nios_next_network.py +++ b/plugins/lookup/nios_next_network.py @@ -1,4 +1,3 @@ -#!/usr/bin/python # Copyright (c) 2018-2019 Red Hat, Inc. # Copyright (c) 2020 Infoblox, Inc. # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) @@ -10,50 +9,64 @@ DOCUMENTATION = ''' --- -lookup: nios_next_network +name: nios_next_network short_description: Return the next available network range for a network-container +version_added: "1.0.0" description: - Uses the Infoblox WAPI API to return the next available network addresses for a given network CIDR requirements: - infoblox_client -extends_documentation_fragment: -- community.general.nios options: _terms: description: The CIDR network to retrieve the next network from next available network within the specified container. required: True + type: str cidr: description: - The CIDR of the network to retrieve the next network from next available network within the specified container. Also, Requested CIDR must be specified and greater than the parent CIDR. required: True - default: 24 + type: str num: - description: The number of network addresses to return from network-container + description: The number of network addresses to return from network-container. required: false default: 1 + type: int exclude: - description: Network addresses returned from network-container excluding list of user's input network range + description: Network addresses returned from network-container excluding list of user's input network range. required: false default: '' + type: list + elements: str + network_view: + description: The network view to retrieve the CIDR network from. + required: false + default: default + type: str ''' EXAMPLES = """ - name: return next available network for network-container 192.168.10.0/24 - set_fact: - networkaddr: "{{ lookup('nios_next_network', '192.168.10.0/24', cidr=25, provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}" + ansible.builtin.set_fact: + networkaddr: "{{ lookup('infoblox.nios_modules.nios_next_network', '192.168.10.0/24', cidr=25, + provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}" + +- name: return next available network for network-container 192.168.10.0/24 in a non-default network view + ansible.builtin.set_fact: + networkaddr: "{{ lookup('infoblox.nios_modules.nios_next_network', '192.168.10.0/24', cidr=25, network_view='ansible' + provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}" - name: return the next 2 available network addresses for network-container 192.168.10.0/24 - set_fact: - networkaddr: "{{ lookup('nios_next_network', '192.168.10.0/24', cidr=25, num=2, + ansible.builtin.set_fact: + networkaddr: "{{ lookup('infoblox.nios_modules.nios_next_network', '192.168.10.0/24', cidr=25, num=2, provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}" - name: return the available network addresses for network-container 192.168.10.0/24 excluding network range '192.168.10.0/25' - set_fact: - networkaddr: "{{ lookup('nios_next_network', '192.168.10.0/24', cidr=25, exclude=['192.168.10.0/25'], + ansible.builtin.set_fact: + networkaddr: "{{ lookup('infoblox.nios_modules.nios_next_network', '192.168.10.0/24', cidr=25, exclude=['192.168.10.0/25'], provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}" """ @@ -66,7 +79,6 @@ """ from ansible.plugins.lookup import LookupBase -#from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiLookup from ansible.module_utils._text import to_text from ansible.errors import AnsibleError from ..module_utils.api import WapiLookup @@ -92,9 +104,14 @@ def run(self, terms, variables=None, **kwargs): raise AnsibleError('unable to find network-container object %s' % network) num = kwargs.get('num', 1) exclude_ip = kwargs.get('exclude', []) + network_view = kwargs.get('network_view', 'default') try: - ref = network_obj[0]['_ref'] + ref_list = [network['_ref'] for network in network_obj if network['network_view'] == network_view] + if not ref_list: + raise AnsibleError('no records found') + else: + ref = ref_list[0] avail_nets = wapi.call_func('next_available_network', ref, {'cidr': cidr, 'num': num, 'exclude': exclude_ip}) return [avail_nets['networks']] except Exception as exc: diff --git a/ansible_collection/infoblox/nios_modules/plugins/module_utils/api.py b/plugins/module_utils/api.py similarity index 62% rename from ansible_collection/infoblox/nios_modules/plugins/module_utils/api.py rename to plugins/module_utils/api.py index c1105823..018e9f15 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/module_utils/api.py +++ b/plugins/module_utils/api.py @@ -1,3 +1,5 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type # This code is part of Ansible, but is an independent component. # This particular file snippet, and this file snippet only, is BSD licensed. # Modules you write using this snippet, which is embedded dynamically by Ansible @@ -26,12 +28,16 @@ # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # + +import json import os from functools import partial from ansible.module_utils._text import to_native from ansible.module_utils.six import iteritems from ansible.module_utils._text import to_text from ansible.module_utils.basic import env_fallback +from ansible.module_utils.common.validation import check_type_dict, safe_eval +from ansible.module_utils.six import string_types try: from infoblox_client.connector import Connector @@ -62,11 +68,16 @@ NIOS_IPV4_NETWORK_CONTAINER = 'networkcontainer' NIOS_IPV6_NETWORK_CONTAINER = 'ipv6networkcontainer' NIOS_MEMBER = 'member' +NIOS_DTC_SERVER = 'dtc:server' +NIOS_DTC_POOL = 'dtc:pool' +NIOS_DTC_LBDN = 'dtc:lbdn' NIOS_PROVIDER_SPEC = { 'host': dict(fallback=(env_fallback, ['INFOBLOX_HOST'])), 'username': dict(fallback=(env_fallback, ['INFOBLOX_USERNAME'])), 'password': dict(fallback=(env_fallback, ['INFOBLOX_PASSWORD']), no_log=True), + 'cert': dict(fallback=(env_fallback, ['INFOBLOX_CERT'])), + 'key': dict(fallback=(env_fallback, ['INFOBLOX_KEY']), no_log=True), 'validate_certs': dict(type='bool', default=False, fallback=(env_fallback, ['INFOBLOX_SSL_VERIFY']), aliases=['ssl_verify']), 'silent_ssl_warnings': dict(type='bool', default=True), 'http_request_timeout': dict(type='int', default=10, fallback=(env_fallback, ['INFOBLOX_HTTP_REQUEST_TIMEOUT'])), @@ -158,7 +169,7 @@ def member_normalize(member_spec): 'pre_provisioning', 'network_setting', 'v6_network_setting', 'ha_port_setting', 'lan_port_setting', 'lan2_physical_setting', 'lan_ha_port_setting', 'mgmt_network_setting', 'v6_mgmt_network_setting'] - for key in member_spec.keys(): + for key in list(member_spec.keys()): if key in member_elements and member_spec[key] is not None: member_spec[key] = member_spec[key][0] if isinstance(member_spec[key], dict): @@ -172,6 +183,15 @@ def member_normalize(member_spec): return member_spec +def normalize_ib_spec(ib_spec): + result = {} + for arg in ib_spec: + result[arg] = dict([(k, v) + for k, v in iteritems(ib_spec[arg]) + if k not in ('ib_req', 'transform', 'update')]) + return result + + class WapiBase(object): ''' Base class for implementing Infoblox WAPI API ''' provider_spec = {'provider': dict(type='dict', options=NIOS_PROVIDER_SPEC)} @@ -265,13 +285,10 @@ def run(self, ib_obj_type, ib_spec): else: proposed_object[key] = self.module.params[key] - # If configure_by_dns is set to False, then delete the default dns set in the param else throw exception + # If configure_by_dns is set to False and view is 'default', then delete the default dns if not proposed_object.get('configure_for_dns') and proposed_object.get('view') == 'default'\ and ib_obj_type == NIOS_HOST_RECORD: del proposed_object['view'] - elif not proposed_object.get('configure_for_dns') and proposed_object.get('view') != 'default'\ - and ib_obj_type == NIOS_HOST_RECORD: - self.module.fail_json(msg='DNS Bypass is not allowed if DNS view is set other than \'default\'') if ib_obj_ref: if len(ib_obj_ref) > 1: @@ -280,7 +297,7 @@ def run(self, ib_obj_type, ib_spec): if each.get('ipv4addr') and each.get('ipv4addr') == proposed_object.get('ipv4addr'): current_object = each # To check for existing Host_record with same name with input Host_record by IP - elif each.get('ipv4addrs')[0].get('ipv4addr') and each.get('ipv4addrs')[0].get('ipv4addr')\ + elif each.get('ipv4addrs') and each.get('ipv4addrs')[0].get('ipv4addr')\ == proposed_object.get('ipv4addrs')[0].get('ipv4addr'): current_object = each # Else set the current_object with input value @@ -300,10 +317,39 @@ def run(self, ib_obj_type, ib_spec): if (ib_obj_type == NIOS_MEMBER): proposed_object = member_normalize(proposed_object) + # checks if the 'text' field has to be updated for the TXT Record + if (ib_obj_type == NIOS_TXT_RECORD): + text_obj = proposed_object["text"] + if text_obj.startswith("{"): + try: + text_obj = json.loads(text_obj) + txt = text_obj['new_text'] + except Exception: + (result, exc) = safe_eval(text_obj, dict(), include_exceptions=True) + if exc is not None: + raise TypeError('unable to evaluate string as dictionary') + txt = result['new_text'] + proposed_object['text'] = txt + # checks if the name's field has been updated if update and new_name: proposed_object['name'] = new_name + check_remove = [] + if (ib_obj_type == NIOS_HOST_RECORD): + # this check is for idempotency, as if the same ip address shall be passed + # add param will be removed, and same exists true for remove case as well. + if 'ipv4addrs' in [current_object and proposed_object]: + for each in current_object['ipv4addrs']: + if each['ipv4addr'] == proposed_object['ipv4addrs'][0]['ipv4addr']: + if 'add' in proposed_object['ipv4addrs'][0]: + del proposed_object['ipv4addrs'][0]['add'] + break + check_remove += each.values() + if proposed_object['ipv4addrs'][0]['ipv4addr'] not in check_remove: + if 'remove' in proposed_object['ipv4addrs'][0]: + del proposed_object['ipv4addrs'][0]['remove'] + res = None modified = not self.compare_objects(current_object, proposed_object) if 'extattrs' in proposed_object: @@ -324,28 +370,53 @@ def run(self, ib_obj_type, ib_spec): result['api_results'] = self.call_func('create_token', ref, proposed_object) result['changed'] = True elif modified: - self.check_if_recordname_exists(obj_filter, ib_obj_ref, ib_obj_type, current_object, proposed_object) + if 'ipv4addrs' in proposed_object: + if ('add' not in proposed_object['ipv4addrs'][0]) and ('remove' not in proposed_object['ipv4addrs'][0]): + self.check_if_recordname_exists(obj_filter, ib_obj_ref, ib_obj_type, current_object, proposed_object) if (ib_obj_type in (NIOS_HOST_RECORD, NIOS_NETWORK_VIEW, NIOS_DNS_VIEW)): + run_update = True proposed_object = self.on_update(proposed_object, ib_spec) - res = self.update_object(ref, proposed_object) - if (ib_obj_type in (NIOS_A_RECORD, NIOS_AAAA_RECORD)): - # popping 'view' key as update of 'view' is not supported with respect to a:record/aaaa:record + if 'ipv4addrs' in proposed_object: + if ('add' or 'remove') in proposed_object['ipv4addrs'][0]: + run_update, proposed_object = self.check_if_add_remove_ip_arg_exists(proposed_object) + if run_update: + res = self.update_object(ref, proposed_object) + result['changed'] = True + else: + res = ref + + if (ib_obj_type in (NIOS_A_RECORD, NIOS_AAAA_RECORD, NIOS_PTR_RECORD, NIOS_SRV_RECORD, NIOS_NAPTR_RECORD)): + # popping 'view' key as update of 'view' is not supported with respect to a:record/aaaa:record/srv:record/ptr:record/naptr:record proposed_object = self.on_update(proposed_object, ib_spec) del proposed_object['view'] - res = self.update_object(ref, proposed_object) - elif 'network_view' in proposed_object: + if not self.module.check_mode: + res = self.update_object(ref, proposed_object) + result['changed'] = True + if (ib_obj_type in (NIOS_ZONE)): + # popping 'zone_format' key as update of 'zone_format' is not supported with respect to zone_auth + proposed_object = self.on_update(proposed_object, ib_spec) + del proposed_object['zone_format'] + self.update_object(ref, proposed_object) + result['changed'] = True + elif 'network_view' in proposed_object and (ib_obj_type not in (NIOS_IPV4_FIXED_ADDRESS, NIOS_IPV6_FIXED_ADDRESS)): proposed_object.pop('network_view') + result['changed'] = True if not self.module.check_mode and res is None: proposed_object = self.on_update(proposed_object, ib_spec) self.update_object(ref, proposed_object) - result['changed'] = True + result['changed'] = True elif state == 'absent': if ref is not None: - if not self.module.check_mode: + if 'ipv4addrs' in proposed_object: + if 'remove' in proposed_object['ipv4addrs'][0]: + self.check_if_add_remove_ip_arg_exists(proposed_object) + self.update_object(ref, proposed_object) + result['changed'] = True + elif not self.module.check_mode: self.delete_object(ref) - result['changed'] = True + result['changed'] = True return result @@ -374,15 +445,43 @@ def check_if_nios_next_ip_exists(self, proposed_object): if 'ipv4addrs' in proposed_object: if 'nios_next_ip' in proposed_object['ipv4addrs'][0]['ipv4addr']: - ip_range = self.module._check_type_dict(proposed_object['ipv4addrs'][0]['ipv4addr'])['nios_next_ip'] + ip_range = check_type_dict(proposed_object['ipv4addrs'][0]['ipv4addr'])['nios_next_ip'] proposed_object['ipv4addrs'][0]['ipv4addr'] = NIOS_NEXT_AVAILABLE_IP + ':' + ip_range elif 'ipv4addr' in proposed_object: if 'nios_next_ip' in proposed_object['ipv4addr']: - ip_range = self.module._check_type_dict(proposed_object['ipv4addr'])['nios_next_ip'] + ip_range = check_type_dict(proposed_object['ipv4addr'])['nios_next_ip'] proposed_object['ipv4addr'] = NIOS_NEXT_AVAILABLE_IP + ':' + ip_range return proposed_object + def check_if_add_remove_ip_arg_exists(self, proposed_object): + ''' + This function shall check if add/remove param is set to true and + is passed in the args, then we will update the proposed dictionary + to add/remove IP to existing host_record, if the user passes false + param with the argument nothing shall be done. + :returns: True if param is changed based on add/remove, and also the + changed proposed_object. + ''' + update = False + if 'add' in proposed_object['ipv4addrs'][0]: + if proposed_object['ipv4addrs'][0]['add']: + proposed_object['ipv4addrs+'] = proposed_object['ipv4addrs'] + del proposed_object['ipv4addrs'] + del proposed_object['ipv4addrs+'][0]['add'] + update = True + else: + del proposed_object['ipv4addrs'][0]['add'] + elif 'remove' in proposed_object['ipv4addrs'][0]: + if proposed_object['ipv4addrs'][0]['remove']: + proposed_object['ipv4addrs-'] = proposed_object['ipv4addrs'] + del proposed_object['ipv4addrs'] + del proposed_object['ipv4addrs-'][0]['remove'] + update = True + else: + del proposed_object['ipv4addrs'][0]['remove'] + return update, proposed_object + def issubset(self, item, objects): ''' Checks if item is a subset of objects :args item: the subset item to validate @@ -408,6 +507,9 @@ def compare_objects(self, current_object, proposed_object): return False elif isinstance(proposed_item, list): + if key == 'aliases': + if set(current_item) != set(proposed_item): + return False for subitem in proposed_item: if not self.issubset(subitem, current_item): return False @@ -426,52 +528,139 @@ def get_object_ref(self, module, ib_obj_type, obj_filter, ib_spec): update = False old_name = new_name = None + old_ipv4addr_exists = old_text_exists = False if ('name' in obj_filter): # gets and returns the current object based on name/old_name passed try: - name_obj = self.module._check_type_dict(obj_filter['name']) - old_name = name_obj['old_name'] - new_name = name_obj['new_name'] + name_obj = check_type_dict(obj_filter['name']) + # check if network_view allows searching and updating with camelCase + if (ib_obj_type == NIOS_NETWORK_VIEW): + old_name = name_obj['old_name'] + new_name = name_obj['new_name'] + else: + old_name = name_obj['old_name'].lower() + new_name = name_obj['new_name'].lower() except TypeError: name = obj_filter['name'] if old_name and new_name: if (ib_obj_type == NIOS_HOST_RECORD): test_obj_filter = dict([('name', old_name), ('view', obj_filter['view'])]) - elif (ib_obj_type in (NIOS_AAAA_RECORD, NIOS_A_RECORD)): - test_obj_filter = obj_filter else: test_obj_filter = dict([('name', old_name)]) # get the object reference - ib_obj = self.get_object(ib_obj_type, test_obj_filter, return_fields=ib_spec.keys()) + ib_obj = self.get_object(ib_obj_type, test_obj_filter, return_fields=list(ib_spec.keys())) if ib_obj: obj_filter['name'] = new_name else: - test_obj_filter['name'] = new_name - ib_obj = self.get_object(ib_obj_type, test_obj_filter, return_fields=ib_spec.keys()) + raise Exception("object with name: '%s' is not found" % (old_name)) update = True return ib_obj, update, new_name if (ib_obj_type == NIOS_HOST_RECORD): + # to fix the sanity issue + name = obj_filter['name'] # to check only by name if dns bypassing is set if not obj_filter['configure_for_dns']: test_obj_filter = dict([('name', name)]) else: test_obj_filter = dict([('name', name), ('view', obj_filter['view'])]) - elif (ib_obj_type == NIOS_IPV4_FIXED_ADDRESS or ib_obj_type == NIOS_IPV6_FIXED_ADDRESS and 'mac' in obj_filter): + elif (ib_obj_type == NIOS_IPV4_FIXED_ADDRESS and 'mac' in obj_filter): test_obj_filter = dict([['mac', obj_filter['mac']]]) + elif (ib_obj_type == NIOS_IPV6_FIXED_ADDRESS and 'duid' in obj_filter): + test_obj_filter = dict([['duid', obj_filter['duid']]]) + elif (ib_obj_type == NIOS_CNAME_RECORD): + test_obj_filter = dict([('name', obj_filter['name']), ('view', obj_filter['view'])]) elif (ib_obj_type == NIOS_A_RECORD): # resolves issue where a_record with uppercase name was returning null and was failing test_obj_filter = obj_filter test_obj_filter['name'] = test_obj_filter['name'].lower() + # resolves issue where multiple a_records with same name and different IP address + try: + ipaddr_obj = check_type_dict(obj_filter['ipv4addr']) + ipaddr = ipaddr_obj.get('old_ipv4addr') + old_ipv4addr_exists = True if ipaddr else False + except TypeError: + ipaddr = obj_filter['ipv4addr'] + test_obj_filter['ipv4addr'] = ipaddr + elif (ib_obj_type == NIOS_TXT_RECORD): + # resolves issue where multiple txt_records with same name and different text + test_obj_filter = obj_filter + try: + text_obj = obj_filter['text'] + if text_obj.startswith("{"): + try: + text_obj = json.loads(text_obj) + txt = text_obj['old_text'] + old_text_exists = True + except Exception: + (result, exc) = safe_eval(text_obj, dict(), include_exceptions=True) + if exc is not None: + raise TypeError('unable to evaluate string as dictionary') + txt = result['old_text'] + old_text_exists = True + else: + txt = text_obj + except TypeError: + txt = obj_filter['text'] + test_obj_filter['text'] = txt # check if test_obj_filter is empty copy passed obj_filter else: test_obj_filter = obj_filter - ib_obj = self.get_object(ib_obj_type, test_obj_filter.copy(), return_fields=ib_spec.keys()) + ib_obj = self.get_object(ib_obj_type, test_obj_filter.copy(), return_fields=list(ib_spec.keys())) + + # prevents creation of a new A record with 'new_ipv4addr' when A record with a particular 'old_ipv4addr' is not found + if old_ipv4addr_exists and ib_obj is None: + raise Exception("A Record with ipv4addr: '%s' is not found" % (ipaddr)) + # prevents creation of a new TXT record with 'new_text' when TXT record with a particular 'old_text' is not found + if old_text_exists and ib_obj is None: + raise Exception("TXT Record with text: '%s' is not found" % (txt)) + elif (ib_obj_type == NIOS_A_RECORD): + # resolves issue where multiple a_records with same name and different IP address + test_obj_filter = obj_filter + try: + ipaddr_obj = check_type_dict(obj_filter['ipv4addr']) + ipaddr = ipaddr_obj.get('old_ipv4addr') + old_ipv4addr_exists = True if ipaddr else False + except TypeError: + ipaddr = obj_filter['ipv4addr'] + test_obj_filter['ipv4addr'] = ipaddr + # prevents creation of a new A record with 'new_ipv4addr' when A record with a particular 'old_ipv4addr' is not found + if old_ipv4addr_exists and ib_obj is None: + raise Exception("A Record with ipv4addr: '%s' is not found" % (ipaddr)) + ib_obj = self.get_object(ib_obj_type, test_obj_filter.copy(), return_fields=list(ib_spec.keys())) + # prevents creation of a new A record with 'new_ipv4addr' when A record with a particular 'old_ipv4addr' is not found + if old_ipv4addr_exists and ib_obj is None: + raise Exception("A Record with ipv4addr: '%s' is not found" % (ipaddr)) + elif (ib_obj_type == NIOS_TXT_RECORD): + # resolves issue where multiple txt_records with same name and different text + test_obj_filter = obj_filter + try: + text_obj = obj_filter(['text']) + if text_obj.startswith("{"): + try: + text_obj = json.loads(text_obj) + txt = text_obj['old_text'] + old_text_exists = True + except Exception: + (result, exc) = safe_eval(text_obj, dict(), include_exceptions=True) + if exc is not None: + raise TypeError('unable to evaluate string as dictionary') + txt = result['old_text'] + old_text_exists = True + else: + txt = text_obj + except TypeError: + txt = obj_filter['text'] + test_obj_filter['text'] = txt + ib_obj = self.get_object(ib_obj_type, test_obj_filter.copy(), return_fields=list(ib_spec.keys())) + # prevents creation of a new TXT record with 'new_text' when TXT record with a particular 'old_text' is not found + if old_text_exists and ib_obj is None: + raise Exception("TXT Record with text: '%s' is not found" % (txt)) elif (ib_obj_type == NIOS_ZONE): # del key 'restart_if_needed' as nios_zone get_object fails with the key present temp = ib_spec['restart_if_needed'] del ib_spec['restart_if_needed'] - ib_obj = self.get_object(ib_obj_type, obj_filter.copy(), return_fields=ib_spec.keys()) + ib_obj = self.get_object(ib_obj_type, obj_filter.copy(), return_fields=list(ib_spec.keys())) # reinstate restart_if_needed if ib_obj is none, meaning there's no existing nios_zone ref if not ib_obj: ib_spec['restart_if_needed'] = temp @@ -479,12 +668,20 @@ def get_object_ref(self, module, ib_obj_type, obj_filter, ib_spec): # del key 'create_token' as nios_member get_object fails with the key present temp = ib_spec['create_token'] del ib_spec['create_token'] - ib_obj = self.get_object(ib_obj_type, obj_filter.copy(), return_fields=ib_spec.keys()) + ib_obj = self.get_object(ib_obj_type, obj_filter.copy(), return_fields=list(ib_spec.keys())) if temp: # reinstate 'create_token' key ib_spec['create_token'] = temp + elif (ib_obj_type in (NIOS_IPV4_NETWORK, NIOS_IPV6_NETWORK, NIOS_IPV4_NETWORK_CONTAINER, NIOS_IPV6_NETWORK_CONTAINER)): + # del key 'template' as nios_network get_object fails with the key present + temp = ib_spec['template'] + del ib_spec['template'] + ib_obj = self.get_object(ib_obj_type, obj_filter.copy(), return_fields=list(ib_spec.keys())) + if temp: + # reinstate 'template' key + ib_spec['template'] = temp else: - ib_obj = self.get_object(ib_obj_type, obj_filter.copy(), return_fields=ib_spec.keys()) + ib_obj = self.get_object(ib_obj_type, obj_filter.copy(), return_fields=list(ib_spec.keys())) return ib_obj, update, new_name def on_update(self, proposed_object, ib_spec): diff --git a/plugins/module_utils/network.py b/plugins/module_utils/network.py new file mode 100644 index 00000000..4357a9b5 --- /dev/null +++ b/plugins/module_utils/network.py @@ -0,0 +1,19 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +import socket + + +def validate_ip_address(address): + try: + socket.inet_aton(address) + except socket.error: + return False + return address.count('.') == 3 + + +def validate_ip_v6_address(address): + try: + socket.inet_pton(socket.AF_INET6, address) + except socket.error: + return False + return True diff --git a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_a_record.py b/plugins/modules/nios_a_record.py similarity index 79% rename from ansible_collection/infoblox/nios_modules/plugins/modules/nios_a_record.py rename to plugins/modules/nios_a_record.py index 0b690459..0164e94e 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_a_record.py +++ b/plugins/modules/nios_a_record.py @@ -6,59 +6,61 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'certified'} - - DOCUMENTATION = ''' --- module: nios_a_record -version_added: "2.7" author: "Blair Rampling (@brampling)" short_description: Configure Infoblox NIOS A records +version_added: "1.0.0" description: - Adds and/or removes instances of A record objects from Infoblox NIOS servers. This module manages NIOS C(record:a) objects using the Infoblox WAPI interface over REST. requirements: - infoblox-client -extends_documentation_fragment: nios +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). options: name: description: - Specifies the fully qualified hostname to add or remove from - the system + the system. required: true + type: str view: description: - Sets the DNS view to associate this A record with. The DNS - view must already be configured on the system - required: true + view must already be configured on the system. default: default aliases: - dns_view + type: str ipv4addr: description: - Configures the IPv4 address for this A record. Users can dynamically allocate ipv4 address to A record by passing dictionary containing, - I(nios_next_ip) and I(CIDR network range). See example - required: true + I(nios_next_ip) and I(CIDR network range). See example. aliases: - ipv4 + required: true + type: str ttl: description: - - Configures the TTL to be associated with this A record + - Configures the TTL to be associated with this A record. + type: int extattrs: description: - Allows for the configuration of Extensible Attributes on the instance of the object. This argument accepts a set of key / value pairs for configuration. + type: dict comment: description: - Configures a text string comment to be associated with the instance of this object. The provided text string will be configured on the object instance. + type: str state: description: - Configures the intended state of the instance of the object on @@ -69,11 +71,12 @@ choices: - present - absent + type: str ''' EXAMPLES = ''' -- name: configure an A record - nios_a_record: +- name: Configure an A record + infoblox.nios_modules.nios_a_record: name: a.ansible.com ipv4: 192.168.10.1 state: present @@ -83,8 +86,8 @@ password: admin connection: local -- name: add a comment to an existing A record - nios_a_record: +- name: Add a comment to an existing A record + infoblox.nios_modules.nios_a_record: name: a.ansible.com ipv4: 192.168.10.1 comment: this is a test comment @@ -95,8 +98,8 @@ password: admin connection: local -- name: remove an A record from the system - nios_a_record: +- name: Remove an A record from the system + infoblox.nios_modules.nios_a_record: name: a.ansible.com ipv4: 192.168.10.1 state: absent @@ -106,8 +109,8 @@ password: admin connection: local -- name: update an A record name - nios_a_record: +- name: Update an A record name + infoblox.nios_modules.nios_a_record: name: {new_name: a_new.ansible.com, old_name: a.ansible.com} ipv4: 192.168.10.1 state: present @@ -117,8 +120,8 @@ password: admin connection: local -- name: dynamically add a record to next available ip - nios_a_record: +- name: Dynamically add a record to next available ip + infoblox.nios_modules.nios_a_record: name: a.ansible.com ipv4: {nios_next_ip: 192.168.10.0/24} state: present @@ -133,10 +136,10 @@ from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.six import iteritems -#from ansible_collections.saileshgiri.test_col.plugins.module_utils.api import WapiModule -#from ansible_collections.saileshgiri.test_col.plugins.module_utils.api import NIOS_A_RECORD from ..module_utils.api import WapiModule from ..module_utils.api import NIOS_A_RECORD +from ..module_utils.api import normalize_ib_spec + def main(): ''' Main entry point for module execution @@ -146,7 +149,7 @@ def main(): name=dict(required=True, ib_req=True), view=dict(default='default', aliases=['dns_view'], ib_req=True), - ipv4addr=dict(aliases=['ipv4'], ib_req=True), + ipv4addr=dict(required=True, aliases=['ipv4'], ib_req=True), ttl=dict(type='int'), @@ -159,7 +162,7 @@ def main(): state=dict(default='present', choices=['present', 'absent']) ) - argument_spec.update(ib_spec) + argument_spec.update(normalize_ib_spec(ib_spec)) argument_spec.update(WapiModule.provider_spec) module = AnsibleModule(argument_spec=argument_spec, diff --git a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_aaaa_record.py b/plugins/modules/nios_aaaa_record.py similarity index 82% rename from ansible_collection/infoblox/nios_modules/plugins/modules/nios_aaaa_record.py rename to plugins/modules/nios_aaaa_record.py index 935fe376..bbafe8db 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_aaaa_record.py +++ b/plugins/modules/nios_aaaa_record.py @@ -6,57 +6,56 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'certified'} - - DOCUMENTATION = ''' --- module: nios_aaaa_record -version_added: "2.6" author: "Blair Rampling (@brampling)" short_description: Configure Infoblox NIOS AAAA records +version_added: "1.0.0" description: - Adds and/or removes instances of AAAA record objects from Infoblox NIOS servers. This module manages NIOS C(record:aaaa) objects using the Infoblox WAPI interface over REST. requirements: - infoblox-client -extends_documentation_fragment: nios options: name: description: - Specifies the fully qualified hostname to add or remove from - the system + the system. required: true + type: str view: description: - Sets the DNS view to associate this AAAA record with. The DNS - view must already be configured on the system - required: true + view must already be configured on the system. default: default aliases: - dns_view + type: str ipv6addr: description: - Configures the IPv6 address for this AAAA record. - required: true aliases: - ipv6 + required: true + type: str ttl: description: - - Configures the TTL to be associated with this AAAA record + - Configures the TTL to be associated with this AAAA record. + type: int extattrs: description: - Allows for the configuration of Extensible Attributes on the instance of the object. This argument accepts a set of key / value pairs for configuration. + type: dict comment: description: - Configures a text string comment to be associated with the instance of this object. The provided text string will be configured on the object instance. + type: str state: description: - Configures the intended state of the instance of the object on @@ -67,11 +66,16 @@ choices: - present - absent + type: str +extends_documentation_fragment: + - infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). ''' EXAMPLES = ''' -- name: configure an AAAA record - nios_aaaa_record: +- name: Configure an AAAA record + infoblox.nios_modules.nios_aaaa_record: name: aaaa.ansible.com ipv6: 2001:0db8:85a3:0000:0000:8a2e:0370:7334 state: present @@ -81,8 +85,8 @@ password: admin connection: local -- name: add a comment to an existing AAAA record - nios_aaaa_record: +- name: Add a comment to an existing AAAA record + infoblox.nios_modules.nios_aaaa_record: name: aaaa.ansible.com ipv6: 2001:0db8:85a3:0000:0000:8a2e:0370:7334 comment: this is a test comment @@ -93,8 +97,8 @@ password: admin connection: local -- name: remove an AAAA record from the system - nios_aaaa_record: +- name: Remove an AAAA record from the system + infoblox.nios_modules.nios_aaaa_record: name: aaaa.ansible.com ipv6: 2001:0db8:85a3:0000:0000:8a2e:0370:7334 state: absent @@ -104,8 +108,8 @@ password: admin connection: local -- name: update an AAAA record name - nios_aaaa_record: +- name: Update an AAAA record name + infoblox.nios_modules.nios_aaaa_record: name: {new_name: aaaa_new.ansible.com, old_name: aaaa.ansible.com} ipv6: 2001:0db8:85a3:0000:0000:8a2e:0370:7334 state: present @@ -122,6 +126,8 @@ from ansible.module_utils.six import iteritems from ..module_utils.api import WapiModule from ..module_utils.api import NIOS_AAAA_RECORD +from ..module_utils.api import normalize_ib_spec + def main(): ''' Main entry point for module execution @@ -131,7 +137,7 @@ def main(): name=dict(required=True, ib_req=True), view=dict(default='default', aliases=['dns_view'], ib_req=True), - ipv6addr=dict(aliases=['ipv6'], ib_req=True), + ipv6addr=dict(required=True, aliases=['ipv6'], ib_req=True), ttl=dict(type='int'), @@ -144,7 +150,7 @@ def main(): state=dict(default='present', choices=['present', 'absent']) ) - argument_spec.update(ib_spec) + argument_spec.update(normalize_ib_spec(ib_spec)) argument_spec.update(WapiModule.provider_spec) module = AnsibleModule(argument_spec=argument_spec, diff --git a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_cname_record.py b/plugins/modules/nios_cname_record.py similarity index 82% rename from ansible_collection/infoblox/nios_modules/plugins/modules/nios_cname_record.py rename to plugins/modules/nios_cname_record.py index c08320e7..5bc117d1 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_cname_record.py +++ b/plugins/modules/nios_cname_record.py @@ -6,57 +6,59 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'certified'} - - DOCUMENTATION = ''' --- module: nios_cname_record -version_added: "2.7" author: "Blair Rampling (@brampling)" short_description: Configure Infoblox NIOS CNAME records +version_added: "1.0.0" description: - Adds and/or removes instances of CNAME record objects from Infoblox NIOS servers. This module manages NIOS C(record:cname) objects using the Infoblox WAPI interface over REST. requirements: - infoblox-client -extends_documentation_fragment: nios +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). options: name: description: - Specifies the fully qualified hostname to add or remove from - the system + the system. required: true + type: str view: description: - Sets the DNS view to associate this CNAME record with. The DNS - view must already be configured on the system - required: true + view must already be configured on the system. default: default aliases: - dns_view + type: str canonical: description: - Configures the canonical name for this CNAME record. - required: true aliases: - cname + required: true + type: str ttl: description: - - Configures the TTL to be associated with this CNAME record + - Configures the TTL to be associated with this CNAME record. + type: int extattrs: description: - Allows for the configuration of Extensible Attributes on the instance of the object. This argument accepts a set of key / value pairs for configuration. + type: dict comment: description: - Configures a text string comment to be associated with the instance of this object. The provided text string will be configured on the object instance. + type: str state: description: - Configures the intended state of the instance of the object on @@ -67,11 +69,12 @@ choices: - present - absent + type: str ''' EXAMPLES = ''' -- name: configure a CNAME record - nios_cname_record: +- name: Configure a CNAME record + infoblox.nios_modules.nios_cname_record: name: cname.ansible.com canonical: realhost.ansible.com state: present @@ -81,8 +84,8 @@ password: admin connection: local -- name: add a comment to an existing CNAME record - nios_cname_record: +- name: Add a comment to an existing CNAME record + infoblox.nios_modules.nios_cname_record: name: cname.ansible.com canonical: realhost.ansible.com comment: this is a test comment @@ -93,8 +96,8 @@ password: admin connection: local -- name: remove a CNAME record from the system - nios_cname_record: +- name: Remove a CNAME record from the system + infoblox.nios_modules.nios_cname_record: name: cname.ansible.com canonical: realhost.ansible.com state: absent @@ -111,6 +114,7 @@ from ansible.module_utils.six import iteritems from ..module_utils.api import WapiModule from ..module_utils.api import NIOS_CNAME_RECORD +from ..module_utils.api import normalize_ib_spec def main(): @@ -121,7 +125,7 @@ def main(): name=dict(required=True, ib_req=True), view=dict(default='default', aliases=['dns_view'], ib_req=True), - canonical=dict(aliases=['cname'], ib_req=True), + canonical=dict(required=True, aliases=['cname'], ib_req=True), ttl=dict(type='int'), @@ -134,7 +138,7 @@ def main(): state=dict(default='present', choices=['present', 'absent']) ) - argument_spec.update(ib_spec) + argument_spec.update(normalize_ib_spec(ib_spec)) argument_spec.update(WapiModule.provider_spec) module = AnsibleModule(argument_spec=argument_spec, diff --git a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_dns_view.py b/plugins/modules/nios_dns_view.py similarity index 85% rename from ansible_collection/infoblox/nios_modules/plugins/modules/nios_dns_view.py rename to plugins/modules/nios_dns_view.py index 958d2b2c..83790aca 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_dns_view.py +++ b/plugins/modules/nios_dns_view.py @@ -6,17 +6,12 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'certified'} - - DOCUMENTATION = ''' --- module: nios_dns_view -version_added: "2.5" author: "Peter Sprygada (@privateip)" short_description: Configure Infoblox NIOS DNS views +version_added: "1.0.0" description: - Adds and/or removes instances of DNS view objects from Infoblox NIOS servers. This module manages NIOS C(view) objects @@ -24,7 +19,9 @@ - Updates instances of DNS view object from Infoblox NIOS servers. requirements: - infoblox-client -extends_documentation_fragment: nios +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). options: name: description: @@ -34,41 +31,43 @@ required: true aliases: - view + type: str network_view: description: - Specifies the name of the network view to assign the configured DNS view to. The network view must already be configured on the target system. - required: true default: default + type: str extattrs: description: - Allows for the configuration of Extensible Attributes on the instance of the object. This argument accepts a set of key / value pairs for configuration. - required: false + type: dict comment: description: - Configures a text string comment to be associated with the instance of this object. The provided text string will be configured on the object instance. - required: false + type: str state: description: - Configures the intended state of the instance of the object on the NIOS server. When this value is set to C(present), the object is configured on the device and when this value is set to C(absent) the value is removed (if necessary) from the device. - required: false default: present choices: - present - absent + type: str + ''' EXAMPLES = ''' -- name: configure a new dns view instance - nios_dns_view: +- name: Configure a new dns view instance + infoblox.nios_modules.nios_dns_view: name: ansible-dns state: present provider: @@ -76,8 +75,9 @@ username: admin password: admin connection: local -- name: update the comment for dns view - nios_dns_view: + +- name: Update the comment for dns view + infoblox.nios_modules.nios_dns_view: name: ansible-dns comment: this is an example comment state: present @@ -86,8 +86,9 @@ username: admin password: admin connection: local -- name: remove the dns view instance - nios_dns_view: + +- name: Remove the dns view instance + infoblox.nios_modules.nios_dns_view: name: ansible-dns state: absent provider: @@ -95,8 +96,9 @@ username: admin password: admin connection: local -- name: update the dns view instance - nios_dns_view: + +- name: Update the dns view instance + infoblox.nios_modules.nios_dns_view: name: {new_name: ansible-dns-new, old_name: ansible-dns} state: present provider: @@ -111,6 +113,7 @@ from ansible.module_utils.basic import AnsibleModule from ..module_utils.api import WapiModule from ..module_utils.api import NIOS_DNS_VIEW +from ..module_utils.api import normalize_ib_spec def main(): @@ -129,7 +132,7 @@ def main(): state=dict(default='present', choices=['present', 'absent']) ) - argument_spec.update(ib_spec) + argument_spec.update(normalize_ib_spec(ib_spec)) argument_spec.update(WapiModule.provider_spec) module = AnsibleModule(argument_spec=argument_spec, diff --git a/plugins/modules/nios_dtc_lbdn.py b/plugins/modules/nios_dtc_lbdn.py new file mode 100644 index 00000000..392a7cb5 --- /dev/null +++ b/plugins/modules/nios_dtc_lbdn.py @@ -0,0 +1,242 @@ +#!/usr/bin/python +# Copyright (c) 2018-2019 Red Hat, Inc. +# Copyright (c) 2020 Infoblox, Inc. +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: nios_dtc_lbdn +author: "Mauricio Teixeira (@badnetmask)" +version_added: "1.1.0" +short_description: Configure Infoblox NIOS DTC LBDN +description: + - Adds and/or removes instances of DTC Load Balanced Domain Name (LBDN) + objects from Infoblox NIOS servers. This module manages NIOS + C(dtc:lbdn) objects using the Infoblox WAPI interface over REST. +requirements: + - infoblox-client +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). +options: + name: + description: + - Specifies the display name of the DTC LBDN, not DNS related. + required: true + type: str + lb_method: + description: + - Configures the load balancing method. Used to select pool. + required: true + type: str + choices: + - GLOBAL_AVAILABILITY + - RATIO + - ROUND_ROBIN + - TOPOLOGY + auth_zones: + description: + - List of linked authoritative zones. + - When using I(auth_zones), you must specify at least one + I(patterns) + required: false + type: list + elements: str + patterns: + description: + - Specify LBDN wildcards for pattern match. + required: false + type: list + elements: str + types: + description: + - Specifies the list of resource record types supported by LBDN. + - This option will work properly only if you set the C(wapi_version) + variable on your C(provider) variable to a + number higher than "2.6". + required: false + type: list + elements: str + choices: + - A + - AAAA + - CNAME + - NAPTR + - SRV + pools: + description: + - The pools used for load balancing. + required: false + type: list + elements: dict + suboptions: + pool: + description: + - Provide the name of the pool to link with + required: true + type: str + ratio: + description: + - Provide the weight of the pool + default: 1 + required: false + type: int + ttl: + description: + - The Time To Live (TTL) value for the DTC LBDN. A 32-bit unsigned + integer that represents the duration, in seconds, for which the + record is valid (cached). Zero indicates that the record should + not be cached. + type: int + extattrs: + description: + - Allows for the configuration of Extensible Attributes on the + instance of the object. This argument accepts a set of key / value + pairs for configuration. + type: dict + comment: + description: + - Configures a text string comment to be associated with the instance + of this object. The provided text string will be configured on the + object instance. + type: str + state: + description: + - Configures the intended state of the instance of the object on + the NIOS server. When this value is set to C(present), the object + is configured on the device and when this value is set to C(absent) + the value is removed (if necessary) from the device. + default: present + choices: + - present + - absent + type: str +''' + +EXAMPLES = ''' +- name: Configure a DTC LBDN + infoblox.nios_modules.nios_dtc_lbdn: + name: web.ansible.com + lb_method: ROUND_ROBIN + pools: + - pool: web_pool + state: present + provider: + host: "{{ inventory_hostname_short }}" + username: admin + password: admin + connection: local + +- name: Add a comment to a DTC LBDN + infoblox.nios_modules.nios_dtc_lbdn: + name: web.ansible.com + lb_method: ROUND_ROBIN + comment: this is a test comment + state: present + provider: + host: "{{ inventory_hostname_short }}" + username: admin + password: admin + connection: local + +- name: Remove a DTC LBDN from the system + infoblox.nios_modules.nios_dtc_lbdn: + name: web.ansible.com + lb_method: ROUND_ROBIN + state: absent + provider: + host: "{{ inventory_hostname_short }}" + username: admin + password: admin + connection: local +''' + +RETURN = ''' # ''' + +from ..module_utils.api import NIOS_DTC_LBDN +from ..module_utils.api import WapiModule +from ..module_utils.api import normalize_ib_spec +from ansible.module_utils.six import iteritems +from ansible.module_utils.basic import AnsibleModule + + +def main(): + ''' Main entry point for module execution + ''' + + def auth_zones_transform(module): + zone_list = list() + if module.params['auth_zones']: + for zone in module.params['auth_zones']: + zone_obj = wapi.get_object('zone_auth', + {'fqdn': zone}) + if zone_obj is not None: + zone_list.append(zone_obj[0]['_ref']) + else: + module.fail_json( + msg='auth_zone %s cannot be found.' % zone) + # epdb.serve() + return zone_list + + def pools_transform(module): + pool_list = list() + if module.params['pools']: + for pool in module.params['pools']: + pool_obj = wapi.get_object('dtc:pool', + {'name': pool['pool']}) + if 'ratio' not in pool: + pool['ratio'] = 1 + if pool_obj is not None: + pool_list.append({'pool': pool_obj[0]['_ref'], + 'ratio': pool['ratio']}) + else: + module.fail_json(msg='pool %s cannot be found.' % pool) + return pool_list + + auth_zones_spec = dict() + + pools_spec = dict( + pool=dict(required=True), + ratio=dict(type='int', default=1) + ) + + ib_spec = dict( + name=dict(required=True, ib_req=True), + lb_method=dict(required=True, choices=['GLOBAL_AVAILABILITY', + 'RATIO', 'ROUND_ROBIN', 'TOPOLOGY']), + + auth_zones=dict(type='list', elements='str', options=auth_zones_spec, + transform=auth_zones_transform), + patterns=dict(type='list', elements='str'), + types=dict(type='list', elements='str', choices=['A', 'AAAA', 'CNAME', 'NAPTR', + 'SRV']), + pools=dict(type='list', elements='dict', options=pools_spec, + transform=pools_transform), + ttl=dict(type='int'), + + extattrs=dict(type='dict'), + comment=dict(), + ) + + argument_spec = dict( + provider=dict(required=True), + state=dict(default='present', choices=['present', 'absent']) + ) + + argument_spec.update(normalize_ib_spec(ib_spec)) + argument_spec.update(WapiModule.provider_spec) + + module = AnsibleModule(argument_spec=argument_spec, + supports_check_mode=True) + + wapi = WapiModule(module) + result = wapi.run(NIOS_DTC_LBDN, ib_spec) + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/nios_dtc_pool.py b/plugins/modules/nios_dtc_pool.py new file mode 100644 index 00000000..2611fe1b --- /dev/null +++ b/plugins/modules/nios_dtc_pool.py @@ -0,0 +1,235 @@ +#!/usr/bin/python +# Copyright (c) 2018-2019 Red Hat, Inc. +# Copyright (c) 2020 Infoblox, Inc. +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: nios_dtc_pool +author: "Mauricio Teixeira (@badnetmask)" +version_added: "1.1.0" +short_description: Configure Infoblox NIOS DTC Pool +description: + - Adds and/or removes instances of DTC Pool objects from + Infoblox NIOS servers. This module manages NIOS C(dtc:pool) objects + using the Infoblox WAPI interface over REST. A DTC pool is a collection + of IDNS resources (virtual servers). +requirements: + - infoblox-client +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). +options: + name: + description: + - Specifies the DTC Pool display name + required: true + type: str + lb_preferred_method: + description: + - Configures the preferred load balancing method. + - Use this to select a method type from the pool. + choices: + - ALL_AVAILABLE + - DYNAMIC_RATIO + - GLOBAL_AVAILABILITY + - RATIO + - ROUND_ROBIN + - TOPOLOGY + required: true + type: str + servers: + description: + - Configure the DTC Servers related to the pool + required: false + type: list + elements: dict + suboptions: + server: + description: + - Provide the name of the DTC Server + required: true + type: str + ratio: + description: + - Provide the weight of the server + default: 1 + required: false + type: int + monitors: + description: + - Specifies the health monitors related to pool. + - The format of this parameter is required due to an API + limitation. + - This option only works if you set the C(wapi_version) + variable on your C(provider) variable to a number higher + than "2.6". + required: false + type: list + elements: dict + suboptions: + name: + description: + - Provide the name of the health monitor. + required: true + type: str + type: + description: + - Provide the type of health monitor. + choices: + - http + - icmp + - tcp + - pdp + - sip + - snmp + required: true + type: str + extattrs: + description: + - Allows for the configuration of Extensible Attributes on the + instance of the object. This argument accepts a set of key / value + pairs for configuration. + type: dict + comment: + description: + - Configures a text string comment to be associated with the instance + of this object. The provided text string will be configured on the + object instance. + type: str + state: + description: + - Configures the intended state of the instance of the object on + the NIOS server. When this value is set to C(present), the object + is configured on the device and when this value is set to C(absent) + the value is removed (if necessary) from the device. + default: present + choices: + - present + - absent + type: str +''' + +EXAMPLES = ''' +- name: Configure a DTC Pool + infoblox.nios_modules.nios_dtc_pool: + name: web_pool + lb_preferred_method: ROUND_ROBIN + servers: + - server: a.ansible.com + - server: b.ansible.com + state: present + provider: + host: "{{ inventory_hostname_short }}" + username: admin + password: admin + connection: local + +- name: Add a comment to a DTC Pool + infoblox.nios_modules.nios_dtc_pool: + name: web_pool + lb_preferred_method: ROUND_ROBIN + comment: this is a test comment + state: present + provider: + host: "{{ inventory_hostname_short }}" + username: admin + password: admin + connection: local + +- name: Remove a DTC Pool from the system + infoblox.nios_modules.nios_dtc_pool: + name: web_pool + lb_preferred_method: ROUND_ROBIN + state: absent + provider: + host: "{{ inventory_hostname_short }}" + username: admin + password: admin + connection: local +''' + +RETURN = ''' # ''' + +from ..module_utils.api import NIOS_DTC_POOL +from ..module_utils.api import WapiModule +from ..module_utils.api import normalize_ib_spec +from ansible.module_utils.six import iteritems +from ansible.module_utils.basic import AnsibleModule + + +def main(): + ''' Main entry point for module execution + ''' + + def servers_transform(module): + server_list = list() + if module.params['servers']: + for server in module.params['servers']: + server_obj = wapi.get_object('dtc:server', + {'name': server['server']}) + if server_obj is not None: + server_list.append({'server': server_obj[0]['_ref'], + 'ratio': server['ratio']}) + return server_list + + def monitors_transform(module): + monitor_list = list() + if module.params['monitors']: + for monitor in module.params['monitors']: + monitor_obj = wapi.get_object('dtc:monitor:' + monitor['type'], + {'name': monitor['name']}) + if monitor_obj is not None: + monitor_list.append(monitor_obj[0]['_ref']) + return monitor_list + + servers_spec = dict( + server=dict(required=True), + ratio=dict(type='int', default=1) + ) + + monitors_spec = dict( + name=dict(required=True), + type=dict(required=True, choices=['http', 'icmp', 'tcp', 'pdp', 'sip', 'snmp']) + ) + + ib_spec = dict( + name=dict(required=True, ib_req=True), + lb_preferred_method=dict(required=True, choices=['ALL_AVAILABLE', + 'DYNAMIC_RATIO', + 'GLOBAL_AVAILABILITY', + 'RATIO', + 'ROUND_ROBIN', + 'TOPOLOGY']), + + servers=dict(type='list', elements='dict', options=servers_spec, + transform=servers_transform), + monitors=dict(type='list', elements='dict', options=monitors_spec, + transform=monitors_transform), + + extattrs=dict(type='dict'), + comment=dict(), + ) + + argument_spec = dict( + provider=dict(required=True), + state=dict(default='present', choices=['present', 'absent']) + ) + + argument_spec.update(normalize_ib_spec(ib_spec)) + argument_spec.update(WapiModule.provider_spec) + + module = AnsibleModule(argument_spec=argument_spec, + supports_check_mode=True) + + wapi = WapiModule(module) + result = wapi.run(NIOS_DTC_POOL, ib_spec) + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/nios_dtc_server.py b/plugins/modules/nios_dtc_server.py new file mode 100644 index 00000000..d2810a80 --- /dev/null +++ b/plugins/modules/nios_dtc_server.py @@ -0,0 +1,144 @@ +#!/usr/bin/python +# Copyright (c) 2018-2019 Red Hat, Inc. +# Copyright (c) 2020 Infoblox, Inc. +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: nios_dtc_server +author: "Mauricio Teixeira (@badnetmask)" +short_description: Configure Infoblox NIOS DTC Server +version_added: "1.1.0" +description: + - Adds and/or removes instances of DTC Server objects from + Infoblox NIOS servers. This module manages NIOS C(dtc:server) objects + using the Infoblox WAPI interface over REST. +requirements: + - infoblox-client +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). +options: + name: + description: + - Specifies the DTC Server display name + required: true + type: str + host: + description: + - Configures the IP address (A response) or FQDN (CNAME response) + of the server + required: true + type: str + disable: + description: + - Determines whether the DTC Server is disabled or not. + When this is set to False, the fixed address is enabled. + required: false + type: bool + default: False + extattrs: + description: + - Allows for the configuration of Extensible Attributes on the + instance of the object. This argument accepts a set of key / value + pairs for configuration. + type: dict + comment: + description: + - Configures a text string comment to be associated with the instance + of this object. The provided text string will be configured on the + object instance. + type: str + state: + description: + - Configures the intended state of the instance of the object on + the NIOS server. When this value is set to C(present), the object + is configured on the device and when this value is set to C(absent) + the value is removed (if necessary) from the device. + default: present + choices: + - present + - absent + type: str +''' + +EXAMPLES = ''' +- name: Configure a DTC Server + infoblox.nios_modules.nios_dtc_server: + name: a.example.com + host: 192.168.10.1 + state: present + provider: + host: "{{ inventory_hostname_short }}" + username: admin + password: admin + connection: local + +- name: Add a comment to a DTC server + infoblox.nios_modules.nios_dtc_server: + name: a.example.com + host: 192.168.10.1 + comment: this is a test comment + state: present + provider: + host: "{{ inventory_hostname_short }}" + username: admin + password: admin + connection: local + +- name: Remove a DTC Server from the system + infoblox.nios_modules.nios_dtc_server: + name: a.example.com + host: 192.168.10.1 + state: absent + provider: + host: "{{ inventory_hostname_short }}" + username: admin + password: admin + connection: local +''' + +RETURN = ''' # ''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems +from ..module_utils.api import WapiModule +from ..module_utils.api import NIOS_DTC_SERVER +from ..module_utils.api import normalize_ib_spec + + +def main(): + ''' Main entry point for module execution + ''' + + ib_spec = dict( + name=dict(required=True, ib_req=True), + host=dict(required=True, ib_req=True), + + disable=dict(type='bool', default=False), + extattrs=dict(type='dict'), + comment=dict(), + ) + + argument_spec = dict( + provider=dict(required=True), + state=dict(default='present', choices=['present', 'absent']) + ) + + argument_spec.update(normalize_ib_spec(ib_spec)) + argument_spec.update(WapiModule.provider_spec) + + module = AnsibleModule(argument_spec=argument_spec, + supports_check_mode=True) + + wapi = WapiModule(module) + result = wapi.run(NIOS_DTC_SERVER, ib_spec) + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_fixed_address.py b/plugins/modules/nios_fixed_address.py similarity index 76% rename from ansible_collection/infoblox/nios_modules/plugins/modules/nios_fixed_address.py rename to plugins/modules/nios_fixed_address.py index 4b800c5c..c01d762e 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_fixed_address.py +++ b/plugins/modules/nios_fixed_address.py @@ -6,50 +6,60 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'certified'} - - DOCUMENTATION = ''' --- module: nios_fixed_address -version_added: "2.8" author: "Sumit Jaiswal (@sjaiswal)" short_description: Configure Infoblox NIOS DHCP Fixed Address +version_added: "1.0.0" description: - A fixed address is a specific IP address that a DHCP server always assigns when a lease request comes from a particular MAC address of the client. - - Supports both IPV4 and IPV6 internet protocols + - A fix address reservation is a specific IP address that a DHCP + server reserves and never assigns to a client. + - Supports both IPV4 and IPV6 internet protocols. requirements: - infoblox-client -extends_documentation_fragment: nios +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - The "mac" field is mandatory for all CRUD operations relating to + IPv4 Fixed address. + - The "duid" field is mandatory for all CRUD operations relating to + IPv6 Fixed address. + - This module supports C(check_mode). options: name: description: - Specifies the hostname with which fixed DHCP ip-address is stored for respective mac. - required: false + type: str + required: true ipaddr: description: - IPV4/V6 address of the fixed address. + type: str required: true mac: description: - - The MAC address of the interface. - required: true + - The MAC address of the IPv4 interface. For a fix address reservation + specify mac address as 00:00:00:00:00:00 + type: str + duid: + description: + - The DUID address of the IPv6 interface. + type: str network: description: - Specifies the network range in which ipaddr exists. - required: true + type: str aliases: - network network_view: description: - Configures the name of the network view to associate with this configured instance. - required: false + type: str default: default options: description: @@ -57,16 +67,21 @@ the configured network instance. This argument accepts a list of values (see suboptions). When configuring suboptions at least one of C(name) or C(num) must be specified. + type: list + elements: dict suboptions: name: description: - The name of the DHCP option to configure + type: str num: description: - The number of the DHCP option to configure + type: int value: description: - The value of the DHCP option specified by C(name) + type: str required: true use_option: description: @@ -76,23 +91,27 @@ vendor_class: description: - The name of the space this DHCP option is associated to + type: str default: DHCP extattrs: description: - Allows for the configuration of Extensible Attributes on the instance of the object. This argument accepts a set of key / value pairs for configuration. + type: dict comment: description: - Configures a text string comment to be associated with the instance of this object. The provided text string will be configured on the object instance. + type: str state: description: - Configures the intended state of the instance of the object on the NIOS server. When this value is set to C(present), the object is configured on the device and when this value is set to C(absent) the value is removed (if necessary) from the device. + type: str default: present choices: - present @@ -100,8 +119,8 @@ ''' EXAMPLES = ''' -- name: configure ipv4 dhcp fixed address - nios_fixed_address: +- name: Configure an ipv4 dhcp fixed address + infoblox.nios_modules.nios_fixed_address: name: ipv4_fixed ipaddr: 192.168.10.1 mac: 08:6d:41:e8:fd:e8 @@ -114,8 +133,24 @@ username: admin password: admin connection: local -- name: configure a ipv6 dhcp fixed address - nios_fixed_address: + +- name: Configure an ipv4 dhcp fixed address reservation + infoblox.nios_modules.nios_fixed_address: + name: ipv4_fixed + ipaddr: 192.168.10.1 + mac: 00:00:00:00:00:00 + network: 192.168.10.0/24 + network_view: default + comment: this is a test comment + state: present + provider: + host: "{{ inventory_hostname_short }}" + username: admin + password: admin + connection: local + +- name: Configure an ipv6 dhcp fixed address + infoblox.nios_modules.nios_fixed_address: name: ipv6_fixed ipaddr: fe80::1/10 mac: 08:6d:41:e8:fd:e8 @@ -128,8 +163,9 @@ username: admin password: admin connection: local -- name: set dhcp options for a ipv4 fixed address - nios_fixed_address: + +- name: Set dhcp options for an ipv4 fixed address + infoblox.nios_modules.nios_fixed_address: name: ipv4_fixed ipaddr: 192.168.10.1 mac: 08:6d:41:e8:fd:e8 @@ -145,8 +181,9 @@ username: admin password: admin connection: local -- name: remove a ipv4 dhcp fixed address - nios_fixed_address: + +- name: Remove an ipv4 dhcp fixed address + infoblox.nios_modules.nios_fixed_address: name: ipv4_fixed ipaddr: 192.168.10.1 mac: 08:6d:41:e8:fd:e8 @@ -166,8 +203,10 @@ from ansible.module_utils.six import iteritems from ..module_utils.api import NIOS_IPV4_FIXED_ADDRESS, NIOS_IPV6_FIXED_ADDRESS from ..module_utils.api import WapiModule +from ..module_utils.api import normalize_ib_spec from ..module_utils.network import validate_ip_address, validate_ip_v6_address + def options(module): ''' Transforms the module argument into a valid WAPI struct This function will transform the options argument into a structure that @@ -213,10 +252,20 @@ def validate_ip_addr_type(ip, arg_spec, module): if validate_ip_address(check_ip[0]) and 'ipaddr' in arg_spec: arg_spec['ipv4addr'] = arg_spec.pop('ipaddr') module.params['ipv4addr'] = module.params.pop('ipaddr') + del arg_spec['duid'] + del module.params['duid'] + if module.params["mac"] is None: + raise ValueError("the 'mac' address of the object must be specified") + module.params['mac'] = module.params['mac'].lower() return NIOS_IPV4_FIXED_ADDRESS, arg_spec, module elif validate_ip_v6_address(check_ip[0]) and 'ipaddr' in arg_spec: arg_spec['ipv6addr'] = arg_spec.pop('ipaddr') module.params['ipv6addr'] = module.params.pop('ipaddr') + del arg_spec['mac'] + del module.params['mac'] + if module.params["duid"] is None: + raise ValueError("the 'duid' of the object must be specified") + module.params['duid'] = module.params['duid'].lower() return NIOS_IPV6_FIXED_ADDRESS, arg_spec, module @@ -236,15 +285,16 @@ def main(): ib_spec = dict( name=dict(required=True), - ipaddr=dict(required=True, aliases=['ipaddr'], ib_req=True), - mac=dict(required=True, aliases=['mac'], ib_req=True), - network=dict(required=True, aliases=['network'], ib_req=True), - network_view=dict(default='default', aliases=['network_view']), + ipaddr=dict(required=True, ib_req=True, type='str'), + mac=dict(ib_req=True, type='str'), + duid=dict(ib_req=True, type='str'), + network=dict(), + network_view=dict(default='default'), options=dict(type='list', elements='dict', options=option_spec, transform=options), extattrs=dict(type='dict'), - comment=dict() + comment=dict(type='str') ) argument_spec = dict( @@ -252,7 +302,7 @@ def main(): state=dict(default='present', choices=['present', 'absent']) ) - argument_spec.update(ib_spec) + argument_spec.update(normalize_ib_spec(ib_spec)) argument_spec.update(WapiModule.provider_spec) module = AnsibleModule(argument_spec=argument_spec, diff --git a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_host_record.py b/plugins/modules/nios_host_record.py similarity index 68% rename from ansible_collection/infoblox/nios_modules/plugins/modules/nios_host_record.py rename to plugins/modules/nios_host_record.py index 0dd2edcd..9c3af314 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_host_record.py +++ b/plugins/modules/nios_host_record.py @@ -6,17 +6,12 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'certified'} - - DOCUMENTATION = ''' --- module: nios_host_record -version_added: "2.5" author: "Peter Sprygada (@privateip)" short_description: Configure Infoblox NIOS host records +version_added: "1.0.0" description: - Adds and/or removes instances of host record objects from Infoblox NIOS servers. This module manages NIOS C(record:host) objects @@ -24,29 +19,30 @@ - Updates instances of host record object from Infoblox NIOS servers. requirements: - infoblox-client -extends_documentation_fragment: nios +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). options: name: description: - Specifies the fully qualified hostname to add or remove from the system. User can also update the hostname as it is possible to pass a dict containing I(new_name), I(old_name). See examples. + type: str required: true view: description: - Sets the DNS view to associate this host record with. The DNS - view must already be configured on the system - required: true + view must already be configured on the system. + type: str default: default aliases: - dns_view configure_for_dns: - version_added: "2.7" description: - Sets the DNS to particular parent. If user needs to bypass DNS user can make the value to false. type: bool - required: false default: true aliases: - dns @@ -59,7 +55,9 @@ ipv4addrs: description: - Configures the IPv4 addresses for this host record. This argument - accepts a list of values (see suboptions) + accepts a list of values (see suboptions). + type: list + elements: dict aliases: - ipv4 suboptions: @@ -67,14 +65,18 @@ description: - Configures the IPv4 address for the host record. Users can dynamically allocate ipv4 address to host record by passing dictionary containing, - I(nios_next_ip) and I(CIDR network range). See example + I(nios_next_ip) and I(CIDR network range). If user wants to add or + remove the ipv4 address from existing record, I(add/remove) + params need to be used. See examples. + type: str required: true aliases: - address configure_for_dhcp: description: - Configure the host_record over DHCP instead of DNS, if user - changes it to true, user need to mention MAC address to configure + changes it to true, user need to mention MAC address to configure. + type: bool required: false aliases: - dhcp @@ -82,54 +84,90 @@ description: - Configures the hardware MAC address for the host record. If user makes DHCP to true, user need to mention MAC address. + type: str required: false aliases: - mac + add: + version_added: "1.0.0" + description: + - If user wants to add the ipv4 address to an existing host record. + Note that with I(add) user will have to keep the I(state) as I(present), + as new IP address is allocated to existing host record. See examples. + type: bool + required: false + aliases: + - add + remove: + version_added: "1.0.0" + description: + - If user wants to remove the ipv4 address from an existing host record. + Note that with I(remove) user will have to change the I(state) to I(absent), + as IP address is de-allocated from an existing host record. See examples. + type: bool + required: false + aliases: + - remove ipv6addrs: description: - Configures the IPv6 addresses for the host record. This argument - accepts a list of values (see options) + accepts a list of values (see options). + type: list + elements: dict aliases: - ipv6 suboptions: ipv6addr: description: - - Configures the IPv6 address for the host record + - Configures the IPv6 address for the host record. + type: str required: true aliases: - address configure_for_dhcp: description: - Configure the host_record over DHCP instead of DNS, if user - changes it to true, user need to mention MAC address to configure + changes it to true, user need to mention MAC address to configure. + type: bool + required: false + mac: + description: + - Configures the hardware MAC address for the host record. If user makes + DHCP to true, user need to mention MAC address. + type: str required: false aliases: - - dhcp + - mac aliases: - version_added: "2.6" description: - Configures an optional list of additional aliases to add to the host record. These are equivalent to CNAMEs but held within a host record. Must be in list format. + type: list + elements: str ttl: description: - - Configures the TTL to be associated with this host record + - Configures the TTL to be associated with this host record. + type: int extattrs: description: - Allows for the configuration of Extensible Attributes on the instance of the object. This argument accepts a set of key / value pairs for configuration. + type: dict comment: description: - Configures a text string comment to be associated with the instance of this object. The provided text string will be configured on the object instance. + type: str state: description: - Configures the intended state of the instance of the object on the NIOS server. When this value is set to C(present), the object is configured on the device and when this value is set to C(absent) the value is removed (if necessary) from the device. + type: str default: present choices: - present @@ -137,35 +175,23 @@ ''' EXAMPLES = ''' -- name: configure an ipv4 host record - nios_host_record: - name: host.ansible.com - ipv4: - - address: 192.168.10.1 - aliases: - - cname.ansible.com - state: present - ddns_protected: True - provider: - host: "{{ inventory_hostname_short }}" - username: admin - password: admin - connection: local -- name: configure an ipv4 host record - nios_host_record: +- name: Configure an ipv4 host record + infoblox.nios_modules.nios_host_record: name: host.ansible.com ipv4: - address: 192.168.10.1 aliases: - cname.ansible.com state: present + ddns_protected: True provider: host: "{{ inventory_hostname_short }}" username: admin password: admin connection: local -- name: add a comment to an existing host record - nios_host_record: + +- name: Add a comment to an existing host record + infoblox.nios_modules.nios_host_record: name: host.ansible.com ipv4: - address: 192.168.10.1 @@ -176,8 +202,9 @@ username: admin password: admin connection: local -- name: remove a host record from the system - nios_host_record: + +- name: Remove a host record from the system + infoblox.nios_modules.nios_host_record: name: host.ansible.com state: absent provider: @@ -185,8 +212,9 @@ username: admin password: admin connection: local -- name: update an ipv4 host record - nios_host_record: + +- name: Update an ipv4 host record + infoblox.nios_modules.nios_host_record: name: {new_name: host-new.ansible.com, old_name: host.ansible.com} ipv4: - address: 192.168.10.1 @@ -196,8 +224,9 @@ username: admin password: admin connection: local -- name: create an ipv4 host record bypassing DNS - nios_host_record: + +- name: Create an ipv4 host record bypassing DNS + infoblox.nios_modules.nios_host_record: name: new_host ipv4: - address: 192.168.10.1 @@ -208,8 +237,9 @@ username: admin password: admin connection: local -- name: create an ipv4 host record over DHCP - nios_host_record: + +- name: Create an ipv4 host record over DHCP + infoblox.nios_modules.nios_host_record: name: host.ansible.com ipv4: - address: 192.168.10.1 @@ -221,8 +251,9 @@ username: admin password: admin connection: local -- name: dynamically add host record to next available ip - nios_host_record: + +- name: Dynamically add host record to next available ip + infoblox.nios_modules.nios_host_record: name: host.ansible.com ipv4: - address: {nios_next_ip: 192.168.10.0/24} @@ -233,6 +264,32 @@ username: admin password: admin connection: local + +- name: Add ip to host record + infoblox.nios_modules.nios_host_record: + name: host.ansible.com + ipv4: + - address: 192.168.10.2 + add: true + state: present + provider: + host: "{{ inventory_hostname_short }}" + username: admin + password: admin + connection: local + +- name: Remove ip from host record + infoblox.nios_modules.nios_host_record: + name: host.ansible.com + ipv4: + - address: 192.168.10.1 + remove: true + state: absent + provider: + host: "{{ inventory_hostname_short }}" + username: admin + password: admin + connection: local ''' RETURN = ''' # ''' @@ -241,6 +298,8 @@ from ansible.module_utils.six import iteritems from ..module_utils.api import WapiModule from ..module_utils.api import NIOS_HOST_RECORD +from ..module_utils.api import normalize_ib_spec + def ipaddr(module, key, filtered_keys=None): ''' Transforms the input value into a struct supported by WAPI @@ -272,15 +331,17 @@ def main(): ''' Main entry point for module execution ''' ipv4addr_spec = dict( - ipv4addr=dict(required=True, aliases=['address'], ib_req=True), - configure_for_dhcp=dict(type='bool', required=False, aliases=['dhcp'], ib_req=True), - mac=dict(required=False, aliases=['mac'], ib_req=True) + ipv4addr=dict(required=True, aliases=['address']), + configure_for_dhcp=dict(type='bool', required=False, aliases=['dhcp']), + mac=dict(required=False), + add=dict(type='bool', required=False), + remove=dict(type='bool', required=False) ) ipv6addr_spec = dict( - ipv6addr=dict(required=True, aliases=['address'], ib_req=True), - configure_for_dhcp=dict(type='bool', required=False, aliases=['configure_for_dhcp'], ib_req=True), - mac=dict(required=False, aliases=['mac'], ib_req=True) + ipv6addr=dict(required=True, aliases=['address']), + configure_for_dhcp=dict(type='bool', required=False), + mac=dict(required=False) ) ib_spec = dict( @@ -290,8 +351,8 @@ def main(): ipv4addrs=dict(type='list', aliases=['ipv4'], elements='dict', options=ipv4addr_spec, transform=ipv4addrs), ipv6addrs=dict(type='list', aliases=['ipv6'], elements='dict', options=ipv6addr_spec, transform=ipv6addrs), configure_for_dns=dict(type='bool', default=True, required=False, aliases=['dns'], ib_req=True), - aliases=dict(type='list'), - ddns_protected=dict(type='bool', default=False, required=False), + aliases=dict(type='list', elements='str'), + ddns_protected=dict(type='bool', default=False, required=False), ttl=dict(type='int'), @@ -304,7 +365,7 @@ def main(): state=dict(default='present', choices=['present', 'absent']) ) - argument_spec.update(ib_spec) + argument_spec.update(normalize_ib_spec(ib_spec)) argument_spec.update(WapiModule.provider_spec) module = AnsibleModule(argument_spec=argument_spec, diff --git a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_member.py b/plugins/modules/nios_member.py similarity index 85% rename from ansible_collection/infoblox/nios_modules/plugins/modules/nios_member.py rename to plugins/modules/nios_member.py index f2a5980b..38a6899b 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_member.py +++ b/plugins/modules/nios_member.py @@ -6,21 +6,19 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'certified'} - DOCUMENTATION = ''' --- module: nios_member -version_added: "2.8" author: "Krishna Vasudevan (@krisvasudevan)" short_description: Configure Infoblox NIOS members +version_added: "1.0.0" description: - Adds and/or removes Infoblox NIOS servers. This module manages NIOS C(member) objects using the Infoblox WAPI interface over REST. requirements: - infoblox-client -extends_documentation_fragment: nios +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). options: host_name: description: @@ -29,58 +27,75 @@ required: true aliases: - name + type: str vip_setting: description: - Configures the network settings for the grid member. - required: true suboptions: address: description: - The IPv4 Address of the Grid Member + type: str subnet_mask: description: - The subnet mask for the Grid Member + type: str gateway: description: - The default gateway for the Grid Member + type: str + type: list + elements: dict ipv6_setting: description: - Configures the IPv6 settings for the grid member. - required: true suboptions: virtual_ip: description: - The IPv6 Address of the Grid Member + type: str cidr_prefix: description: - The IPv6 CIDR prefix for the Grid Member + type: int gateway: description: - The gateway address for the Grid Member + type: str + type: list + elements: dict config_addr_type: description: - - Address configuration type (IPV4/IPV6/BOTH) + - Address configuration type (IPV4/IPV6/BOTH). default: IPV4 + type: str comment: description: - A descriptive comment of the Grid member. + type: str extattrs: description: - Extensible attributes associated with the object. + type: dict enable_ha: description: - If set to True, the member has two physical nodes (HA pair). + default: False type: bool router_id: description: - Virtual router identifier. Provide this ID if "ha_enabled" is set to "true". This is a unique VRID number (from 1 to 255) for the local subnet. + type: int lan2_enabled: description: - When set to "true", the LAN2 port is enabled as an independent port or as a port for failover purposes. + default: False type: bool lan2_port_setting: description: - Settings for the Grid member LAN2 port if 'lan2_enabled' is set to "true". + type: list + elements: dict suboptions: enabled: description: @@ -93,32 +108,45 @@ address: description: - The IPv4 Address of LAN2 + type: str subnet_mask: description: - The subnet mask of LAN2 + type: str gateway: description: - The default gateway of LAN2 + type: str + type: list + elements: dict v6_network_setting: description: - If the 'enable' field is set to True, this defines IPv6 network settings for LAN2. + type: list + elements: dict suboptions: virtual_ip: description: - The IPv6 Address of LAN2 + type: str cidr_prefix: description: - The IPv6 CIDR prefix of LAN2 + type: int gateway: description: - The gateway address of LAN2 + type: str platform: description: - Configures the Hardware Platform. default: INFOBLOX + type: str node_info: description: - Configures the node information list with detailed status report on the operations of the Grid Member. + type: list + elements: dict suboptions: lan2_physical_setting: description: @@ -131,19 +159,28 @@ duplex: description: - The port duplex; if speed is 1000, duplex must be FULL. + type: str speed: description: - The port speed; if speed is 1000, duplex is FULL. + type: str + type: list + elements: dict lan_ha_port_setting: description: - LAN/HA port settings for the node. + type: list + elements: dict suboptions: ha_ip_address: description: - HA IP address. + type: str ha_port_setting: description: - Physical port settings for the HA interface. + type: list + elements: dict suboptions: auto_port_setting_enabled: description: @@ -152,12 +189,16 @@ duplex: description: - The port duplex; if speed is 1000, duplex must be FULL. + type: str speed: description: - The port speed; if speed is 1000, duplex is FULL. + type: str lan_port_setting: description: - Physical port settings for the LAN interface. + type: list + elements: dict suboptions: auto_port_setting_enabled: description: @@ -166,44 +207,60 @@ duplex: description: - The port duplex; if speed is 1000, duplex must be FULL. + type: str speed: description: - The port speed; if speed is 1000, duplex is FULL. + type: str mgmt_ipv6addr: description: - Public IPv6 address for the LAN1 interface. + type: str mgmt_lan: description: - Public IPv4 address for the LAN1 interface. + type: str mgmt_network_setting: description: - Network settings for the MGMT port of the node. + type: list + elements: dict suboptions: address: description: - The IPv4 Address of MGMT + type: str subnet_mask: description: - The subnet mask of MGMT + type: str gateway: description: - The default gateway of MGMT + type: str v6_mgmt_network_setting: description: - The network settings for the IPv6 MGMT port of the node. + type: list + elements: dict suboptions: virtual_ip: description: - The IPv6 Address of MGMT + type: str cidr_prefix: description: - The IPv6 CIDR prefix of MGMT + type: int gateway: description: - The gateway address of MGMT + type: str mgmt_port_setting: description: - Settings for the member MGMT port. + type: list + elements: dict suboptions: enabled: description: @@ -221,40 +278,50 @@ description: - The name of the upgrade group to which this Grid member belongs. default: Default + type: str use_syslog_proxy_setting: description: - - Use flag for external_syslog_server_enable , syslog_servers, syslog_proxy_setting, syslog_size + - Use flag for external_syslog_server_enable , syslog_servers, syslog_proxy_setting, syslog_size. type: bool external_syslog_server_enable: description: - - Determines if external syslog servers should be enabled + - Determines if external syslog servers should be enabled. type: bool syslog_servers: description: - The list of external syslog servers. + type: list + elements: dict suboptions: address: description: - The server address. + type: str category_list: description: - The list of all syslog logging categories. + type: list + elements: str connection_type: description: - The connection type for communicating with this server.(STCP/TCP?UDP) default: UDP + type: str local_interface: description: - The local interface through which the appliance sends syslog messages to the syslog server.(ANY/LAN/MGMT) default: ANY + type: str message_node_id: description: - Identify the node in the syslog message. (HOSTNAME/IP_HOSTNAME/LAN/MGMT) default: LAN + type: str message_source: description: - The source of syslog messages to be sent to the external syslog server. default: ANY + type: str only_category_list: description: - The list of selected syslog logging categories. The appliance forwards syslog messages that belong to the selected categories. @@ -263,27 +330,37 @@ description: - The port this server listens on. default: 514 + type: int severity: description: - The severity filter. The appliance sends log messages of the specified severity and above to the external syslog server. default: DEBUG + type: str pre_provisioning: description: - Pre-provisioning information. + type: list + elements: dict suboptions: hardware_info: description: - An array of structures that describe the hardware being pre-provisioned. + type: list + elements: dict suboptions: hwmodel: description: - Hardware model + type: str hwtype: description: - Hardware type. + type: str licenses: description: - An array of license types. + type: list + elements: str create_token: description: - Flag for initiating a create token request for pre-provisioned members. @@ -299,11 +376,12 @@ choices: - present - absent + type: str ''' EXAMPLES = ''' -- name: add a member to the grid with IPv4 address - nios_member: +- name: Add a member to the grid with IPv4 address + infoblox.nios_modules.nios_member: host_name: member01.localdomain vip_setting: - address: 192.168.1.100 @@ -318,8 +396,9 @@ username: admin password: admin connection: local -- name: add a HA member to the grid - nios_member: + +- name: Add a HA member to the grid + infoblox.nios_modules.nios_member: host_name: memberha.localdomain vip_setting: - address: 192.168.1.100 @@ -343,8 +422,9 @@ username: admin password: admin connection: local -- name: update the member with pre-provisioning details specified - nios_member: + +- name: Update the member with pre-provisioning details specified + infoblox.nios_modules.nios_member: name: member01.localdomain pre_provisioning: - hardware_info: @@ -362,8 +442,9 @@ username: admin password: admin connection: local -- name: remove the member - nios_member: + +- name: Remove the member + infoblox.nios_modules.nios_member: name: member01.localdomain state: absent provider: @@ -379,6 +460,8 @@ from ansible.module_utils.six import iteritems from ..module_utils.api import WapiModule from ..module_utils.api import NIOS_MEMBER +from ..module_utils.api import normalize_ib_spec + def main(): ''' Main entry point for module execution @@ -430,7 +513,7 @@ def main(): syslog_spec = dict( address=dict(), - category_list=dict(type='list'), + category_list=dict(type='list', elements='str'), connection_type=dict(default='UDP'), local_interface=dict(default='ANY'), message_node_id=dict(default='LAN'), @@ -447,7 +530,7 @@ def main(): pre_prov_spec = dict( hardware_info=dict(type='list', elements='dict', options=hw_spec), - licenses=dict(type='list'), + licenses=dict(type='list', elements='str'), ) ib_spec = dict( @@ -477,7 +560,7 @@ def main(): state=dict(default='present', choices=['present', 'absent']) ) - argument_spec.update(ib_spec) + argument_spec.update(normalize_ib_spec(ib_spec)) argument_spec.update(WapiModule.provider_spec) module = AnsibleModule(argument_spec=argument_spec, diff --git a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_mx_record.py b/plugins/modules/nios_mx_record.py similarity index 82% rename from ansible_collection/infoblox/nios_modules/plugins/modules/nios_mx_record.py rename to plugins/modules/nios_mx_record.py index 7596a67e..1ff3bc8a 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_mx_record.py +++ b/plugins/modules/nios_mx_record.py @@ -6,67 +6,71 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'certified'} - - DOCUMENTATION = ''' --- module: nios_mx_record -version_added: "2.7" author: "Blair Rampling (@brampling)" short_description: Configure Infoblox NIOS MX records +version_added: "1.0.0" description: - Adds and/or removes instances of MX record objects from Infoblox NIOS servers. This module manages NIOS C(record:mx) objects using the Infoblox WAPI interface over REST. requirements: - infoblox-client -extends_documentation_fragment: nios +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). options: name: description: - Specifies the fully qualified hostname to add or remove from - the system + the system. + type: str required: true view: description: - Sets the DNS view to associate this a record with. The DNS - view must already be configured on the system - required: true + view must already be configured on the system. + type: str default: default aliases: - dns_view mail_exchanger: description: - Configures the mail exchanger FQDN for this MX record. + type: str required: true aliases: - mx preference: description: - Configures the preference (0-65535) for this MX record. + type: int required: true ttl: description: - - Configures the TTL to be associated with this host record + - Configures the TTL to be associated with this host record. + type: int extattrs: description: - Allows for the configuration of Extensible Attributes on the instance of the object. This argument accepts a set of key / value pairs for configuration. + type: dict comment: description: - Configures a text string comment to be associated with the instance of this object. The provided text string will be configured on the object instance. + type: str state: description: - Configures the intended state of the instance of the object on the NIOS server. When this value is set to C(present), the object is configured on the device and when this value is set to C(absent) the value is removed (if necessary) from the device. + type: str default: present choices: - present @@ -74,8 +78,8 @@ ''' EXAMPLES = ''' -- name: configure an MX record - nios_mx_record: +- name: Configure an MX record + infoblox.nios_modules.nios_mx_record: name: ansible.com mx: mailhost.ansible.com preference: 0 @@ -86,8 +90,8 @@ password: admin connection: local -- name: add a comment to an existing MX record - nios_mx_record: +- name: Add a comment to an existing MX record + infoblox.nios_modules.nios_mx_record: name: ansible.com mx: mailhost.ansible.com preference: 0 @@ -99,8 +103,8 @@ password: admin connection: local -- name: remove an MX record from the system - nios_mx_record: +- name: Remove an MX record from the system + infoblox.nios_modules.nios_mx_record: name: ansible.com mx: mailhost.ansible.com preference: 0 @@ -118,6 +122,7 @@ from ansible.module_utils.six import iteritems from ..module_utils.api import WapiModule from ..module_utils.api import NIOS_MX_RECORD +from ..module_utils.api import normalize_ib_spec def main(): @@ -128,8 +133,8 @@ def main(): name=dict(required=True, ib_req=True), view=dict(default='default', aliases=['dns_view'], ib_req=True), - mail_exchanger=dict(aliases=['mx'], ib_req=True), - preference=dict(type='int', ib_req=True), + mail_exchanger=dict(required=True, aliases=['mx'], ib_req=True), + preference=dict(required=True, type='int', ib_req=True), ttl=dict(type='int'), @@ -142,7 +147,7 @@ def main(): state=dict(default='present', choices=['present', 'absent']) ) - argument_spec.update(ib_spec) + argument_spec.update(normalize_ib_spec(ib_spec)) argument_spec.update(WapiModule.provider_spec) module = AnsibleModule(argument_spec=argument_spec, diff --git a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_naptr_record.py b/plugins/modules/nios_naptr_record.py similarity index 87% rename from ansible_collection/infoblox/nios_modules/plugins/modules/nios_naptr_record.py rename to plugins/modules/nios_naptr_record.py index 876d7615..aa59921b 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_naptr_record.py +++ b/plugins/modules/nios_naptr_record.py @@ -6,35 +6,33 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'certified'} - - DOCUMENTATION = ''' --- module: nios_naptr_record -version_added: "2.7" author: "Blair Rampling (@brampling)" short_description: Configure Infoblox NIOS NAPTR records +version_added: "1.0.0" description: - Adds and/or removes instances of NAPTR record objects from Infoblox NIOS servers. This module manages NIOS C(record:naptr) objects using the Infoblox WAPI interface over REST. requirements: - infoblox_client -extends_documentation_fragment: nios +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). options: name: description: - Specifies the fully qualified hostname to add or remove from - the system + the system. + type: str required: true view: description: - Sets the DNS view to associate this a record with. The DNS - view must already be configured on the system - required: true + view must already be configured on the system. + type: str default: default aliases: - dns_view @@ -43,31 +41,31 @@ - Configures the order (0-65535) for this NAPTR record. This parameter specifies the order in which the NAPTR rules are applied when multiple rules are present. - required: true + type: int preference: description: - Configures the preference (0-65535) for this NAPTR record. The preference field determines the order NAPTR records are processed when multiple records with the same order parameter are present. - required: true + type: int replacement: description: - Configures the replacement field for this NAPTR record. For nonterminal NAPTR records, this field specifies the next domain name to look up. - required: true + type: str services: description: - Configures the services field (128 characters maximum) for this NAPTR record. The services field contains protocol and service identifiers, such as "http+E2U" or "SIPS+D2T". - required: false + type: str flags: description: - Configures the flags field for this NAPTR record. These control the interpretation of the fields for an NAPTR record object. Supported values for the flags field are "U", "S", "P" and "A". - required: false + type: str regexp: description: - Configures the regexp field for this NAPTR record. This is the @@ -75,26 +73,30 @@ should be a POSIX compliant regular expression, including the substitution rule and flags. Refer to RFC 2915 for the field syntax details. - required: false + type: str ttl: description: - - Configures the TTL to be associated with this NAPTR record + - Configures the TTL to be associated with this NAPTR record. + type: int extattrs: description: - Allows for the configuration of Extensible Attributes on the instance of the object. This argument accepts a set of key / value pairs for configuration. + type: dict comment: description: - Configures a text string comment to be associated with the instance of this object. The provided text string will be configured on the object instance. + type: str state: description: - Configures the intended state of the instance of the object on the NIOS server. When this value is set to C(present), the object is configured on the device and when this value is set to C(absent) the value is removed (if necessary) from the device. + type: str default: present choices: - present @@ -102,8 +104,8 @@ ''' EXAMPLES = ''' -- name: configure a NAPTR record - nios_naptr_record: +- name: Configure an NAPTR record + infoblox.nios_modules.nios_naptr_record: name: '*.subscriber-100.ansiblezone.com' order: 1000 preference: 10 @@ -115,8 +117,8 @@ password: admin connection: local -- name: add a comment to an existing NAPTR record - nios_naptr_record: +- name: Add a comment to an existing NAPTR record + infoblox.nios_modules.nios_naptr_record: name: '*.subscriber-100.ansiblezone.com' order: 1000 preference: 10 @@ -129,8 +131,8 @@ password: admin connection: local -- name: remove a NAPTR record from the system - nios_naptr_record: +- name: Remove an NAPTR record from the system + infoblox.nios_modules.nios_naptr_record: name: '*.subscriber-100.ansiblezone.com' order: 1000 preference: 10 @@ -148,7 +150,7 @@ from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.six import iteritems from ..module_utils.api import WapiModule - +from ..module_utils.api import normalize_ib_spec def main(): @@ -177,7 +179,7 @@ def main(): state=dict(default='present', choices=['present', 'absent']) ) - argument_spec.update(ib_spec) + argument_spec.update(normalize_ib_spec(ib_spec)) argument_spec.update(WapiModule.provider_spec) module = AnsibleModule(argument_spec=argument_spec, diff --git a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_network.py b/plugins/modules/nios_network.py similarity index 86% rename from ansible_collection/infoblox/nios_modules/plugins/modules/nios_network.py rename to plugins/modules/nios_network.py index c2e74189..e53782dd 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_network.py +++ b/plugins/modules/nios_network.py @@ -6,30 +6,28 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'certified'} - - DOCUMENTATION = ''' --- module: nios_network -version_added: "2.5" author: "Peter Sprygada (@privateip)" short_description: Configure Infoblox NIOS network object +version_added: "1.0.0" description: - Adds and/or removes instances of network objects from Infoblox NIOS servers. This module manages NIOS C(network) objects using the Infoblox WAPI interface over REST. - - Supports both IPV4 and IPV6 internet protocols + - Supports both IPV4 and IPV6 internet protocols. requirements: - infoblox-client -extends_documentation_fragment: nios +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). options: network: description: - Specifies the network to add or remove from the system. The value should use CIDR notation. + type: str required: true aliases: - name @@ -38,7 +36,7 @@ description: - Configures the name of the network view to associate with this configured instance. - required: true + type: str default: default options: description: @@ -46,6 +44,8 @@ the configured network instance. This argument accepts a list of values (see suboptions). When configuring suboptions at least one of C(name) or C(num) must be specified. + type: list + elements: dict suboptions: name: description: @@ -53,12 +53,15 @@ C(router), C(router-templates), C(domain-name-servers), C(domain-name), C(broadcast-address), C(broadcast-address-offset), C(dhcp-lease-time), and C(dhcp6.name-servers). + type: str num: description: - The number of the DHCP option to configure + type: int value: description: - The value of the DHCP option specified by C(name) + type: str required: true use_option: description: @@ -68,29 +71,37 @@ vendor_class: description: - The name of the space this DHCP option is associated to + type: str default: DHCP + template: + description: + - If set on creation, the network is created according to the values + specified in the selected template. + type: str extattrs: description: - Allows for the configuration of Extensible Attributes on the instance of the object. This argument accepts a set of key / value pairs for configuration. + type: dict comment: description: - Configures a text string comment to be associated with the instance of this object. The provided text string will be configured on the object instance. + type: str container: description: - If set to true it'll create the network container to be added or removed from the system. type: bool - version_added: '2.8' state: description: - Configures the intended state of the instance of the object on the NIOS server. When this value is set to C(present), the object is configured on the device and when this value is set to C(absent) the value is removed (if necessary) from the device. + type: str default: present choices: - present @@ -98,8 +109,8 @@ ''' EXAMPLES = ''' -- name: configure a network ipv4 - nios_network: +- name: Configure a network ipv4 + infoblox.nios_modules.nios_network: network: 192.168.10.0/24 comment: this is a test comment state: present @@ -108,8 +119,9 @@ username: admin password: admin connection: local -- name: configure a network ipv6 - nios_network: + +- name: Configure a network ipv6 + infoblox.nios_modules.nios_network: network: fe80::/64 comment: this is a test comment state: present @@ -118,8 +130,9 @@ username: admin password: admin connection: local -- name: set dhcp options for a network ipv4 - nios_network: + +- name: Set dhcp options for a network ipv4 + infoblox.nios_modules.nios_network: network: 192.168.10.0/24 comment: this is a test comment options: @@ -131,8 +144,9 @@ username: admin password: admin connection: local -- name: remove a network ipv4 - nios_network: + +- name: Remove a network ipv4 + infoblox.nios_modules.nios_network: network: 192.168.10.0/24 state: absent provider: @@ -140,8 +154,9 @@ username: admin password: admin connection: local -- name: configure a ipv4 network container - nios_network: + +- name: Configure an ipv4 network container + infoblox.nios_modules.nios_network: network: 192.168.10.0/24 container: true comment: test network container @@ -151,8 +166,9 @@ username: admin password: admin connection: local -- name: configure a ipv6 network container - nios_network: + +- name: Configure an ipv6 network container + infoblox.nios_modules.nios_network: network: fe80::/64 container: true comment: test network container @@ -162,8 +178,9 @@ username: admin password: admin connection: local -- name: remove a ipv4 network container - nios_network: + +- name: Remove an ipv4 network container + infoblox.nios_modules.nios_network: networkr: 192.168.10.0/24 container: true comment: test network container @@ -182,8 +199,10 @@ from ..module_utils.api import WapiModule from ..module_utils.api import NIOS_IPV4_NETWORK, NIOS_IPV6_NETWORK from ..module_utils.api import NIOS_IPV4_NETWORK_CONTAINER, NIOS_IPV6_NETWORK_CONTAINER +from ..module_utils.api import normalize_ib_spec from ..module_utils.network import validate_ip_address, validate_ip_v6_address + def options(module): ''' Transforms the module argument into a valid WAPI struct This function will transform the options argument into a structure that @@ -238,10 +257,10 @@ def check_vendor_specific_dhcp_option(module, ib_spec): ''' for key, value in iteritems(ib_spec): if isinstance(module.params[key], list): - temp_dict = module.params[key][0] - if 'num' in temp_dict: - if temp_dict['num'] in (43, 124, 125): - del module.params[key][0]['use_option'] + for temp_dict in module.params[key]: + if 'num' in temp_dict: + if temp_dict['num'] in (43, 124, 125, 67, 60): + del temp_dict['use_option'] return ib_spec @@ -265,6 +284,7 @@ def main(): options=dict(type='list', elements='dict', options=option_spec, transform=options), + template=dict(type='str'), extattrs=dict(type='dict'), comment=dict(), container=dict(type='bool', ib_req=True) @@ -275,7 +295,7 @@ def main(): state=dict(default='present', choices=['present', 'absent']) ) - argument_spec.update(ib_spec) + argument_spec.update(normalize_ib_spec(ib_spec)) argument_spec.update(WapiModule.provider_spec) module = AnsibleModule(argument_spec=argument_spec, diff --git a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_network_view.py b/plugins/modules/nios_network_view.py similarity index 84% rename from ansible_collection/infoblox/nios_modules/plugins/modules/nios_network_view.py rename to plugins/modules/nios_network_view.py index 0101031c..3ebcb1f6 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_network_view.py +++ b/plugins/modules/nios_network_view.py @@ -6,17 +6,12 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'certified'} - - DOCUMENTATION = ''' --- module: nios_network_view -version_added: "2.5" author: "Peter Sprygada (@privateip)" short_description: Configure Infoblox NIOS network views +version_added: "1.0.0" description: - Adds and/or removes instances of network view objects from Infoblox NIOS servers. This module manages NIOS C(networkview) objects @@ -24,13 +19,16 @@ - Updates instances of network view object from Infoblox NIOS servers. requirements: - infoblox-client -extends_documentation_fragment: nios +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). options: name: description: - Specifies the fully qualified hostname to add or remove from the system. User can also update the hostname as it is possible to pass a dict containing I(new_name), I(old_name). See examples. + type: str required: true aliases: - network_view @@ -39,17 +37,20 @@ - Allows for the configuration of Extensible Attributes on the instance of the object. This argument accepts a set of key / value pairs for configuration. + type: dict comment: description: - Configures a text string comment to be associated with the instance of this object. The provided text string will be configured on the object instance. + type: str state: description: - Configures the intended state of the instance of the object on the NIOS server. When this value is set to C(present), the object is configured on the device and when this value is set to C(absent) the value is removed (if necessary) from the device. + type: str default: present choices: - present @@ -57,8 +58,8 @@ ''' EXAMPLES = ''' -- name: configure a new network view - nios_network_view: +- name: Configure a new network view + infoblox.nios_modules.nios_network_view: name: ansible state: present provider: @@ -66,8 +67,9 @@ username: admin password: admin connection: local -- name: update the comment for network view - nios_network_view: + +- name: Update the comment for network view + infoblox.nios_modules.nios_network_view: name: ansible comment: this is an example comment state: present @@ -76,8 +78,9 @@ username: admin password: admin connection: local -- name: remove the network view - nios_network_view: + +- name: Remove the network view + infoblox.nios_modules.nios_network_view: name: ansible state: absent provider: @@ -85,8 +88,9 @@ username: admin password: admin connection: local -- name: update a existing network view - nios_network_view: + +- name: Update an existing network view + infoblox.nios_modules.nios_network_view: name: {new_name: ansible-new, old_name: ansible} state: present provider: @@ -101,6 +105,7 @@ from ansible.module_utils.basic import AnsibleModule from ..module_utils.api import WapiModule from ..module_utils.api import NIOS_NETWORK_VIEW +from ..module_utils.api import normalize_ib_spec def main(): @@ -117,7 +122,7 @@ def main(): state=dict(default='present', choices=['present', 'absent']) ) - argument_spec.update(ib_spec) + argument_spec.update(normalize_ib_spec(ib_spec)) argument_spec.update(WapiModule.provider_spec) module = AnsibleModule(argument_spec=argument_spec, diff --git a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_nsgroup.py b/plugins/modules/nios_nsgroup.py similarity index 77% rename from ansible_collection/infoblox/nios_modules/plugins/modules/nios_nsgroup.py rename to plugins/modules/nios_nsgroup.py index 85560229..948fe238 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_nsgroup.py +++ b/plugins/modules/nios_nsgroup.py @@ -5,43 +5,43 @@ # Copyright (c) 2020 Infoblox, Inc. # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - from __future__ import absolute_import, division, print_function - __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'certified'} - DOCUMENTATION = ''' --- module: nios_nsgroup short_description: Configure InfoBlox DNS Nameserver Groups -extends_documentation_fragment: nios +version_added: "1.0.0" +extends_documentation_fragment: infoblox.nios_modules.nios author: - Erich Birngruber (@ebirn) - Sumit Jaiswal (@sjaiswal) -version_added: "2.8" description: - Adds and/or removes nameserver groups form Infoblox NIOS servers. This module manages NIOS C(nsgroup) objects using the Infoblox. WAPI interface over REST. requirements: - infoblox_client +notes: + - This module supports C(check_mode). options: name: description: - Specifies the name of the NIOS nameserver group to be managed. required: true + type: str grid_primary: description: - This host is to be used as primary server in this nameserver group. It must be a grid member. This option is required when setting I(use_external_primaries) to C(false). + type: list + elements: dict suboptions: name: description: - Provide the name of the grid member to identify the host. required: true + type: str enable_preferred_primaries: description: - This flag represents whether the preferred_primaries field values of this member are used (see Infoblox WAPI docs). @@ -62,15 +62,54 @@ - Configure the external nameserver as stealth server (without NS record) in the zones. type: bool default: false + preferred_primaries: + description: + - Provide a list of elements like in I(external_primaries) to set the precedence of preferred primary nameservers. + type: list + elements: dict + suboptions: + address: + description: + - Configures the IP address of the external nameserver + required: true + type: str + name: + description: + - Set a label for the external nameserver + required: true + type: str + stealth: + description: + - Configure the external nameserver as stealth server (without NS record) in the zones. + type: bool + default: false + tsig_key_name: + description: + - Sets a label for the I(tsig_key) value + required: true + type: str + tsig_key_alg: + description: + - Provides the algorithm used for the I(tsig_key) in use. + choices: ['HMAC-MD5', 'HMAC-SHA256'] + default: 'HMAC-MD5' + type: str + tsig_key: + description: + - Set a DNS TSIG key for the nameserver to secure zone transfers (AFXRs). + type: str grid_secondaries: description: - Configures the list of grid member hosts that act as secondary nameservers. This option is required when setting I(use_external_primaries) to C(true). + type: list + elements: dict suboptions: name: description: - Provide the name of the grid member to identify the host. required: true + type: str enable_preferred_primaries: description: - This flag represents whether the preferred_primaries field values of this member are used (see Infoblox WAPI docs). @@ -94,32 +133,67 @@ preferred_primaries: description: - Provide a list of elements like in I(external_primaries) to set the precedence of preferred primary nameservers. + type: list + elements: dict + suboptions: + address: + description: + - Configures the IP address of the external nameserver + required: true + type: str + name: + description: + - Set a label for the external nameserver + required: true + type: str + stealth: + description: + - Configure the external nameserver as stealth server (without NS record) in the zones. + type: bool + default: false + tsig_key_name: + description: + - Sets a label for the I(tsig_key) value + required: true + type: str + tsig_key_alg: + description: + - Provides the algorithm used for the I(tsig_key) in use. + choices: ['HMAC-MD5', 'HMAC-SHA256'] + default: 'HMAC-MD5' + type: str + tsig_key: + description: + - Set a DNS TSIG key for the nameserver to secure zone transfers (AFXRs). + type: str is_grid_default: description: - If set to C(True) this nsgroup will become the default nameserver group for new zones. type: bool - required: false default: false use_external_primary: description: - This flag controls whether the group is using an external primary nameserver. Note that modification of this field requires passing values for I(grid_secondaries) and I(external_primaries). type: bool - required: false default: false external_primaries: description: - Configures a list of external nameservers (non-members of the grid). This option is required when setting I(use_external_primaries) to C(true). + type: list + elements: dict suboptions: address: description: - Configures the IP address of the external nameserver required: true + type: str name: description: - Set a label for the external nameserver required: true + type: str stealth: description: - Configure the external nameserver as stealth server (without NS record) in the zones. @@ -128,27 +202,34 @@ tsig_key_name: description: - Sets a label for the I(tsig_key) value + required: true + type: str tsig_key_alg: description: - Provides the algorithm used for the I(tsig_key) in use. choices: ['HMAC-MD5', 'HMAC-SHA256'] default: 'HMAC-MD5' + type: str tsig_key: description: - Set a DNS TSIG key for the nameserver to secure zone transfers (AFXRs). - required: false + type: str external_secondaries: description: - Allows to provide a list of external secondary nameservers, that are not members of the grid. + type: list + elements: dict suboptions: address: description: - Configures the IP address of the external nameserver required: true + type: str name: description: - Set a label for the external nameserver required: true + type: str stealth: description: - Configure the external nameserver as stealth server (without NS record) in the zones. @@ -157,26 +238,30 @@ tsig_key_name: description: - Sets a label for the I(tsig_key) value + required: true + type: str tsig_key_alg: description: - Provides the algorithm used for the I(tsig_key) in use. choices: ['HMAC-MD5', 'HMAC-SHA256'] default: 'HMAC-MD5' + type: str tsig_key: description: - Set a DNS TSIG key for the nameserver to secure zone transfers (AFXRs). + type: str extattrs: description: - Allows for the configuration of Extensible Attributes on the instance of the object. This argument accepts a set of key / value pairs for configuration. - required: false + type: str comment: description: - Configures a text string comment to be associated with the instance of this object. The provided text string will be configured on the object instance. - required: false + type: str state: description: - Configures the intended state of the instance of the object on @@ -185,11 +270,12 @@ the value is removed (if necessary) from the device. choices: [present, absent] default: present + type: str ''' EXAMPLES = ''' -- name: create simple infoblox nameserver group - nios_nsgroup: +- name: Create simple infoblox nameserver group + infoblox.nios_modules.nios_nsgroup: name: my-simple-group comment: "this is a simple nameserver group" grid_primary: @@ -201,8 +287,8 @@ password: admin connection: local -- name: create infoblox nameserver group with external primaries - nios_nsgroup: +- name: Create infoblox nameserver group with external primaries + infoblox.nios_modules.nios_nsgroup: name: my-example-group use_external_primary: true comment: "this is my example nameserver group" @@ -218,8 +304,8 @@ password: admin connection: local -- name: delete infoblox nameserver group - nios_nsgroup: +- name: Delete infoblox nameserver group + infoblox.nios_modules.nios_nsgroup: name: my-simple-group comment: "this is a simple nameserver group" grid_primary: @@ -237,6 +323,7 @@ from ansible.module_utils.basic import AnsibleModule from ..module_utils.api import WapiModule from ..module_utils.api import NIOS_NSGROUP +from ..module_utils.api import normalize_ib_spec # from infoblox documentation @@ -305,20 +392,20 @@ def grid_secondaries_preferred_primaries_transform(module): return module.params['grid_secondaries'] extserver_spec = dict( - address=dict(required=True, ib_req=True), - name=dict(required=True, ib_req=True), + address=dict(required=True), + name=dict(required=True), stealth=dict(type='bool', default=False), - tsig_key=dict(), + tsig_key=dict(no_log=True), tsig_key_alg=dict(choices=['HMAC-MD5', 'HMAC-SHA256'], default='HMAC-MD5'), tsig_key_name=dict(required=True) ) memberserver_spec = dict( - name=dict(required=True, ib_req=True), + name=dict(required=True), enable_preferred_primaries=dict(type='bool', default=False), grid_replicate=dict(type='bool', default=False), lead=dict(type='bool', default=False), - preferred_primaries=dict(type='list', elements='dict', options=extserver_spec, default=[]), + preferred_primaries=dict(type='list', elements='dict', options=extserver_spec, default=None), stealth=dict(type='bool', default=False), ) @@ -337,7 +424,7 @@ def grid_secondaries_preferred_primaries_transform(module): comment=dict(), ) - argument_spec.update(ib_spec) + argument_spec.update(normalize_ib_spec(ib_spec)) argument_spec.update(WapiModule.provider_spec) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) diff --git a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_ptr_record.py b/plugins/modules/nios_ptr_record.py similarity index 86% rename from ansible_collection/infoblox/nios_modules/plugins/modules/nios_ptr_record.py rename to plugins/modules/nios_ptr_record.py index 884e07b4..d649badc 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_ptr_record.py +++ b/plugins/modules/nios_ptr_record.py @@ -4,71 +4,73 @@ # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function - __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'certified'} - DOCUMENTATION = ''' --- module: nios_ptr_record -version_added: "2.7" author: "Trebuchet Clement (@clementtrebuchet)" short_description: Configure Infoblox NIOS PTR records +version_added: "1.0.0" description: - Adds and/or removes instances of PTR record objects from Infoblox NIOS servers. This module manages NIOS C(record:ptr) objects using the Infoblox WAPI interface over REST. requirements: - infoblox_client -extends_documentation_fragment: nios +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). options: name: description: - The name of the DNS PTR record in FQDN format to add or remove from the system. The field is required only for an PTR object in Forward Mapping Zone. - required: false + type: str view: description: - Sets the DNS view to associate this a record with. The DNS - view must already be configured on the system - required: false + view must already be configured on the system. + type: str + default: default aliases: - dns_view ipv4addr: description: - The IPv4 Address of the record. Mutually exclusive with the ipv6addr. - required: true + type: str aliases: - ipv4 ipv6addr: description: - The IPv6 Address of the record. Mutually exclusive with the ipv4addr. - required: true aliases: - ipv6 + type: str ptrdname: description: - The domain name of the DNS PTR record in FQDN format. required: true + type: str ttl: description: - Time To Live (TTL) value for the record. A 32-bit unsigned integer that represents the duration, in seconds, that the record is valid (cached). Zero indicates that the record should not be cached. + type: int extattrs: description: - Allows for the configuration of Extensible Attributes on the instance of the object. This argument accepts a set of key / value pairs for configuration. + type: dict comment: description: - Configures a text string comment to be associated with the instance of this object. The provided text string will be configured on the object instance. Maximum 256 characters. + type: str state: description: - Configures the intended state of the instance of the object on @@ -79,11 +81,12 @@ choices: - present - absent + type: str ''' EXAMPLES = ''' - name: Create a PTR Record - nios_ptr_record: + infoblox.nios_modules.nios_ptr_record: ipv4: 192.168.10.1 ptrdname: host.ansible.com state: present @@ -94,7 +97,7 @@ connection: local - name: Delete a PTR Record - nios_ptr_record: + infoblox.nios_modules.nios_ptr_record: ipv4: 192.168.10.1 ptrdname: host.ansible.com state: absent @@ -110,16 +113,17 @@ from ansible.module_utils.basic import AnsibleModule from ..module_utils.api import WapiModule from ..module_utils.api import NIOS_PTR_RECORD +from ..module_utils.api import normalize_ib_spec def main(): # Module entry point ib_spec = dict( name=dict(required=False), - view=dict(aliases=['dns_view']), + view=dict(default='default', aliases=['dns_view'], ib_req=True), ipv4addr=dict(aliases=['ipv4'], ib_req=True), ipv6addr=dict(aliases=['ipv6'], ib_req=True), - ptrdname=dict(ib_req=True), + ptrdname=dict(required=True, ib_req=True), ttl=dict(type='int'), @@ -132,7 +136,7 @@ def main(): state=dict(default='present', choices=['present', 'absent']) ) - argument_spec.update(ib_spec) + argument_spec.update(normalize_ib_spec(ib_spec)) argument_spec.update(WapiModule.provider_spec) mutually_exclusive = [('ipv4addr', 'ipv6addr')] diff --git a/plugins/modules/nios_restartservices.py b/plugins/modules/nios_restartservices.py new file mode 100644 index 00000000..b8f0bc49 --- /dev/null +++ b/plugins/modules/nios_restartservices.py @@ -0,0 +1,144 @@ +#!/usr/bin/python +# Copyright (c) 2018-2019 Red Hat, Inc. +# Copyright (c) 2020 Infoblox, Inc. +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: nios_restartservices +author: "Mauricio Teixeira (@badnetmask)" +short_description: Restart grid services. +version_added: "1.1.0" +description: + - Restart grid services. + - When invoked without any options, will restart ALL services on the + default restart group IF NEEDED. +requirements: + - infoblox-client +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). +options: + groups: + description: + - The list of the Service Restart Groups to restart. + required: false + type: list + elements: str + members: + description: + - The list of the Grid Members to restart. + required: false + type: list + elements: str + mode: + description: + - The restart method in case of grid restart. + required: false + type: str + choices: + - GROUPED + - SEQUENTIAL + - SIMULTANEOUS + restart_option: + description: + - Controls whether services are restarted unconditionally or when needed + required: false + type: str + default: RESTART_IF_NEEDED + choices: + - RESTART_IF_NEEDED + - FORCE_RESTART + services: + description: + - The list of services the restart applicable to. + required: false + type: list + elements: str + default: ALL + choices: + - ALL + - DNS + - DHCP + - DHCPV4 + - DHCPV6 +''' + +EXAMPLES = ''' +- name: Restart all grid services if needed. + infoblox.nios_modules.nios_restartservices: + provider: + host: "{{ inventory_hostname_short }}" + username: admin + password: admin + connection: local + +- name: Restart DNS service if needed. + infoblox.nios_modules.nios_restartservices: + services: + - DNS + provider: + host: "{{ inventory_hostname_short }}" + username: admin + password: admin + connection: local +''' + +RETURN = ''' # ''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems +from ..module_utils.api import WapiModule +from ..module_utils.api import normalize_ib_spec + + +def main(): + ''' Main entry point for module execution + ''' + + ib_spec = dict( + groups=dict(type='list', elements='str'), + members=dict(type='list', elements='str'), + mode=dict(type='str', choices=['GROUPED', 'SEQUENTIAL', + 'SIMULTANEOUS']), + restart_option=dict(type='str', default='RESTART_IF_NEEDED', + choices=['RESTART_IF_NEEDED', 'FORCE_RESTART']), + services=dict(type='list', elements='str', default=['ALL'], + choices=['ALL', 'DNS', 'DHCP', 'DHCPV4', 'DHCPV6']) + ) + + argument_spec = dict( + provider=dict(required=True) + ) + + argument_spec.update(normalize_ib_spec(ib_spec)) + argument_spec.update(WapiModule.provider_spec) + + module = AnsibleModule(argument_spec=argument_spec, + supports_check_mode=True) + + wapi = WapiModule(module) + + # restart is a grid function, so we need to properly format + # the arguments before sending the command + restart_params = module.params + del restart_params['provider'] + if restart_params['groups'] is None: + del restart_params['groups'] + if restart_params['members'] is None: + del restart_params['members'] + if restart_params['mode'] is None: + del restart_params['mode'] + grid_obj = wapi.get_object('grid') + if grid_obj is None: + module.fail_json(msg='Failed to get NIOS grid information.') + result = wapi.call_func('restartservices', grid_obj[0]['_ref'], restart_params) + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_srv_record.py b/plugins/modules/nios_srv_record.py similarity index 85% rename from ansible_collection/infoblox/nios_modules/plugins/modules/nios_srv_record.py rename to plugins/modules/nios_srv_record.py index d222b54d..9ac94577 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_srv_record.py +++ b/plugins/modules/nios_srv_record.py @@ -6,67 +6,68 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'certified'} - - DOCUMENTATION = ''' --- module: nios_srv_record -version_added: "2.7" author: "Blair Rampling (@brampling)" short_description: Configure Infoblox NIOS SRV records +version_added: "1.0.0" description: - Adds and/or removes instances of SRV record objects from Infoblox NIOS servers. This module manages NIOS C(record:srv) objects using the Infoblox WAPI interface over REST. requirements: - infoblox-client -extends_documentation_fragment: nios +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). options: name: description: - Specifies the fully qualified hostname to add or remove from - the system + the system. required: true + type: str view: description: - Sets the DNS view to associate this a record with. The DNS - view must already be configured on the system - required: true + view must already be configured on the system. default: default aliases: - dns_view + type: str port: description: - Configures the port (0-65535) of this SRV record. - required: true + type: int priority: description: - Configures the priority (0-65535) for this SRV record. - required: true + type: int target: description: - Configures the target FQDN for this SRV record. - required: true + type: str weight: description: - Configures the weight (0-65535) for this SRV record. - required: true + type: int ttl: description: - - Configures the TTL to be associated with this host record + - Configures the TTL to be associated with this host record. + type: int extattrs: description: - Allows for the configuration of Extensible Attributes on the instance of the object. This argument accepts a set of key / value pairs for configuration. + type: dict comment: description: - Configures a text string comment to be associated with the instance of this object. The provided text string will be configured on the object instance. + type: str state: description: - Configures the intended state of the instance of the object on @@ -77,11 +78,12 @@ choices: - present - absent + type: str ''' EXAMPLES = ''' -- name: configure an SRV record - nios_srv_record: +- name: Configure an SRV record + infoblox.nios_modules.nios_srv_record: name: _sip._tcp.service.ansible.com port: 5080 priority: 10 @@ -94,8 +96,8 @@ password: admin connection: local -- name: add a comment to an existing SRV record - nios_srv_record: +- name: Add a comment to an existing SRV record + infoblox.nios_modules.nios_srv_record: name: _sip._tcp.service.ansible.com port: 5080 priority: 10 @@ -109,8 +111,8 @@ password: admin connection: local -- name: remove an SRV record from the system - nios_srv_record: +- name: Remove an SRV record from the system + infoblox.nios_modules.nios_srv_record: name: _sip._tcp.service.ansible.com port: 5080 priority: 10 @@ -130,8 +132,7 @@ from ansible.module_utils.six import iteritems from ..module_utils.api import WapiModule from ..module_utils.api import NIOS_SRV_RECORD - - +from ..module_utils.api import normalize_ib_spec def main(): @@ -158,7 +159,7 @@ def main(): state=dict(default='present', choices=['present', 'absent']) ) - argument_spec.update(ib_spec) + argument_spec.update(normalize_ib_spec(ib_spec)) argument_spec.update(WapiModule.provider_spec) module = AnsibleModule(argument_spec=argument_spec, diff --git a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_txt_record.py b/plugins/modules/nios_txt_record.py similarity index 84% rename from ansible_collection/infoblox/nios_modules/plugins/modules/nios_txt_record.py rename to plugins/modules/nios_txt_record.py index c2e2a778..51e4504c 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_txt_record.py +++ b/plugins/modules/nios_txt_record.py @@ -6,57 +6,60 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'certified'} - - DOCUMENTATION = ''' --- module: nios_txt_record -version_added: "2.7" author: "Corey Wanless (@coreywan)" short_description: Configure Infoblox NIOS txt records +version_added: "1.0.0" description: - Adds and/or removes instances of txt record objects from Infoblox NIOS servers. This module manages NIOS C(record:txt) objects using the Infoblox WAPI interface over REST. requirements: - infoblox_client -extends_documentation_fragment: nios +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). options: name: description: - Specifies the fully qualified hostname to add or remove from - the system + the system. required: true + type: str view: description: - Sets the DNS view to associate this tst record with. The DNS - view must already be configured on the system - required: true + view must already be configured on the system. default: default aliases: - dns_view + type: str text: description: - Text associated with the record. It can contain up to 255 bytes per substring, up to a total of 512 bytes. To enter leading, trailing, or embedded spaces in the text, add quotes around the text to preserve the spaces. + required: true + type: str ttl: description: - - Configures the TTL to be associated with this tst record + - Configures the TTL to be associated with this txt record. + type: int extattrs: description: - Allows for the configuration of Extensible Attributes on the instance of the object. This argument accepts a set of key / value pairs for configuration. + type: dict comment: description: - Configures a text string comment to be associated with the instance of this object. The provided text string will be configured on the object instance. + type: str state: description: - Configures the intended state of the instance of the object on @@ -67,11 +70,12 @@ choices: - present - absent + type: str ''' EXAMPLES = ''' - name: Ensure a text Record Exists - nios_txt_record: + infoblox.nios_modules.nios_txt_record: name: fqdn.txt.record.com text: mytext state: present @@ -82,7 +86,7 @@ password: admin - name: Ensure a text Record does not exist - nios_txt_record: + infoblox.nios_modules.nios_txt_record: name: fqdn.txt.record.com text: mytext state: absent @@ -98,6 +102,7 @@ from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.six import iteritems from ..module_utils.api import WapiModule +from ..module_utils.api import normalize_ib_spec def main(): @@ -107,7 +112,7 @@ def main(): ib_spec = dict( name=dict(required=True, ib_req=True), view=dict(default='default', aliases=['dns_view'], ib_req=True), - text=dict(type='str', ib_req=True), + text=dict(required=True, type='str', ib_req=True), ttl=dict(type='int'), extattrs=dict(type='dict'), comment=dict(), @@ -118,7 +123,7 @@ def main(): state=dict(default='present', choices=['present', 'absent']) ) - argument_spec.update(ib_spec) + argument_spec.update(normalize_ib_spec(ib_spec)) argument_spec.update(WapiModule.provider_spec) module = AnsibleModule(argument_spec=argument_spec, diff --git a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_zone.py b/plugins/modules/nios_zone.py similarity index 82% rename from ansible_collection/infoblox/nios_modules/plugins/modules/nios_zone.py rename to plugins/modules/nios_zone.py index 30f8821d..982c5e21 100644 --- a/ansible_collection/infoblox/nios_modules/plugins/modules/nios_zone.py +++ b/plugins/modules/nios_zone.py @@ -6,24 +6,21 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'certified'} - - DOCUMENTATION = ''' --- module: nios_zone -version_added: "2.5" author: "Peter Sprygada (@privateip)" short_description: Configure Infoblox NIOS DNS zones +version_added: "1.0.0" description: - Adds and/or removes instances of DNS zone objects from Infoblox NIOS servers. This module manages NIOS C(zone_auth) objects using the Infoblox WAPI interface over REST. requirements: - infoblox-client -extends_documentation_fragment: nios +extends_documentation_fragment: infoblox.nios_modules.nios +notes: + - This module supports C(check_mode). options: fqdn: description: @@ -32,15 +29,16 @@ required: true aliases: - name + type: str view: description: - Configures the DNS view name for the configured resource. The specified DNS zone must already exist on the running NIOS instance prior to configuring zones. - required: true default: default aliases: - dns_view + type: str grid_primary: description: - Configures the grid primary servers for this zone. @@ -48,6 +46,10 @@ name: description: - The name of the grid primary server + required: true + type: str + type: list + elements: dict grid_secondaries: description: - Configures the grid secondary servers for this zone. @@ -55,35 +57,40 @@ name: description: - The name of the grid secondary server + required: true + type: str + type: list + elements: dict ns_group: - version_added: "2.6" description: - Configures the name server group for this zone. Name server group is mutually exclusive with grid primary and grid secondaries. + type: str restart_if_needed: - version_added: "2.6" description: - If set to true, causes the NIOS DNS service to restart and load the - new zone configuration + new zone configuration. type: bool zone_format: - version_added: "2.7" description: - Create an authorative Reverse-Mapping Zone which is an area of network space for which one or more name servers-primary and secondary-have the responsibility to respond to address-to-name queries. It supports reverse-mapping zones for both IPv4 and IPv6 addresses. default: FORWARD + type: str extattrs: description: - Allows for the configuration of Extensible Attributes on the instance of the object. This argument accepts a set of key / value pairs for configuration. + type: dict comment: description: - Configures a text string comment to be associated with the instance of this object. The provided text string will be configured on the object instance. + type: str state: description: - Configures the intended state of the instance of the object on @@ -94,11 +101,12 @@ choices: - present - absent + type: str ''' EXAMPLES = ''' -- name: configure a zone on the system using grid primary and secondaries - nios_zone: +- name: Configure a zone on the system using grid primary and secondaries + infoblox.nios_modules.nios_zone: name: ansible.com grid_primary: - name: gridprimary.grid.com @@ -112,8 +120,9 @@ username: admin password: admin connection: local -- name: configure a zone on the system using a name server group - nios_zone: + +- name: Configure a zone on the system using a name server group + infoblox.nios_modules.nios_zone: name: ansible.com ns_group: examplensg restart_if_needed: true @@ -123,8 +132,9 @@ username: admin password: admin connection: local -- name: configure a reverse mapping zone on the system using IPV4 zone format - nios_zone: + +- name: Configure a reverse mapping zone on the system using IPV4 zone format + infoblox.nios_modules.nios_zone: name: 10.10.10.0/24 zone_format: IPV4 state: present @@ -133,8 +143,9 @@ username: admin password: admin connection: local -- name: configure a reverse mapping zone on the system using IPV6 zone format - nios_zone: + +- name: Configure a reverse mapping zone on the system using IPV6 zone format + infoblox.nios_modules.nios_zone: name: 100::1/128 zone_format: IPV6 state: present @@ -143,8 +154,9 @@ username: admin password: admin connection: local -- name: update the comment and ext attributes for an existing zone - nios_zone: + +- name: Update the comment and ext attributes for an existing zone + infoblox.nios_modules.nios_zone: name: ansible.com comment: this is an example comment extattrs: @@ -155,8 +167,9 @@ username: admin password: admin connection: local -- name: remove the dns zone - nios_zone: + +- name: Remove the dns zone + infoblox.nios_modules.nios_zone: name: ansible.com state: absent provider: @@ -164,8 +177,9 @@ username: admin password: admin connection: local -- name: remove the reverse mapping dns zone from the system with IPV4 zone format - nios_zone: + +- name: Remove the reverse mapping dns zone from the system with IPV4 zone format + infoblox.nios_modules.nios_zone: name: 10.10.10.0/24 zone_format: IPV4 state: absent @@ -181,6 +195,7 @@ from ansible.module_utils.basic import AnsibleModule from ..module_utils.api import WapiModule from ..module_utils.api import NIOS_ZONE +from ..module_utils.api import normalize_ib_spec def main(): @@ -192,7 +207,7 @@ def main(): ib_spec = dict( fqdn=dict(required=True, aliases=['name'], ib_req=True, update=False), - zone_format=dict(default='FORWARD', aliases=['zone_format'], ib_req=False), + zone_format=dict(default='FORWARD', ib_req=False), view=dict(default='default', aliases=['dns_view'], ib_req=True), grid_primary=dict(type='list', elements='dict', options=grid_spec), @@ -209,7 +224,7 @@ def main(): state=dict(default='present', choices=['present', 'absent']) ) - argument_spec.update(ib_spec) + argument_spec.update(normalize_ib_spec(ib_spec)) argument_spec.update(WapiModule.provider_spec) module = AnsibleModule(argument_spec=argument_spec, diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..be611454 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +infoblox-client diff --git a/tests/ignore-2.10.txt b/tests/ignore-2.10.txt deleted file mode 100644 index 5fb9d8f2..00000000 --- a/tests/ignore-2.10.txt +++ /dev/null @@ -1,114 +0,0 @@ -plugins/module_utils/net_tools/nios/api.py future-import-boilerplate -plugins/module_utils/net_tools/nios/api.py metaclass-boilerplate -plugins/modules/net_tools/nios/nios_a_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_a_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_a_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_a_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_a_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_a_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_aaaa_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_aaaa_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_aaaa_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_aaaa_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_aaaa_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_aaaa_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_cname_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_cname_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_cname_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_cname_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_cname_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_cname_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_dns_view.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_dns_view.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_dns_view.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_dns_view.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_dns_view.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_dns_view.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:doc-elements-mismatch -plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:parameter-alias-self -plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:doc-elements-mismatch -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:nonexistent-parameter-documented -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:parameter-alias-self -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:parameter-list-no-elements -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_member.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_member.py validate-modules:doc-elements-mismatch -plugins/modules/net_tools/nios/nios_member.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_member.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_member.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_member.py validate-modules:parameter-list-no-elements -plugins/modules/net_tools/nios/nios_member.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_member.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_mx_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_mx_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_mx_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_mx_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_mx_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_mx_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_naptr_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_naptr_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_naptr_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_naptr_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_naptr_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_naptr_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_network.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_network.py validate-modules:doc-elements-mismatch -plugins/modules/net_tools/nios/nios_network.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_network.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_network.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_network.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_network.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_network_view.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_network_view.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_network_view.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_network_view.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_network_view.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_network_view.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:doc-choices-do-not-match-spec -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:doc-elements-mismatch -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:missing-suboption-docs -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_ptr_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_ptr_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_ptr_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_ptr_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_ptr_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_ptr_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_srv_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_srv_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_srv_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_srv_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_srv_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_srv_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_txt_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_txt_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_txt_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_txt_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_txt_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_txt_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_zone.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_zone.py validate-modules:doc-elements-mismatch -plugins/modules/net_tools/nios/nios_zone.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_zone.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_zone.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_zone.py validate-modules:parameter-alias-self -plugins/modules/net_tools/nios/nios_zone.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_zone.py validate-modules:undocumented-parameter -plugins/doc_fragments/nios.py future-import-boilerplate -plugins/doc_fragments/nios.py metaclass-boilerplate diff --git a/tests/ignore-2.9.txt b/tests/ignore-2.9.txt deleted file mode 100644 index 5fb9d8f2..00000000 --- a/tests/ignore-2.9.txt +++ /dev/null @@ -1,114 +0,0 @@ -plugins/module_utils/net_tools/nios/api.py future-import-boilerplate -plugins/module_utils/net_tools/nios/api.py metaclass-boilerplate -plugins/modules/net_tools/nios/nios_a_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_a_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_a_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_a_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_a_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_a_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_aaaa_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_aaaa_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_aaaa_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_aaaa_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_aaaa_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_aaaa_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_cname_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_cname_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_cname_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_cname_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_cname_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_cname_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_dns_view.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_dns_view.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_dns_view.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_dns_view.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_dns_view.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_dns_view.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:doc-elements-mismatch -plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:parameter-alias-self -plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:doc-elements-mismatch -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:nonexistent-parameter-documented -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:parameter-alias-self -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:parameter-list-no-elements -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_host_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_member.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_member.py validate-modules:doc-elements-mismatch -plugins/modules/net_tools/nios/nios_member.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_member.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_member.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_member.py validate-modules:parameter-list-no-elements -plugins/modules/net_tools/nios/nios_member.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_member.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_mx_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_mx_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_mx_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_mx_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_mx_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_mx_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_naptr_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_naptr_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_naptr_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_naptr_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_naptr_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_naptr_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_network.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_network.py validate-modules:doc-elements-mismatch -plugins/modules/net_tools/nios/nios_network.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_network.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_network.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_network.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_network.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_network_view.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_network_view.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_network_view.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_network_view.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_network_view.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_network_view.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:doc-choices-do-not-match-spec -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:doc-elements-mismatch -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:missing-suboption-docs -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_ptr_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_ptr_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_ptr_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_ptr_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_ptr_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_ptr_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_srv_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_srv_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_srv_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_srv_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_srv_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_srv_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_txt_record.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_txt_record.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_txt_record.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_txt_record.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_txt_record.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_txt_record.py validate-modules:undocumented-parameter -plugins/modules/net_tools/nios/nios_zone.py validate-modules:doc-default-does-not-match-spec -plugins/modules/net_tools/nios/nios_zone.py validate-modules:doc-elements-mismatch -plugins/modules/net_tools/nios/nios_zone.py validate-modules:doc-missing-type -plugins/modules/net_tools/nios/nios_zone.py validate-modules:doc-required-mismatch -plugins/modules/net_tools/nios/nios_zone.py validate-modules:invalid-ansiblemodule-schema -plugins/modules/net_tools/nios/nios_zone.py validate-modules:parameter-alias-self -plugins/modules/net_tools/nios/nios_zone.py validate-modules:parameter-type-not-in-doc -plugins/modules/net_tools/nios/nios_zone.py validate-modules:undocumented-parameter -plugins/doc_fragments/nios.py future-import-boilerplate -plugins/doc_fragments/nios.py metaclass-boilerplate diff --git a/tests/integration/targets/incidental_nios_prepare_tests/aliases b/tests/integration/targets/incidental_nios_prepare_tests/aliases deleted file mode 100644 index 136c05e0..00000000 --- a/tests/integration/targets/incidental_nios_prepare_tests/aliases +++ /dev/null @@ -1 +0,0 @@ -hidden diff --git a/tests/integration/targets/incidental_nios_txt_record/aliases b/tests/integration/targets/incidental_nios_txt_record/aliases deleted file mode 100644 index dfb77b81..00000000 --- a/tests/integration/targets/incidental_nios_txt_record/aliases +++ /dev/null @@ -1,3 +0,0 @@ -shippable/cloud/incidental -cloud/nios -destructive diff --git a/tests/integration/targets/incidental_nios_txt_record/defaults/main.yaml b/tests/integration/targets/incidental_nios_txt_record/defaults/main.yaml deleted file mode 100644 index ebf6ffc9..00000000 --- a/tests/integration/targets/incidental_nios_txt_record/defaults/main.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -testcase: "*" -test_items: [] \ No newline at end of file diff --git a/tests/integration/targets/incidental_nios_txt_record/meta/main.yaml b/tests/integration/targets/incidental_nios_txt_record/meta/main.yaml deleted file mode 100644 index c7c538f4..00000000 --- a/tests/integration/targets/incidental_nios_txt_record/meta/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - incidental_nios_prepare_tests diff --git a/tests/integration/targets/incidental_nios_txt_record/tasks/main.yml b/tests/integration/targets/incidental_nios_txt_record/tasks/main.yml deleted file mode 100644 index e15b4c55..00000000 --- a/tests/integration/targets/incidental_nios_txt_record/tasks/main.yml +++ /dev/null @@ -1 +0,0 @@ -- include: nios_txt_record_idempotence.yml diff --git a/tests/integration/targets/incidental_nios_txt_record/tasks/nios_txt_record_idempotence.yml b/tests/integration/targets/incidental_nios_txt_record/tasks/nios_txt_record_idempotence.yml deleted file mode 100644 index 3b7357af..00000000 --- a/tests/integration/targets/incidental_nios_txt_record/tasks/nios_txt_record_idempotence.yml +++ /dev/null @@ -1,80 +0,0 @@ -- name: cleanup the parent object - nios_zone: - name: ansible.com - state: absent - provider: "{{ nios_provider }}" - -- name: create the parent object - nios_zone: - name: ansible.com - state: present - provider: "{{ nios_provider }}" - -- name: cleanup txt record - nios_txt_record: - name: txt.ansible.com - text: mytext - state: absent - provider: "{{ nios_provider }}" - -- name: create txt record - nios_txt_record: - name: txt.ansible.com - text: mytext - state: present - provider: "{{ nios_provider }}" - register: txt_create1 - -- name: create txt record - nios_txt_record: - name: txt.ansible.com - text: mytext - state: present - provider: "{{ nios_provider }}" - register: txt_create2 - -- assert: - that: - - "txt_create1.changed" - - "not txt_create2.changed" - -- name: add a comment to an existing txt record - nios_txt_record: - name: txt.ansible.com - text: mytext - state: present - comment: mycomment - provider: "{{ nios_provider }}" - register: txt_update1 - -- name: add a comment to an existing txt record - nios_txt_record: - name: txt.ansible.com - text: mytext - state: present - comment: mycomment - provider: "{{ nios_provider }}" - register: txt_update2 - -- name: remove a txt record from the system - nios_txt_record: - name: txt.ansible.com - state: absent - provider: "{{ nios_provider }}" - register: txt_delete1 - -- name: remove a txt record from the system - nios_txt_record: - name: txt.ansible.com - state: absent - provider: "{{ nios_provider }}" - register: txt_delete2 - -- assert: - that: - - "txt_create1.changed" - - "not txt_create2.changed" - - "txt_update1.changed" - - "not txt_update2.changed" - - "txt_delete1.changed" - - "not txt_delete2.changed" diff --git a/tests/integration/nios/nios_a_record/aliases b/tests/integration/targets/nios_a_record/aliases similarity index 100% rename from tests/integration/nios/nios_a_record/aliases rename to tests/integration/targets/nios_a_record/aliases diff --git a/tests/integration/nios/nios_a_record/defaults/main.yaml b/tests/integration/targets/nios_a_record/defaults/main.yaml similarity index 100% rename from tests/integration/nios/nios_a_record/defaults/main.yaml rename to tests/integration/targets/nios_a_record/defaults/main.yaml diff --git a/tests/integration/nios/nios_a_record/meta/main.yaml b/tests/integration/targets/nios_a_record/meta/main.yaml similarity index 100% rename from tests/integration/nios/nios_a_record/meta/main.yaml rename to tests/integration/targets/nios_a_record/meta/main.yaml diff --git a/tests/integration/nios/nios_a_record/tasks/main.yml b/tests/integration/targets/nios_a_record/tasks/main.yml similarity index 100% rename from tests/integration/nios/nios_a_record/tasks/main.yml rename to tests/integration/targets/nios_a_record/tasks/main.yml diff --git a/tests/integration/nios/nios_a_record/tasks/nios_a_record_idempotence.yml b/tests/integration/targets/nios_a_record/tasks/nios_a_record_idempotence.yml similarity index 100% rename from tests/integration/nios/nios_a_record/tasks/nios_a_record_idempotence.yml rename to tests/integration/targets/nios_a_record/tasks/nios_a_record_idempotence.yml diff --git a/tests/integration/nios/nios_aaaa_record/aliases b/tests/integration/targets/nios_aaaa_record/aliases similarity index 100% rename from tests/integration/nios/nios_aaaa_record/aliases rename to tests/integration/targets/nios_aaaa_record/aliases diff --git a/tests/integration/nios/nios_aaaa_record/defaults/main.yaml b/tests/integration/targets/nios_aaaa_record/defaults/main.yaml similarity index 100% rename from tests/integration/nios/nios_aaaa_record/defaults/main.yaml rename to tests/integration/targets/nios_aaaa_record/defaults/main.yaml diff --git a/tests/integration/nios/nios_aaaa_record/meta/main.yaml b/tests/integration/targets/nios_aaaa_record/meta/main.yaml similarity index 100% rename from tests/integration/nios/nios_aaaa_record/meta/main.yaml rename to tests/integration/targets/nios_aaaa_record/meta/main.yaml diff --git a/tests/integration/nios/nios_aaaa_record/tasks/main.yml b/tests/integration/targets/nios_aaaa_record/tasks/main.yml similarity index 100% rename from tests/integration/nios/nios_aaaa_record/tasks/main.yml rename to tests/integration/targets/nios_aaaa_record/tasks/main.yml diff --git a/tests/integration/nios/nios_aaaa_record/tasks/nios_aaaa_record_idempotence.yml b/tests/integration/targets/nios_aaaa_record/tasks/nios_aaaa_record_idempotence.yml similarity index 100% rename from tests/integration/nios/nios_aaaa_record/tasks/nios_aaaa_record_idempotence.yml rename to tests/integration/targets/nios_aaaa_record/tasks/nios_aaaa_record_idempotence.yml diff --git a/tests/integration/nios/nios_cname_record/aliases b/tests/integration/targets/nios_cname_record/aliases similarity index 100% rename from tests/integration/nios/nios_cname_record/aliases rename to tests/integration/targets/nios_cname_record/aliases diff --git a/tests/integration/nios/nios_cname_record/defaults/main.yaml b/tests/integration/targets/nios_cname_record/defaults/main.yaml similarity index 100% rename from tests/integration/nios/nios_cname_record/defaults/main.yaml rename to tests/integration/targets/nios_cname_record/defaults/main.yaml diff --git a/tests/integration/nios/nios_cname_record/meta/main.yaml b/tests/integration/targets/nios_cname_record/meta/main.yaml similarity index 100% rename from tests/integration/nios/nios_cname_record/meta/main.yaml rename to tests/integration/targets/nios_cname_record/meta/main.yaml diff --git a/tests/integration/nios/nios_cname_record/tasks/main.yml b/tests/integration/targets/nios_cname_record/tasks/main.yml similarity index 100% rename from tests/integration/nios/nios_cname_record/tasks/main.yml rename to tests/integration/targets/nios_cname_record/tasks/main.yml diff --git a/tests/integration/nios/nios_cname_record/tasks/nios_cname_record_idempotence.yml b/tests/integration/targets/nios_cname_record/tasks/nios_cname_record_idempotence.yml similarity index 100% rename from tests/integration/nios/nios_cname_record/tasks/nios_cname_record_idempotence.yml rename to tests/integration/targets/nios_cname_record/tasks/nios_cname_record_idempotence.yml diff --git a/tests/integration/nios/nios_dns_view/aliases b/tests/integration/targets/nios_dns_view/aliases similarity index 100% rename from tests/integration/nios/nios_dns_view/aliases rename to tests/integration/targets/nios_dns_view/aliases diff --git a/tests/integration/nios/nios_dns_view/defaults/main.yaml b/tests/integration/targets/nios_dns_view/defaults/main.yaml similarity index 100% rename from tests/integration/nios/nios_dns_view/defaults/main.yaml rename to tests/integration/targets/nios_dns_view/defaults/main.yaml diff --git a/tests/integration/nios/nios_dns_view/meta/main.yaml b/tests/integration/targets/nios_dns_view/meta/main.yaml similarity index 100% rename from tests/integration/nios/nios_dns_view/meta/main.yaml rename to tests/integration/targets/nios_dns_view/meta/main.yaml diff --git a/tests/integration/nios/nios_dns_view/tasks/main.yml b/tests/integration/targets/nios_dns_view/tasks/main.yml similarity index 100% rename from tests/integration/nios/nios_dns_view/tasks/main.yml rename to tests/integration/targets/nios_dns_view/tasks/main.yml diff --git a/tests/integration/nios/nios_dns_view/tasks/nios_dns_view_idempotence.yml b/tests/integration/targets/nios_dns_view/tasks/nios_dns_view_idempotence.yml similarity index 100% rename from tests/integration/nios/nios_dns_view/tasks/nios_dns_view_idempotence.yml rename to tests/integration/targets/nios_dns_view/tasks/nios_dns_view_idempotence.yml diff --git a/tests/integration/nios/nios_host_record/aliases b/tests/integration/targets/nios_host_record/aliases similarity index 100% rename from tests/integration/nios/nios_host_record/aliases rename to tests/integration/targets/nios_host_record/aliases diff --git a/tests/integration/nios/nios_host_record/defaults/main.yaml b/tests/integration/targets/nios_host_record/defaults/main.yaml similarity index 100% rename from tests/integration/nios/nios_host_record/defaults/main.yaml rename to tests/integration/targets/nios_host_record/defaults/main.yaml diff --git a/tests/integration/nios/nios_host_record/meta/main.yaml b/tests/integration/targets/nios_host_record/meta/main.yaml similarity index 100% rename from tests/integration/nios/nios_host_record/meta/main.yaml rename to tests/integration/targets/nios_host_record/meta/main.yaml diff --git a/tests/integration/nios/nios_host_record/tasks/main.yml b/tests/integration/targets/nios_host_record/tasks/main.yml similarity index 100% rename from tests/integration/nios/nios_host_record/tasks/main.yml rename to tests/integration/targets/nios_host_record/tasks/main.yml diff --git a/tests/integration/nios/nios_host_record/tasks/nios_host_record_idempotence.yml b/tests/integration/targets/nios_host_record/tasks/nios_host_record_idempotence.yml similarity index 100% rename from tests/integration/nios/nios_host_record/tasks/nios_host_record_idempotence.yml rename to tests/integration/targets/nios_host_record/tasks/nios_host_record_idempotence.yml diff --git a/tests/integration/nios/nios_mx_record/aliases b/tests/integration/targets/nios_mx_record/aliases similarity index 100% rename from tests/integration/nios/nios_mx_record/aliases rename to tests/integration/targets/nios_mx_record/aliases diff --git a/tests/integration/nios/nios_mx_record/defaults/main.yaml b/tests/integration/targets/nios_mx_record/defaults/main.yaml similarity index 100% rename from tests/integration/nios/nios_mx_record/defaults/main.yaml rename to tests/integration/targets/nios_mx_record/defaults/main.yaml diff --git a/tests/integration/nios/nios_mx_record/meta/main.yaml b/tests/integration/targets/nios_mx_record/meta/main.yaml similarity index 100% rename from tests/integration/nios/nios_mx_record/meta/main.yaml rename to tests/integration/targets/nios_mx_record/meta/main.yaml diff --git a/tests/integration/nios/nios_mx_record/tasks/main.yml b/tests/integration/targets/nios_mx_record/tasks/main.yml similarity index 100% rename from tests/integration/nios/nios_mx_record/tasks/main.yml rename to tests/integration/targets/nios_mx_record/tasks/main.yml diff --git a/tests/integration/nios/nios_mx_record/tasks/nios_mx_record_idempotence.yml b/tests/integration/targets/nios_mx_record/tasks/nios_mx_record_idempotence.yml similarity index 100% rename from tests/integration/nios/nios_mx_record/tasks/nios_mx_record_idempotence.yml rename to tests/integration/targets/nios_mx_record/tasks/nios_mx_record_idempotence.yml diff --git a/tests/integration/nios/nios_naptr_record/aliases b/tests/integration/targets/nios_naptr_record/aliases similarity index 100% rename from tests/integration/nios/nios_naptr_record/aliases rename to tests/integration/targets/nios_naptr_record/aliases diff --git a/tests/integration/nios/nios_naptr_record/defaults/main.yaml b/tests/integration/targets/nios_naptr_record/defaults/main.yaml similarity index 100% rename from tests/integration/nios/nios_naptr_record/defaults/main.yaml rename to tests/integration/targets/nios_naptr_record/defaults/main.yaml diff --git a/tests/integration/nios/nios_naptr_record/meta/main.yaml b/tests/integration/targets/nios_naptr_record/meta/main.yaml similarity index 100% rename from tests/integration/nios/nios_naptr_record/meta/main.yaml rename to tests/integration/targets/nios_naptr_record/meta/main.yaml diff --git a/tests/integration/nios/nios_naptr_record/tasks/main.yml b/tests/integration/targets/nios_naptr_record/tasks/main.yml similarity index 100% rename from tests/integration/nios/nios_naptr_record/tasks/main.yml rename to tests/integration/targets/nios_naptr_record/tasks/main.yml diff --git a/tests/integration/nios/nios_naptr_record/tasks/nios_naptr_record_idempotence.yml b/tests/integration/targets/nios_naptr_record/tasks/nios_naptr_record_idempotence.yml similarity index 100% rename from tests/integration/nios/nios_naptr_record/tasks/nios_naptr_record_idempotence.yml rename to tests/integration/targets/nios_naptr_record/tasks/nios_naptr_record_idempotence.yml diff --git a/tests/integration/nios/nios_network/aliases b/tests/integration/targets/nios_network/aliases similarity index 100% rename from tests/integration/nios/nios_network/aliases rename to tests/integration/targets/nios_network/aliases diff --git a/tests/integration/nios/nios_network/defaults/main.yaml b/tests/integration/targets/nios_network/defaults/main.yaml similarity index 100% rename from tests/integration/nios/nios_network/defaults/main.yaml rename to tests/integration/targets/nios_network/defaults/main.yaml diff --git a/tests/integration/nios/nios_network/meta/main.yaml b/tests/integration/targets/nios_network/meta/main.yaml similarity index 100% rename from tests/integration/nios/nios_network/meta/main.yaml rename to tests/integration/targets/nios_network/meta/main.yaml diff --git a/tests/integration/nios/nios_network/tasks/main.yml b/tests/integration/targets/nios_network/tasks/main.yml similarity index 100% rename from tests/integration/nios/nios_network/tasks/main.yml rename to tests/integration/targets/nios_network/tasks/main.yml diff --git a/tests/integration/nios/nios_network/tasks/nios_network_idempotence.yml b/tests/integration/targets/nios_network/tasks/nios_network_idempotence.yml similarity index 100% rename from tests/integration/nios/nios_network/tasks/nios_network_idempotence.yml rename to tests/integration/targets/nios_network/tasks/nios_network_idempotence.yml diff --git a/tests/integration/nios/nios_network_view/aliases b/tests/integration/targets/nios_network_view/aliases similarity index 100% rename from tests/integration/nios/nios_network_view/aliases rename to tests/integration/targets/nios_network_view/aliases diff --git a/tests/integration/nios/nios_network_view/defaults/main.yaml b/tests/integration/targets/nios_network_view/defaults/main.yaml similarity index 100% rename from tests/integration/nios/nios_network_view/defaults/main.yaml rename to tests/integration/targets/nios_network_view/defaults/main.yaml diff --git a/tests/integration/nios/nios_network_view/meta/main.yaml b/tests/integration/targets/nios_network_view/meta/main.yaml similarity index 100% rename from tests/integration/nios/nios_network_view/meta/main.yaml rename to tests/integration/targets/nios_network_view/meta/main.yaml diff --git a/tests/integration/nios/nios_network_view/tasks/main.yml b/tests/integration/targets/nios_network_view/tasks/main.yml similarity index 100% rename from tests/integration/nios/nios_network_view/tasks/main.yml rename to tests/integration/targets/nios_network_view/tasks/main.yml diff --git a/tests/integration/nios/nios_network_view/tasks/nios_network_view_idempotence.yml b/tests/integration/targets/nios_network_view/tasks/nios_network_view_idempotence.yml similarity index 100% rename from tests/integration/nios/nios_network_view/tasks/nios_network_view_idempotence.yml rename to tests/integration/targets/nios_network_view/tasks/nios_network_view_idempotence.yml diff --git a/tests/integration/nios/nios_ptr_record/aliases b/tests/integration/targets/nios_ptr_record/aliases similarity index 100% rename from tests/integration/nios/nios_ptr_record/aliases rename to tests/integration/targets/nios_ptr_record/aliases diff --git a/tests/integration/nios/nios_ptr_record/defaults/main.yaml b/tests/integration/targets/nios_ptr_record/defaults/main.yaml similarity index 100% rename from tests/integration/nios/nios_ptr_record/defaults/main.yaml rename to tests/integration/targets/nios_ptr_record/defaults/main.yaml diff --git a/tests/integration/nios/nios_ptr_record/meta/main.yaml b/tests/integration/targets/nios_ptr_record/meta/main.yaml similarity index 100% rename from tests/integration/nios/nios_ptr_record/meta/main.yaml rename to tests/integration/targets/nios_ptr_record/meta/main.yaml diff --git a/tests/integration/nios/nios_ptr_record/tasks/main.yml b/tests/integration/targets/nios_ptr_record/tasks/main.yml similarity index 100% rename from tests/integration/nios/nios_ptr_record/tasks/main.yml rename to tests/integration/targets/nios_ptr_record/tasks/main.yml diff --git a/tests/integration/nios/nios_ptr_record/tasks/nios_ptr_record_idempotence.yml b/tests/integration/targets/nios_ptr_record/tasks/nios_ptr_record_idempotence.yml similarity index 100% rename from tests/integration/nios/nios_ptr_record/tasks/nios_ptr_record_idempotence.yml rename to tests/integration/targets/nios_ptr_record/tasks/nios_ptr_record_idempotence.yml diff --git a/tests/integration/nios/nios_srv_record/aliases b/tests/integration/targets/nios_srv_record/aliases similarity index 100% rename from tests/integration/nios/nios_srv_record/aliases rename to tests/integration/targets/nios_srv_record/aliases diff --git a/tests/integration/nios/nios_srv_record/defaults/main.yaml b/tests/integration/targets/nios_srv_record/defaults/main.yaml similarity index 100% rename from tests/integration/nios/nios_srv_record/defaults/main.yaml rename to tests/integration/targets/nios_srv_record/defaults/main.yaml diff --git a/tests/integration/nios/nios_srv_record/meta/main.yaml b/tests/integration/targets/nios_srv_record/meta/main.yaml similarity index 100% rename from tests/integration/nios/nios_srv_record/meta/main.yaml rename to tests/integration/targets/nios_srv_record/meta/main.yaml diff --git a/tests/integration/nios/nios_srv_record/tasks/main.yml b/tests/integration/targets/nios_srv_record/tasks/main.yml similarity index 100% rename from tests/integration/nios/nios_srv_record/tasks/main.yml rename to tests/integration/targets/nios_srv_record/tasks/main.yml diff --git a/tests/integration/nios/nios_srv_record/tasks/nios_srv_record_idempotence.yml b/tests/integration/targets/nios_srv_record/tasks/nios_srv_record_idempotence.yml similarity index 100% rename from tests/integration/nios/nios_srv_record/tasks/nios_srv_record_idempotence.yml rename to tests/integration/targets/nios_srv_record/tasks/nios_srv_record_idempotence.yml diff --git a/tests/integration/nios/nios_txt_record/aliases b/tests/integration/targets/nios_txt_record/aliases similarity index 100% rename from tests/integration/nios/nios_txt_record/aliases rename to tests/integration/targets/nios_txt_record/aliases diff --git a/tests/integration/nios/nios_txt_record/defaults/main.yaml b/tests/integration/targets/nios_txt_record/defaults/main.yaml similarity index 100% rename from tests/integration/nios/nios_txt_record/defaults/main.yaml rename to tests/integration/targets/nios_txt_record/defaults/main.yaml diff --git a/tests/integration/nios/nios_txt_record/meta/main.yaml b/tests/integration/targets/nios_txt_record/meta/main.yaml similarity index 100% rename from tests/integration/nios/nios_txt_record/meta/main.yaml rename to tests/integration/targets/nios_txt_record/meta/main.yaml diff --git a/tests/integration/nios/nios_txt_record/tasks/main.yml b/tests/integration/targets/nios_txt_record/tasks/main.yml similarity index 100% rename from tests/integration/nios/nios_txt_record/tasks/main.yml rename to tests/integration/targets/nios_txt_record/tasks/main.yml diff --git a/tests/integration/nios/nios_txt_record/tasks/nios_txt_record_idempotence.yml b/tests/integration/targets/nios_txt_record/tasks/nios_txt_record_idempotence.yml similarity index 98% rename from tests/integration/nios/nios_txt_record/tasks/nios_txt_record_idempotence.yml rename to tests/integration/targets/nios_txt_record/tasks/nios_txt_record_idempotence.yml index 3b7357af..37638d85 100644 --- a/tests/integration/nios/nios_txt_record/tasks/nios_txt_record_idempotence.yml +++ b/tests/integration/targets/nios_txt_record/tasks/nios_txt_record_idempotence.yml @@ -59,6 +59,7 @@ - name: remove a txt record from the system nios_txt_record: name: txt.ansible.com + text: mytext state: absent provider: "{{ nios_provider }}" register: txt_delete1 @@ -66,6 +67,7 @@ - name: remove a txt record from the system nios_txt_record: name: txt.ansible.com + text: mytext state: absent provider: "{{ nios_provider }}" register: txt_delete2 diff --git a/tests/integration/nios/nios_zone/aliases b/tests/integration/targets/nios_zone/aliases similarity index 100% rename from tests/integration/nios/nios_zone/aliases rename to tests/integration/targets/nios_zone/aliases diff --git a/tests/integration/nios/nios_zone/defaults/main.yaml b/tests/integration/targets/nios_zone/defaults/main.yaml similarity index 100% rename from tests/integration/nios/nios_zone/defaults/main.yaml rename to tests/integration/targets/nios_zone/defaults/main.yaml diff --git a/tests/integration/nios/nios_zone/meta/main.yaml b/tests/integration/targets/nios_zone/meta/main.yaml similarity index 100% rename from tests/integration/nios/nios_zone/meta/main.yaml rename to tests/integration/targets/nios_zone/meta/main.yaml diff --git a/tests/integration/nios/nios_zone/tasks/main.yml b/tests/integration/targets/nios_zone/tasks/main.yml similarity index 100% rename from tests/integration/nios/nios_zone/tasks/main.yml rename to tests/integration/targets/nios_zone/tasks/main.yml diff --git a/tests/integration/nios/nios_zone/tasks/nios_zone_idempotence.yml b/tests/integration/targets/nios_zone/tasks/nios_zone_idempotence.yml similarity index 100% rename from tests/integration/nios/nios_zone/tasks/nios_zone_idempotence.yml rename to tests/integration/targets/nios_zone/tasks/nios_zone_idempotence.yml diff --git a/tests/integration/targets/prepare_nios_tests/tasks/main.yml b/tests/integration/targets/prepare_nios_tests/tasks/main.yml new file mode 100644 index 00000000..2a3092f3 --- /dev/null +++ b/tests/integration/targets/prepare_nios_tests/tasks/main.yml @@ -0,0 +1 @@ +- include: prepare_nios_tests_idempotence.yml diff --git a/tests/integration/targets/prepare_nios_tests/tasks/prepare_nios_tests_idempotence.yml b/tests/integration/targets/prepare_nios_tests/tasks/prepare_nios_tests_idempotence.yml new file mode 100644 index 00000000..749faa20 --- /dev/null +++ b/tests/integration/targets/prepare_nios_tests/tasks/prepare_nios_tests_idempotence.yml @@ -0,0 +1,2 @@ +- pip: + name: infoblox-client diff --git a/tests/requirements.txt b/tests/requirements.txt new file mode 100644 index 00000000..7f835e9f --- /dev/null +++ b/tests/requirements.txt @@ -0,0 +1,9 @@ +infoblox-client +pytest +pytest-xdist +mock +pytest-mock +pytest-cov==2.8.0 +coverage +pygobject +launchpadlib diff --git a/tests/sanity/ignore.txt b/tests/sanity/ignore.txt deleted file mode 100644 index 2a637c93..00000000 --- a/tests/sanity/ignore.txt +++ /dev/null @@ -1,552 +0,0 @@ -docs/bin/find-plugin-refs.py future-import-boilerplate -docs/bin/find-plugin-refs.py metaclass-boilerplate -docs/docsite/_extensions/pygments_lexer.py future-import-boilerplate -docs/docsite/_extensions/pygments_lexer.py metaclass-boilerplate -docs/docsite/_themes/sphinx_rtd_theme/__init__.py future-import-boilerplate -docs/docsite/_themes/sphinx_rtd_theme/__init__.py metaclass-boilerplate -docs/docsite/rst/conf.py future-import-boilerplate -docs/docsite/rst/conf.py metaclass-boilerplate -docs/docsite/rst/dev_guide/testing/sanity/no-smart-quotes.rst no-smart-quotes -examples/scripts/ConfigureRemotingForAnsible.ps1 pslint:PSCustomUseLiteralPath -examples/scripts/upgrade_to_ps3.ps1 pslint:PSCustomUseLiteralPath -examples/scripts/upgrade_to_ps3.ps1 pslint:PSUseApprovedVerbs -examples/scripts/uptime.py future-import-boilerplate -examples/scripts/uptime.py metaclass-boilerplate -hacking/build-ansible.py shebang # only run by release engineers, Python 3.6+ required -hacking/build_library/build_ansible/announce.py compile-2.6!skip # release process only, 3.6+ required -hacking/build_library/build_ansible/announce.py compile-2.7!skip # release process only, 3.6+ required -hacking/build_library/build_ansible/announce.py compile-3.5!skip # release process only, 3.6+ required -hacking/build_library/build_ansible/command_plugins/dump_config.py compile-2.6!skip # docs build only, 2.7+ required -hacking/build_library/build_ansible/command_plugins/dump_keywords.py compile-2.6!skip # docs build only, 2.7+ required -hacking/build_library/build_ansible/command_plugins/generate_man.py compile-2.6!skip # docs build only, 2.7+ required -hacking/build_library/build_ansible/command_plugins/plugin_formatter.py compile-2.6!skip # docs build only, 2.7+ required -hacking/build_library/build_ansible/command_plugins/porting_guide.py compile-2.6!skip # release process only, 3.6+ required -hacking/build_library/build_ansible/command_plugins/porting_guide.py compile-2.7!skip # release process only, 3.6+ required -hacking/build_library/build_ansible/command_plugins/porting_guide.py compile-3.5!skip # release process only, 3.6+ required -hacking/build_library/build_ansible/command_plugins/release_announcement.py compile-2.6!skip # release process only, 3.6+ required -hacking/build_library/build_ansible/command_plugins/release_announcement.py compile-2.7!skip # release process only, 3.6+ required -hacking/build_library/build_ansible/command_plugins/release_announcement.py compile-3.5!skip # release process only, 3.6+ required -hacking/build_library/build_ansible/command_plugins/update_intersphinx.py compile-2.6!skip # release process and docs build only, 3.5+ required -hacking/build_library/build_ansible/command_plugins/update_intersphinx.py compile-2.7!skip # release process and docs build only, 3.5+ required -hacking/fix_test_syntax.py future-import-boilerplate -hacking/fix_test_syntax.py metaclass-boilerplate -hacking/get_library.py future-import-boilerplate -hacking/get_library.py metaclass-boilerplate -hacking/report.py future-import-boilerplate -hacking/report.py metaclass-boilerplate -hacking/return_skeleton_generator.py future-import-boilerplate -hacking/return_skeleton_generator.py metaclass-boilerplate -hacking/test-module.py future-import-boilerplate -hacking/test-module.py metaclass-boilerplate -hacking/tests/gen_distribution_version_testcase.py future-import-boilerplate -hacking/tests/gen_distribution_version_testcase.py metaclass-boilerplate -lib/ansible/cli/console.py pylint:blacklisted-name -lib/ansible/cli/scripts/ansible_cli_stub.py shebang -lib/ansible/cli/scripts/ansible_connection_cli_stub.py shebang -lib/ansible/compat/selectors/_selectors2.py future-import-boilerplate # ignore bundled -lib/ansible/compat/selectors/_selectors2.py metaclass-boilerplate # ignore bundled -lib/ansible/compat/selectors/_selectors2.py pylint:blacklisted-name -lib/ansible/config/base.yml no-unwanted-files -lib/ansible/config/module_defaults.yml no-unwanted-files -lib/ansible/executor/playbook_executor.py pylint:blacklisted-name -lib/ansible/executor/powershell/async_watchdog.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/executor/powershell/async_wrapper.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/executor/powershell/exec_wrapper.ps1 pslint:PSCustomUseLiteralPath -lib/ansible/executor/task_queue_manager.py pylint:blacklisted-name -lib/ansible/module_utils/_text.py future-import-boilerplate -lib/ansible/module_utils/_text.py metaclass-boilerplate -lib/ansible/module_utils/api.py future-import-boilerplate -lib/ansible/module_utils/api.py metaclass-boilerplate -lib/ansible/module_utils/basic.py metaclass-boilerplate -lib/ansible/module_utils/common/network.py future-import-boilerplate -lib/ansible/module_utils/common/network.py metaclass-boilerplate -lib/ansible/module_utils/connection.py future-import-boilerplate -lib/ansible/module_utils/connection.py metaclass-boilerplate -lib/ansible/module_utils/distro/__init__.py empty-init # breaks namespacing, bundled, do not override -lib/ansible/module_utils/distro/_distro.py future-import-boilerplate # ignore bundled -lib/ansible/module_utils/distro/_distro.py metaclass-boilerplate # ignore bundled -lib/ansible/module_utils/distro/_distro.py no-assert -lib/ansible/module_utils/distro/_distro.py pep8!skip # bundled code we don't want to modify -lib/ansible/module_utils/facts/__init__.py empty-init # breaks namespacing, deprecate and eventually remove -lib/ansible/module_utils/facts/network/linux.py pylint:blacklisted-name -lib/ansible/module_utils/facts/sysctl.py future-import-boilerplate -lib/ansible/module_utils/facts/sysctl.py metaclass-boilerplate -lib/ansible/module_utils/facts/system/distribution.py pylint:ansible-bad-function -lib/ansible/module_utils/facts/utils.py future-import-boilerplate -lib/ansible/module_utils/facts/utils.py metaclass-boilerplate -lib/ansible/module_utils/json_utils.py future-import-boilerplate -lib/ansible/module_utils/json_utils.py metaclass-boilerplate -lib/ansible/module_utils/parsing/convert_bool.py future-import-boilerplate -lib/ansible/module_utils/parsing/convert_bool.py metaclass-boilerplate -lib/ansible/module_utils/powershell/Ansible.ModuleUtils.ArgvParser.psm1 pslint:PSUseApprovedVerbs -lib/ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 pslint:PSProvideCommentHelp # need to agree on best format for comment location -lib/ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 pslint:PSUseApprovedVerbs -lib/ansible/module_utils/powershell/Ansible.ModuleUtils.FileUtil.psm1 pslint:PSCustomUseLiteralPath -lib/ansible/module_utils/powershell/Ansible.ModuleUtils.FileUtil.psm1 pslint:PSProvideCommentHelp -lib/ansible/module_utils/powershell/Ansible.ModuleUtils.Legacy.psm1 pslint:PSCustomUseLiteralPath -lib/ansible/module_utils/powershell/Ansible.ModuleUtils.Legacy.psm1 pslint:PSUseApprovedVerbs -lib/ansible/module_utils/powershell/Ansible.ModuleUtils.LinkUtil.psm1 pslint:PSUseApprovedVerbs -lib/ansible/module_utils/pycompat24.py future-import-boilerplate -lib/ansible/module_utils/pycompat24.py metaclass-boilerplate -lib/ansible/module_utils/pycompat24.py no-get-exception -lib/ansible/module_utils/service.py future-import-boilerplate -lib/ansible/module_utils/service.py metaclass-boilerplate -lib/ansible/module_utils/six/__init__.py empty-init # breaks namespacing, bundled, do not override -lib/ansible/module_utils/six/__init__.py future-import-boilerplate # ignore bundled -lib/ansible/module_utils/six/__init__.py metaclass-boilerplate # ignore bundled -lib/ansible/module_utils/six/__init__.py no-basestring -lib/ansible/module_utils/six/__init__.py no-dict-iteritems -lib/ansible/module_utils/six/__init__.py no-dict-iterkeys -lib/ansible/module_utils/six/__init__.py no-dict-itervalues -lib/ansible/module_utils/six/__init__.py replace-urlopen -lib/ansible/module_utils/splitter.py future-import-boilerplate -lib/ansible/module_utils/splitter.py metaclass-boilerplate -lib/ansible/module_utils/urls.py future-import-boilerplate -lib/ansible/module_utils/urls.py metaclass-boilerplate -lib/ansible/module_utils/urls.py pylint:blacklisted-name -lib/ansible/module_utils/urls.py replace-urlopen -lib/ansible/module_utils/yumdnf.py future-import-boilerplate -lib/ansible/module_utils/yumdnf.py metaclass-boilerplate -lib/ansible/modules/commands/command.py validate-modules:doc-missing-type -lib/ansible/modules/commands/command.py validate-modules:nonexistent-parameter-documented -lib/ansible/modules/commands/command.py validate-modules:parameter-list-no-elements -lib/ansible/modules/commands/command.py validate-modules:undocumented-parameter -lib/ansible/modules/commands/expect.py validate-modules:doc-missing-type -lib/ansible/modules/files/assemble.py validate-modules:nonexistent-parameter-documented -lib/ansible/modules/files/blockinfile.py validate-modules:doc-choices-do-not-match-spec -lib/ansible/modules/files/blockinfile.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/files/copy.py pylint:blacklisted-name -lib/ansible/modules/files/copy.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/files/copy.py validate-modules:doc-type-does-not-match-spec -lib/ansible/modules/files/copy.py validate-modules:nonexistent-parameter-documented -lib/ansible/modules/files/copy.py validate-modules:undocumented-parameter -lib/ansible/modules/files/file.py pylint:ansible-bad-function -lib/ansible/modules/files/file.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/files/file.py validate-modules:undocumented-parameter -lib/ansible/modules/files/find.py use-argspec-type-path # fix needed -lib/ansible/modules/files/find.py validate-modules:parameter-list-no-elements -lib/ansible/modules/files/find.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/files/lineinfile.py validate-modules:doc-choices-do-not-match-spec -lib/ansible/modules/files/lineinfile.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/files/lineinfile.py validate-modules:nonexistent-parameter-documented -lib/ansible/modules/files/replace.py validate-modules:nonexistent-parameter-documented -lib/ansible/modules/files/stat.py validate-modules:parameter-invalid -lib/ansible/modules/files/stat.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/files/stat.py validate-modules:undocumented-parameter -lib/ansible/modules/files/unarchive.py validate-modules:nonexistent-parameter-documented -lib/ansible/modules/files/unarchive.py validate-modules:parameter-list-no-elements -lib/ansible/modules/net_tools/basics/get_url.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/net_tools/basics/uri.py pylint:blacklisted-name -lib/ansible/modules/net_tools/basics/uri.py validate-modules:doc-required-mismatch -lib/ansible/modules/net_tools/basics/uri.py validate-modules:parameter-list-no-elements -lib/ansible/modules/net_tools/basics/uri.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/packaging/language/pip.py pylint:blacklisted-name -lib/ansible/modules/packaging/language/pip.py validate-modules:doc-elements-mismatch -lib/ansible/modules/packaging/language/pip.py validate-modules:invalid-ansiblemodule-schema -lib/ansible/modules/packaging/os/apt.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/packaging/os/apt.py validate-modules:parameter-invalid -lib/ansible/modules/packaging/os/apt.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/packaging/os/apt.py validate-modules:undocumented-parameter -lib/ansible/modules/packaging/os/apt_key.py validate-modules:mutually_exclusive-unknown -lib/ansible/modules/packaging/os/apt_key.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/packaging/os/apt_key.py validate-modules:undocumented-parameter -lib/ansible/modules/packaging/os/apt_repository.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/packaging/os/apt_repository.py validate-modules:parameter-invalid -lib/ansible/modules/packaging/os/apt_repository.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/packaging/os/apt_repository.py validate-modules:undocumented-parameter -lib/ansible/modules/packaging/os/dnf.py validate-modules:doc-missing-type -lib/ansible/modules/packaging/os/dnf.py validate-modules:doc-required-mismatch -lib/ansible/modules/packaging/os/dnf.py validate-modules:parameter-invalid -lib/ansible/modules/packaging/os/dnf.py validate-modules:parameter-list-no-elements -lib/ansible/modules/packaging/os/dnf.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/packaging/os/dpkg_selections.py validate-modules:doc-missing-type -lib/ansible/modules/packaging/os/dpkg_selections.py validate-modules:doc-required-mismatch -lib/ansible/modules/packaging/os/package_facts.py validate-modules:doc-choices-do-not-match-spec -lib/ansible/modules/packaging/os/package_facts.py validate-modules:doc-missing-type -lib/ansible/modules/packaging/os/package_facts.py validate-modules:parameter-list-no-elements -lib/ansible/modules/packaging/os/package_facts.py validate-modules:return-syntax-error -lib/ansible/modules/packaging/os/rpm_key.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/packaging/os/yum.py pylint:blacklisted-name -lib/ansible/modules/packaging/os/yum.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/packaging/os/yum.py validate-modules:doc-missing-type -lib/ansible/modules/packaging/os/yum.py validate-modules:parameter-invalid -lib/ansible/modules/packaging/os/yum.py validate-modules:parameter-list-no-elements -lib/ansible/modules/packaging/os/yum.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/packaging/os/yum.py validate-modules:undocumented-parameter -lib/ansible/modules/packaging/os/yum_repository.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/packaging/os/yum_repository.py validate-modules:doc-missing-type -lib/ansible/modules/packaging/os/yum_repository.py validate-modules:parameter-list-no-elements -lib/ansible/modules/packaging/os/yum_repository.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/packaging/os/yum_repository.py validate-modules:undocumented-parameter -lib/ansible/modules/source_control/git.py pylint:blacklisted-name -lib/ansible/modules/source_control/git.py use-argspec-type-path -lib/ansible/modules/source_control/git.py validate-modules:doc-missing-type -lib/ansible/modules/source_control/git.py validate-modules:doc-required-mismatch -lib/ansible/modules/source_control/git.py validate-modules:parameter-list-no-elements -lib/ansible/modules/source_control/git.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/source_control/subversion.py validate-modules:doc-required-mismatch -lib/ansible/modules/source_control/subversion.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/source_control/subversion.py validate-modules:undocumented-parameter -lib/ansible/modules/system/getent.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/system/hostname.py validate-modules:invalid-ansiblemodule-schema -lib/ansible/modules/system/hostname.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/system/iptables.py pylint:blacklisted-name -lib/ansible/modules/system/iptables.py validate-modules:parameter-list-no-elements -lib/ansible/modules/system/known_hosts.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/system/known_hosts.py validate-modules:doc-missing-type -lib/ansible/modules/system/known_hosts.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/system/service.py validate-modules:nonexistent-parameter-documented -lib/ansible/modules/system/service.py validate-modules:use-run-command-not-popen -lib/ansible/modules/system/setup.py validate-modules:doc-missing-type -lib/ansible/modules/system/setup.py validate-modules:parameter-list-no-elements -lib/ansible/modules/system/setup.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/system/systemd.py validate-modules:parameter-invalid -lib/ansible/modules/system/systemd.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/system/systemd.py validate-modules:return-syntax-error -lib/ansible/modules/system/sysvinit.py validate-modules:parameter-list-no-elements -lib/ansible/modules/system/sysvinit.py validate-modules:parameter-type-not-in-doc -lib/ansible/modules/system/sysvinit.py validate-modules:return-syntax-error -lib/ansible/modules/system/user.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/system/user.py validate-modules:doc-default-incompatible-type -lib/ansible/modules/system/user.py validate-modules:parameter-list-no-elements -lib/ansible/modules/system/user.py validate-modules:use-run-command-not-popen -lib/ansible/modules/utilities/logic/async_status.py use-argspec-type-path -lib/ansible/modules/utilities/logic/async_status.py validate-modules!skip -lib/ansible/modules/utilities/logic/async_wrapper.py ansible-doc!skip # not an actual module -lib/ansible/modules/utilities/logic/async_wrapper.py pylint:ansible-bad-function -lib/ansible/modules/utilities/logic/async_wrapper.py use-argspec-type-path -lib/ansible/modules/utilities/logic/wait_for.py validate-modules:parameter-list-no-elements -lib/ansible/parsing/vault/__init__.py pylint:blacklisted-name -lib/ansible/playbook/base.py pylint:blacklisted-name -lib/ansible/playbook/collectionsearch.py required-and-default-attributes # https://github.com/ansible/ansible/issues/61460 -lib/ansible/playbook/helpers.py pylint:blacklisted-name -lib/ansible/playbook/role/__init__.py pylint:blacklisted-name -lib/ansible/plugins/action/normal.py action-plugin-docs # default action plugin for modules without a dedicated action plugin -lib/ansible/plugins/cache/base.py ansible-doc!skip # not a plugin, but a stub for backwards compatibility -lib/ansible/plugins/doc_fragments/backup.py future-import-boilerplate -lib/ansible/plugins/doc_fragments/backup.py metaclass-boilerplate -lib/ansible/plugins/doc_fragments/constructed.py future-import-boilerplate -lib/ansible/plugins/doc_fragments/constructed.py metaclass-boilerplate -lib/ansible/plugins/doc_fragments/decrypt.py future-import-boilerplate -lib/ansible/plugins/doc_fragments/decrypt.py metaclass-boilerplate -lib/ansible/plugins/doc_fragments/default_callback.py future-import-boilerplate -lib/ansible/plugins/doc_fragments/default_callback.py metaclass-boilerplate -lib/ansible/plugins/doc_fragments/files.py future-import-boilerplate -lib/ansible/plugins/doc_fragments/files.py metaclass-boilerplate -lib/ansible/plugins/doc_fragments/inventory_cache.py future-import-boilerplate -lib/ansible/plugins/doc_fragments/inventory_cache.py metaclass-boilerplate -lib/ansible/plugins/doc_fragments/return_common.py future-import-boilerplate -lib/ansible/plugins/doc_fragments/return_common.py metaclass-boilerplate -lib/ansible/plugins/doc_fragments/shell_common.py future-import-boilerplate -lib/ansible/plugins/doc_fragments/shell_common.py metaclass-boilerplate -lib/ansible/plugins/doc_fragments/shell_windows.py future-import-boilerplate -lib/ansible/plugins/doc_fragments/shell_windows.py metaclass-boilerplate -lib/ansible/plugins/doc_fragments/url.py future-import-boilerplate -lib/ansible/plugins/doc_fragments/url.py metaclass-boilerplate -lib/ansible/plugins/doc_fragments/validate.py future-import-boilerplate -lib/ansible/plugins/doc_fragments/validate.py metaclass-boilerplate -lib/ansible/plugins/lookup/sequence.py pylint:blacklisted-name -lib/ansible/plugins/strategy/__init__.py pylint:blacklisted-name -lib/ansible/plugins/strategy/linear.py pylint:blacklisted-name -lib/ansible/vars/hostvars.py pylint:blacklisted-name -setup.py future-import-boilerplate -setup.py metaclass-boilerplate -test/integration/targets/ansible-runner/files/adhoc_example1.py future-import-boilerplate -test/integration/targets/ansible-runner/files/adhoc_example1.py metaclass-boilerplate -test/integration/targets/ansible-runner/files/playbook_example1.py future-import-boilerplate -test/integration/targets/ansible-runner/files/playbook_example1.py metaclass-boilerplate -test/integration/targets/ansible-test/ansible_collections/ns/col/plugins/modules/hello.py pylint:relative-beyond-top-level -test/integration/targets/ansible-test/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_my_util.py pylint:relative-beyond-top-level -test/integration/targets/ansible-test/ansible_collections/ns/col/tests/unit/plugins/modules/test_hello.py pylint:relative-beyond-top-level -test/integration/targets/async/library/async_test.py future-import-boilerplate -test/integration/targets/async/library/async_test.py metaclass-boilerplate -test/integration/targets/async_fail/library/async_test.py future-import-boilerplate -test/integration/targets/async_fail/library/async_test.py metaclass-boilerplate -test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/lookup/lookup_no_future_boilerplate.py future-import-boilerplate -test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/my_util2.py pylint:relative-beyond-top-level -test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/my_util3.py pylint:relative-beyond-top-level -test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/modules/my_module.py pylint:relative-beyond-top-level -test/integration/targets/expect/files/test_command.py future-import-boilerplate -test/integration/targets/expect/files/test_command.py metaclass-boilerplate -test/integration/targets/gathering_facts/library/bogus_facts shebang -test/integration/targets/get_url/files/testserver.py future-import-boilerplate -test/integration/targets/get_url/files/testserver.py metaclass-boilerplate -test/integration/targets/group/files/gidget.py future-import-boilerplate -test/integration/targets/group/files/gidget.py metaclass-boilerplate -test/integration/targets/ignore_unreachable/fake_connectors/bad_exec.py future-import-boilerplate -test/integration/targets/ignore_unreachable/fake_connectors/bad_exec.py metaclass-boilerplate -test/integration/targets/ignore_unreachable/fake_connectors/bad_put_file.py future-import-boilerplate -test/integration/targets/ignore_unreachable/fake_connectors/bad_put_file.py metaclass-boilerplate -test/integration/targets/incidental_script_inventory_vmware_inventory/vmware_inventory.py future-import-boilerplate -test/integration/targets/incidental_script_inventory_vmware_inventory/vmware_inventory.py metaclass-boilerplate -test/integration/targets/incidental_win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.psm1 pslint!skip -test/integration/targets/incidental_win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1 pslint!skip -test/integration/targets/incidental_win_dsc/files/xTestDsc/1.0.0/xTestDsc.psd1 pslint!skip -test/integration/targets/incidental_win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1 pslint!skip -test/integration/targets/incidental_win_dsc/files/xTestDsc/1.0.1/xTestDsc.psd1 pslint!skip -test/integration/targets/incidental_win_ping/library/win_ping_syntax_error.ps1 pslint!skip -test/integration/targets/incidental_win_reboot/templates/post_reboot.ps1 pslint!skip -test/integration/targets/lookup_ini/lookup-8859-15.ini no-smart-quotes -test/integration/targets/module_precedence/lib_with_extension/a.ini shebang -test/integration/targets/module_precedence/lib_with_extension/ping.ini shebang -test/integration/targets/module_precedence/lib_with_extension/ping.py future-import-boilerplate -test/integration/targets/module_precedence/lib_with_extension/ping.py metaclass-boilerplate -test/integration/targets/module_precedence/multiple_roles/bar/library/ping.py future-import-boilerplate -test/integration/targets/module_precedence/multiple_roles/bar/library/ping.py metaclass-boilerplate -test/integration/targets/module_precedence/multiple_roles/foo/library/ping.py future-import-boilerplate -test/integration/targets/module_precedence/multiple_roles/foo/library/ping.py metaclass-boilerplate -test/integration/targets/module_precedence/roles_with_extension/foo/library/a.ini shebang -test/integration/targets/module_precedence/roles_with_extension/foo/library/ping.ini shebang -test/integration/targets/module_precedence/roles_with_extension/foo/library/ping.py future-import-boilerplate -test/integration/targets/module_precedence/roles_with_extension/foo/library/ping.py metaclass-boilerplate -test/integration/targets/module_utils/library/test.py future-import-boilerplate -test/integration/targets/module_utils/library/test.py metaclass-boilerplate -test/integration/targets/module_utils/library/test_env_override.py future-import-boilerplate -test/integration/targets/module_utils/library/test_env_override.py metaclass-boilerplate -test/integration/targets/module_utils/library/test_failure.py future-import-boilerplate -test/integration/targets/module_utils/library/test_failure.py metaclass-boilerplate -test/integration/targets/module_utils/library/test_override.py future-import-boilerplate -test/integration/targets/module_utils/library/test_override.py metaclass-boilerplate -test/integration/targets/module_utils/module_utils/bar0/foo.py pylint:blacklisted-name -test/integration/targets/module_utils/module_utils/foo.py pylint:blacklisted-name -test/integration/targets/module_utils/module_utils/sub/bar/__init__.py pylint:blacklisted-name -test/integration/targets/module_utils/module_utils/sub/bar/bar.py pylint:blacklisted-name -test/integration/targets/module_utils/module_utils/yak/zebra/foo.py pylint:blacklisted-name -test/integration/targets/old_style_modules_posix/library/helloworld.sh shebang -test/integration/targets/pause/test-pause.py future-import-boilerplate -test/integration/targets/pause/test-pause.py metaclass-boilerplate -test/integration/targets/pip/files/ansible_test_pip_chdir/__init__.py future-import-boilerplate -test/integration/targets/pip/files/ansible_test_pip_chdir/__init__.py metaclass-boilerplate -test/integration/targets/pip/files/setup.py future-import-boilerplate -test/integration/targets/pip/files/setup.py metaclass-boilerplate -test/integration/targets/run_modules/library/test.py future-import-boilerplate -test/integration/targets/run_modules/library/test.py metaclass-boilerplate -test/integration/targets/script/files/no_shebang.py future-import-boilerplate -test/integration/targets/script/files/no_shebang.py metaclass-boilerplate -test/integration/targets/service/files/ansible_test_service.py future-import-boilerplate -test/integration/targets/service/files/ansible_test_service.py metaclass-boilerplate -test/integration/targets/setup_rpm_repo/files/create-repo.py future-import-boilerplate -test/integration/targets/setup_rpm_repo/files/create-repo.py metaclass-boilerplate -test/integration/targets/template/files/encoding_1252_utf-8.expected no-smart-quotes -test/integration/targets/template/files/encoding_1252_windows-1252.expected no-smart-quotes -test/integration/targets/template/files/foo.dos.txt line-endings -test/integration/targets/template/role_filter/filter_plugins/myplugin.py future-import-boilerplate -test/integration/targets/template/role_filter/filter_plugins/myplugin.py metaclass-boilerplate -test/integration/targets/template/templates/encoding_1252.j2 no-smart-quotes -test/integration/targets/infra/library/test.py future-import-boilerplate -test/integration/targets/infra/library/test.py metaclass-boilerplate -test/integration/targets/unicode/unicode.yml no-smart-quotes -test/integration/targets/uri/files/testserver.py future-import-boilerplate -test/integration/targets/uri/files/testserver.py metaclass-boilerplate -test/integration/targets/var_precedence/ansible-var-precedence-check.py future-import-boilerplate -test/integration/targets/var_precedence/ansible-var-precedence-check.py metaclass-boilerplate -test/integration/targets/builtin_vars_prompt/test-vars_prompt.py future-import-boilerplate -test/integration/targets/builtin_vars_prompt/test-vars_prompt.py metaclass-boilerplate -test/integration/targets/vault/test-vault-client.py future-import-boilerplate -test/integration/targets/vault/test-vault-client.py metaclass-boilerplate -test/integration/targets/wait_for/files/testserver.py future-import-boilerplate -test/integration/targets/wait_for/files/testserver.py metaclass-boilerplate -test/integration/targets/want_json_modules_posix/library/helloworld.py future-import-boilerplate -test/integration/targets/want_json_modules_posix/library/helloworld.py metaclass-boilerplate -test/integration/targets/win_exec_wrapper/library/test_fail.ps1 pslint:PSCustomUseLiteralPath -test/integration/targets/win_exec_wrapper/tasks/main.yml no-smart-quotes # We are explicitly testing smart quote support for env vars -test/integration/targets/win_module_utils/library/legacy_only_new_way_win_line_ending.ps1 line-endings # Explicitly tests that we still work with Windows line endings -test/integration/targets/win_module_utils/library/legacy_only_old_way_win_line_ending.ps1 line-endings # Explicitly tests that we still work with Windows line endings -test/integration/targets/win_script/files/test_script.ps1 pslint:PSAvoidUsingWriteHost # Keep -test/integration/targets/win_script/files/test_script_creates_file.ps1 pslint:PSAvoidUsingCmdletAliases -test/integration/targets/win_script/files/test_script_removes_file.ps1 pslint:PSCustomUseLiteralPath -test/integration/targets/win_script/files/test_script_with_args.ps1 pslint:PSAvoidUsingWriteHost # Keep -test/integration/targets/win_script/files/test_script_with_splatting.ps1 pslint:PSAvoidUsingWriteHost # Keep -test/integration/targets/windows-minimal/library/win_ping_syntax_error.ps1 pslint!skip -test/lib/ansible_test/_data/requirements/constraints.txt test-constraints -test/lib/ansible_test/_data/requirements/integration.cloud.azure.txt test-constraints -test/lib/ansible_test/_data/sanity/pylint/plugins/string_format.py use-compat-six -test/lib/ansible_test/_data/setup/ConfigureRemotingForAnsible.ps1 pslint:PSCustomUseLiteralPath -test/lib/ansible_test/_data/setup/windows-httptester.ps1 pslint:PSCustomUseLiteralPath -test/support/integration/plugins/module_utils/ansible_tower.py future-import-boilerplate -test/support/integration/plugins/module_utils/ansible_tower.py metaclass-boilerplate -test/support/integration/plugins/module_utils/azure_rm_common.py future-import-boilerplate -test/support/integration/plugins/module_utils/azure_rm_common.py metaclass-boilerplate -test/support/integration/plugins/module_utils/azure_rm_common_rest.py future-import-boilerplate -test/support/integration/plugins/module_utils/azure_rm_common_rest.py metaclass-boilerplate -test/support/integration/plugins/module_utils/cloud.py future-import-boilerplate -test/support/integration/plugins/module_utils/cloud.py metaclass-boilerplate -test/support/integration/plugins/module_utils/common/network.py future-import-boilerplate -test/support/integration/plugins/module_utils/common/network.py metaclass-boilerplate -test/support/integration/plugins/module_utils/compat/ipaddress.py future-import-boilerplate -test/support/integration/plugins/module_utils/compat/ipaddress.py metaclass-boilerplate -test/support/integration/plugins/module_utils/compat/ipaddress.py no-unicode-literals -test/support/integration/plugins/module_utils/database.py future-import-boilerplate -test/support/integration/plugins/module_utils/database.py metaclass-boilerplate -test/support/integration/plugins/module_utils/k8s/common.py metaclass-boilerplate -test/support/integration/plugins/module_utils/k8s/raw.py metaclass-boilerplate -test/support/integration/plugins/module_utils/mysql.py future-import-boilerplate -test/support/integration/plugins/module_utils/mysql.py metaclass-boilerplate -test/support/integration/plugins/module_utils/net_tools/nios/api.py future-import-boilerplate -test/support/integration/plugins/module_utils/net_tools/nios/api.py metaclass-boilerplate -test/support/integration/plugins/module_utils/network/common/utils.py future-import-boilerplate -test/support/integration/plugins/module_utils/network/common/utils.py metaclass-boilerplate -test/support/integration/plugins/module_utils/postgres.py future-import-boilerplate -test/support/integration/plugins/module_utils/postgres.py metaclass-boilerplate -test/support/integration/plugins/modules/lvg.py pylint:blacklisted-name -test/support/integration/plugins/modules/synchronize.py pylint:blacklisted-name -test/support/integration/plugins/modules/timezone.py pylint:blacklisted-name -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/doc_fragments/netconf.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/doc_fragments/netconf.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/doc_fragments/network_agnostic.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/doc_fragments/network_agnostic.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/compat/ipaddress.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/compat/ipaddress.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/compat/ipaddress.py no-unicode-literals -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/compat/ipaddress.py pep8:E203 -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/cfg/base.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/cfg/base.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/config.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/config.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/facts/facts.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/facts/facts.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/netconf.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/netconf.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/network.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/network.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/parsing.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/parsing.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/utils.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/utils.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/netconf/netconf.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/netconf/netconf.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/restconf/restconf.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/restconf/restconf.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/doc_fragments/ios.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/doc_fragments/ios.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/module_utils/network/ios/ios.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/module_utils/network/ios/ios.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/modules/ios_command.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/modules/ios_command.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/modules/ios_config.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/modules/ios_config.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/modules/ios_config.py pep8:E501 -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/doc_fragments/vyos.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/doc_fragments/vyos.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/vyos.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/vyos.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_command.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_command.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_command.py pep8:E231 -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_command.py pylint:blacklisted-name -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_config.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_config.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_facts.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_facts.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_logging.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_logging.py metaclass-boilerplate -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_static_route.py future-import-boilerplate -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_static_route.py metaclass-boilerplate -test/support/windows-integration/plugins/modules/async_status.ps1 pslint!skip -test/support/windows-integration/plugins/modules/setup.ps1 pslint!skip -test/support/windows-integration/plugins/modules/win_copy.ps1 pslint!skip -test/support/windows-integration/plugins/modules/win_dsc.ps1 pslint!skip -test/support/windows-integration/plugins/modules/win_feature.ps1 pslint!skip -test/support/windows-integration/plugins/modules/win_find.ps1 pslint!skip -test/support/windows-integration/plugins/modules/win_lineinfile.ps1 pslint!skip -test/support/windows-integration/plugins/modules/win_regedit.ps1 pslint!skip -test/support/windows-integration/plugins/modules/win_security_policy.ps1 pslint!skip -test/support/windows-integration/plugins/modules/win_shell.ps1 pslint!skip -test/support/windows-integration/plugins/modules/win_wait_for.ps1 pslint!skip -test/units/config/manager/test_find_ini_config_file.py future-import-boilerplate -test/units/executor/test_play_iterator.py pylint:blacklisted-name -test/units/inventory/test_group.py future-import-boilerplate -test/units/inventory/test_group.py metaclass-boilerplate -test/units/inventory/test_host.py future-import-boilerplate -test/units/inventory/test_host.py metaclass-boilerplate -test/units/mock/path.py future-import-boilerplate -test/units/mock/path.py metaclass-boilerplate -test/units/mock/yaml_helper.py future-import-boilerplate -test/units/mock/yaml_helper.py metaclass-boilerplate -test/units/module_utils/basic/test__symbolic_mode_to_octal.py future-import-boilerplate -test/units/module_utils/basic/test_deprecate_warn.py future-import-boilerplate -test/units/module_utils/basic/test_deprecate_warn.py metaclass-boilerplate -test/units/module_utils/basic/test_deprecate_warn.py pylint:ansible-deprecated-no-version -test/units/module_utils/basic/test_exit_json.py future-import-boilerplate -test/units/module_utils/basic/test_get_file_attributes.py future-import-boilerplate -test/units/module_utils/basic/test_heuristic_log_sanitize.py future-import-boilerplate -test/units/module_utils/basic/test_run_command.py future-import-boilerplate -test/units/module_utils/basic/test_run_command.py pylint:blacklisted-name -test/units/module_utils/basic/test_safe_eval.py future-import-boilerplate -test/units/module_utils/basic/test_tmpdir.py future-import-boilerplate -test/units/module_utils/common/test_dict_transformations.py future-import-boilerplate -test/units/module_utils/common/test_dict_transformations.py metaclass-boilerplate -test/units/module_utils/conftest.py future-import-boilerplate -test/units/module_utils/conftest.py metaclass-boilerplate -test/units/module_utils/facts/base.py future-import-boilerplate -test/units/module_utils/facts/hardware/test_sunos_get_uptime_facts.py future-import-boilerplate -test/units/module_utils/facts/hardware/test_sunos_get_uptime_facts.py metaclass-boilerplate -test/units/module_utils/facts/network/test_generic_bsd.py future-import-boilerplate -test/units/module_utils/facts/other/test_facter.py future-import-boilerplate -test/units/module_utils/facts/other/test_ohai.py future-import-boilerplate -test/units/module_utils/facts/system/test_lsb.py future-import-boilerplate -test/units/module_utils/facts/test_ansible_collector.py future-import-boilerplate -test/units/module_utils/facts/test_collector.py future-import-boilerplate -test/units/module_utils/facts/test_collectors.py future-import-boilerplate -test/units/module_utils/facts/test_facts.py future-import-boilerplate -test/units/module_utils/facts/test_timeout.py future-import-boilerplate -test/units/module_utils/facts/test_utils.py future-import-boilerplate -test/units/module_utils/json_utils/test_filter_non_json_lines.py future-import-boilerplate -test/units/module_utils/parsing/test_convert_bool.py future-import-boilerplate -test/units/module_utils/test_distro.py future-import-boilerplate -test/units/module_utils/test_distro.py metaclass-boilerplate -test/units/module_utils/urls/test_Request.py replace-urlopen -test/units/module_utils/urls/test_fetch_url.py replace-urlopen -test/units/modules/conftest.py future-import-boilerplate -test/units/modules/conftest.py metaclass-boilerplate -test/units/modules/files/test_copy.py future-import-boilerplate -test/units/modules/packaging/language/test_pip.py future-import-boilerplate -test/units/modules/packaging/language/test_pip.py metaclass-boilerplate -test/units/modules/packaging/os/test_apt.py future-import-boilerplate -test/units/modules/packaging/os/test_apt.py metaclass-boilerplate -test/units/modules/packaging/os/test_apt.py pylint:blacklisted-name -test/units/modules/packaging/os/test_yum.py future-import-boilerplate -test/units/modules/packaging/os/test_yum.py metaclass-boilerplate -test/units/modules/system/test_iptables.py future-import-boilerplate -test/units/modules/system/test_iptables.py metaclass-boilerplate -test/units/modules/system/test_known_hosts.py future-import-boilerplate -test/units/modules/system/test_known_hosts.py metaclass-boilerplate -test/units/modules/system/test_known_hosts.py pylint:ansible-bad-function -test/units/modules/system/test_systemd.py future-import-boilerplate -test/units/modules/system/test_systemd.py metaclass-boilerplate -test/units/modules/utils.py future-import-boilerplate -test/units/modules/utils.py metaclass-boilerplate -test/units/parsing/utils/test_addresses.py future-import-boilerplate -test/units/parsing/utils/test_addresses.py metaclass-boilerplate -test/units/parsing/vault/test_vault.py pylint:blacklisted-name -test/units/playbook/role/test_role.py pylint:blacklisted-name -test/units/playbook/test_attribute.py future-import-boilerplate -test/units/playbook/test_attribute.py metaclass-boilerplate -test/units/playbook/test_conditional.py future-import-boilerplate -test/units/playbook/test_conditional.py metaclass-boilerplate -test/units/plugins/inventory/test_constructed.py future-import-boilerplate -test/units/plugins/inventory/test_constructed.py metaclass-boilerplate -test/units/plugins/loader_fixtures/import_fixture.py future-import-boilerplate -test/units/plugins/shell/test_cmd.py future-import-boilerplate -test/units/plugins/shell/test_cmd.py metaclass-boilerplate -test/units/plugins/shell/test_powershell.py future-import-boilerplate -test/units/plugins/shell/test_powershell.py metaclass-boilerplate -test/units/plugins/test_plugins.py pylint:blacklisted-name -test/units/template/test_templar.py pylint:blacklisted-name -test/units/test_constants.py future-import-boilerplate -test/units/test_context.py future-import-boilerplate -test/units/utils/fixtures/collections/ansible_collections/my_namespace/my_collection/plugins/action/my_action.py future-import-boilerplate -test/units/utils/fixtures/collections/ansible_collections/my_namespace/my_collection/plugins/action/my_action.py metaclass-boilerplate -test/units/utils/fixtures/collections/ansible_collections/my_namespace/my_collection/plugins/module_utils/my_other_util.py future-import-boilerplate -test/units/utils/fixtures/collections/ansible_collections/my_namespace/my_collection/plugins/module_utils/my_other_util.py metaclass-boilerplate -test/units/utils/fixtures/collections/ansible_collections/my_namespace/my_collection/plugins/module_utils/my_util.py future-import-boilerplate -test/units/utils/fixtures/collections/ansible_collections/my_namespace/my_collection/plugins/module_utils/my_util.py metaclass-boilerplate -test/units/utils/test_cleanup_tmp_file.py future-import-boilerplate -test/units/utils/test_encrypt.py future-import-boilerplate -test/units/utils/test_encrypt.py metaclass-boilerplate -test/units/utils/test_helpers.py future-import-boilerplate -test/units/utils/test_helpers.py metaclass-boilerplate -test/units/utils/test_shlex.py future-import-boilerplate -test/units/utils/test_shlex.py metaclass-boilerplate -test/utils/shippable/check_matrix.py replace-urlopen -test/utils/shippable/timing.py shebang diff --git a/tests/integration/nios/prepare_nios_tests/tasks/main.yml b/tests/unit/__init__.py similarity index 100% rename from tests/integration/nios/prepare_nios_tests/tasks/main.yml rename to tests/unit/__init__.py diff --git a/tests/integration/targets/incidental_nios_prepare_tests/tasks/main.yml b/tests/unit/compat/__init__.py similarity index 100% rename from tests/integration/targets/incidental_nios_prepare_tests/tasks/main.yml rename to tests/unit/compat/__init__.py diff --git a/tests/unit/compat/mock.py b/tests/unit/compat/mock.py new file mode 100644 index 00000000..ba8455bf --- /dev/null +++ b/tests/unit/compat/mock.py @@ -0,0 +1,120 @@ +# (c) 2014, Toshio Kuratomi +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +''' +Compat module for Python3.x's unittest.mock module +''' +import sys + +# Python 2.7 + +# Note: Could use the pypi mock library on python3.x as well as python2.x. It +# is the same as the python3 stdlib mock library + +try: + # Allow wildcard import because we really do want to import all of mock's + # symbols into this compat shim + # pylint: disable=wildcard-import,unused-wildcard-import + from unittest.mock import * +except ImportError: + # Python 2 + # pylint: disable=wildcard-import,unused-wildcard-import + try: + from mock import * + except ImportError: + print('You need the mock library installed on python2.x to run tests') + + +# Prior to 3.4.4, mock_open cannot handle binary read_data +if sys.version_info >= (3,) and sys.version_info < (3, 4, 4): + file_spec = None + + def _iterate_read_data(read_data): + # Helper for mock_open: + # Retrieve lines from read_data via a generator so that separate calls to + # readline, read, and readlines are properly interleaved + sep = b'\n' if isinstance(read_data, bytes) else '\n' + data_as_list = [l + sep for l in read_data.split(sep)] + + if data_as_list[-1] == sep: + # If the last line ended in a newline, the list comprehension will have an + # extra entry that's just a newline. Remove this. + data_as_list = data_as_list[:-1] + else: + # If there wasn't an extra newline by itself, then the file being + # emulated doesn't have a newline to end the last line remove the + # newline that our naive format() added + data_as_list[-1] = data_as_list[-1][:-1] + + for line in data_as_list: + yield line + + def mock_open(mock=None, read_data=''): + """ + A helper function to create a mock to replace the use of `open`. It works + for `open` called directly or used as a context manager. + The `mock` argument is the mock object to configure. If `None` (the + default) then a `MagicMock` will be created for you, with the API limited + to methods or attributes available on standard file handles. + `read_data` is a string for the `read` methoddline`, and `readlines` of the + file handle to return. This is an empty string by default. + """ + def _readlines_side_effect(*args, **kwargs): + if handle.readlines.return_value is not None: + return handle.readlines.return_value + return list(_data) + + def _read_side_effect(*args, **kwargs): + if handle.read.return_value is not None: + return handle.read.return_value + return type(read_data)().join(_data) + + def _readline_side_effect(): + if handle.readline.return_value is not None: + while True: + yield handle.readline.return_value + for line in _data: + yield line + + global file_spec + if file_spec is None: + import _io + file_spec = list(set(dir(_io.TextIOWrapper)).union(set(dir(_io.BytesIO)))) + + if mock is None: + mock = MagicMock(name='open', spec=open) + + handle = MagicMock(spec=file_spec) + handle.__enter__.return_value = handle + + _data = _iterate_read_data(read_data) + + handle.write.return_value = None + handle.read.return_value = None + handle.readline.return_value = None + handle.readlines.return_value = None + + handle.read.side_effect = _read_side_effect + handle.readline.side_effect = _readline_side_effect() + handle.readlines.side_effect = _readlines_side_effect + + mock.return_value = handle + return mock diff --git a/tests/unit/plugins/__init__.py b/tests/unit/plugins/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/plugins/module_utils/__init__.py b/tests/unit/plugins/module_utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/plugins/module_utils/test_api.py b/tests/unit/plugins/module_utils/test_api.py new file mode 100644 index 00000000..550d1bd7 --- /dev/null +++ b/tests/unit/plugins/module_utils/test_api.py @@ -0,0 +1,255 @@ +# (c) 2018 Red Hat, Inc. +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +import copy + +from ansible_collections.infoblox.nios_modules.tests.unit.compat import unittest +from ansible_collections.infoblox.nios_modules.tests.unit.compat.mock import patch, MagicMock, Mock +from ansible.module_utils.common.validation import check_type_dict +from ansible_collections.infoblox.nios_modules.plugins.module_utils import api + + +class TestNiosApi(unittest.TestCase): + + def setUp(self): + super(TestNiosApi, self).setUp() + + self.module = MagicMock(name='AnsibleModule') + self.module.check_mode = False + self.module.params = {'provider': None} + + self.mock_connector = patch('ansible_collections.infoblox.nios_modules.plugins.module_utils.api.get_connector') + self.mock_connector.start() + self.mock_check_type_dict = patch('ansible.module_utils.common.validation.check_type_dict') + self.mock_check_type_dict_obj = self.mock_check_type_dict.start() + + def tearDown(self): + super(TestNiosApi, self).tearDown() + + self.mock_connector.stop() + self.mock_check_type_dict.stop() + + def test_get_provider_spec(self): + provider_options = ['host', 'username', 'password', 'cert', 'key', 'validate_certs', 'silent_ssl_warnings', + 'http_request_timeout', 'http_pool_connections', + 'http_pool_maxsize', 'max_retries', 'wapi_version', 'max_results'] + res = api.WapiBase.provider_spec + self.assertIsNotNone(res) + self.assertIn('provider', res) + self.assertIn('options', res['provider']) + returned_options = res['provider']['options'] + self.assertEqual(sorted(provider_options), sorted(returned_options.keys())) + + def _get_wapi(self, test_object): + wapi = api.WapiModule(self.module) + wapi.get_object = Mock(name='get_object', return_value=test_object) + wapi.create_object = Mock(name='create_object') + wapi.update_object = Mock(name='update_object') + wapi.delete_object = Mock(name='delete_object') + return wapi + + def test_wapi_no_change(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'default', + 'comment': 'test comment', 'extattrs': None} + + test_object = [ + { + "comment": "test comment", + "_ref": "networkview/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": 'default', + "extattrs": {} + } + ] + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertFalse(res['changed']) + + def test_wapi_change(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'default', + 'comment': 'updated comment', 'extattrs': None} + + test_object = [ + { + "comment": "test comment", + "_ref": "networkview/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": "default", + "extattrs": {} + } + ] + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.update_object.called_once_with(test_object) + + def test_wapi_change_false(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'default', + 'comment': 'updated comment', 'extattrs': None, 'fqdn': 'foo'} + + test_object = [ + { + "comment": "test comment", + "_ref": "networkview/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": "default", + "extattrs": {} + } + ] + + test_spec = { + "name": {"ib_req": True}, + "fqdn": {"ib_req": True, 'update': False}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.update_object.called_once_with(test_object) + + def test_wapi_extattrs_change(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'default', + 'comment': 'test comment', 'extattrs': {'Site': 'update'}} + + ref = "networkview/ZG5zLm5ldHdvcmtfdmlldyQw:default/true" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "name": "default", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + kwargs = copy.deepcopy(test_object[0]) + kwargs['extattrs']['Site']['value'] = 'update' + kwargs['name'] = 'default' + del kwargs['_ref'] + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.update_object.assert_called_once_with(ref, kwargs) + + def test_wapi_extattrs_nochange(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'default', + 'comment': 'test comment', 'extattrs': {'Site': 'test'}} + + test_object = [{ + "comment": "test comment", + "_ref": "networkview/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": "default", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertFalse(res['changed']) + + def test_wapi_create(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'ansible', + 'comment': None, 'extattrs': None} + + test_object = None + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'name': 'ansible'}) + + def test_wapi_delete(self): + self.module.params = {'provider': None, 'state': 'absent', 'name': 'ansible', + 'comment': None, 'extattrs': None} + + ref = "networkview/ZG5zLm5ldHdvcmtfdmlldyQw:ansible/false" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "name": "ansible", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) + + def test_wapi_strip_network_view(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'ansible', + 'comment': 'updated comment', 'extattrs': None, + 'network_view': 'default'} + + test_object = [{ + "comment": "test comment", + "_ref": "view/ZG5zLm5ldHdvcmtfdmlldyQw:ansible/true", + "name": "ansible", + "extattrs": {}, + "network_view": "default" + }] + + test_spec = { + "name": {"ib_req": True}, + "network_view": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + kwargs = test_object[0].copy() + ref = kwargs.pop('_ref') + kwargs['comment'] = 'updated comment' + kwargs['name'] = 'ansible' + del kwargs['network_view'] + del kwargs['extattrs'] + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.update_object.assert_called_once_with(ref, kwargs) diff --git a/tests/unit/plugins/modules/__init__.py b/tests/unit/plugins/modules/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/plugins/modules/fixtures/nios_result.txt b/tests/unit/plugins/modules/fixtures/nios_result.txt new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/plugins/modules/test_nios_a_record.py b/tests/unit/plugins/modules/test_nios_a_record.py new file mode 100644 index 00000000..b8722011 --- /dev/null +++ b/tests/unit/plugins/modules/test_nios_a_record.py @@ -0,0 +1,163 @@ +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish + + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +from ansible_collections.infoblox.nios_modules.plugins.modules import nios_a_record +from ansible_collections.infoblox.nios_modules.plugins.module_utils import api +from ansible_collections.infoblox.nios_modules.tests.unit.compat.mock import patch, MagicMock, Mock +from ansible.module_utils.common.validation import check_type_dict +from .test_nios_module import TestNiosModule, load_fixture + + +class TestNiosARecordModule(TestNiosModule): + + module = nios_a_record + + def setUp(self): + super(TestNiosARecordModule, self).setUp() + self.module = MagicMock(name='ansible_collections.infoblox.nios_modules.plugins.modules.nios_a_record.WapiModule') + self.module.check_mode = False + self.module.params = {'provider': None} + self.mock_wapi = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_a_record.WapiModule') + self.exec_command = self.mock_wapi.start() + self.mock_wapi_run = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_a_record.WapiModule.run') + self.mock_wapi_run.start() + self.load_config = self.mock_wapi_run.start() + self.mock_check_type_dict = patch('ansible.module_utils.common.validation.check_type_dict') + self.mock_check_type_dict_obj = self.mock_check_type_dict.start() + + def tearDown(self): + super(TestNiosARecordModule, self).tearDown() + self.mock_wapi.stop() + self.mock_wapi_run.stop() + self.mock_check_type_dict.stop() + + def _get_wapi(self, test_object): + wapi = api.WapiModule(self.module) + wapi.get_object = Mock(name='get_object', return_value=test_object) + wapi.create_object = Mock(name='create_object') + wapi.update_object = Mock(name='update_object') + wapi.delete_object = Mock(name='delete_object') + return wapi + + def load_fixtures(self, commands=None): + self.exec_command.return_value = (0, load_fixture('nios_result.txt').strip(), None) + self.load_config.return_value = dict(diff=None, session='session') + + def test_nios_a_record_create(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'a.ansible.com', + 'ipv4': '192.168.10.1', 'comment': None, 'extattrs': None} + + test_object = None + + test_spec = { + "name": {"ib_req": True}, + "ipv4": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + print("WAPI: ", wapi.__dict__) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'name': 'a.ansible.com', + 'ipv4': '192.168.10.1'}) + + def test_nios_a_record_update_comment(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'a.ansible.com', 'ipv4': '192.168.10.1', + 'comment': 'updated comment', 'extattrs': None} + + test_object = [ + { + "comment": "test comment", + "_ref": "arecord/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": "a.ansible.com", + "ipv4": "192.168.10.1", + "extattrs": {} + } + ] + + test_spec = { + "name": {"ib_req": True}, + "ipv4": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + + def test_nios_a_record_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'name': 'a.ansible.com', 'ipv4': '192.168.10.1', + 'comment': None, 'extattrs': None} + + ref = "arecord/ZG5zLm5ldHdvcmtfdmlldyQw:default/false" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "name": "a.ansible.com", + "ipv4": "192.168.10.1", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "name": {"ib_req": True}, + "ipv4": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) + + def test_nios_a_record_update_record_name(self): + self.module.params = {'provider': None, 'state': 'present', 'name': {'new_name': 'a_new.ansible.com', 'old_name': 'a.ansible.com'}, + 'comment': 'comment', 'extattrs': None} + + test_object = [ + { + "comment": "test comment", + "_ref": "arecord/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": "a_new.ansible.com", + "old_name": "a.ansible.com", + "extattrs": {} + } + ] + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.update_object.called_once_with(test_object) diff --git a/tests/unit/plugins/modules/test_nios_aaaa_record.py b/tests/unit/plugins/modules/test_nios_aaaa_record.py new file mode 100644 index 00000000..9bfa1c5f --- /dev/null +++ b/tests/unit/plugins/modules/test_nios_aaaa_record.py @@ -0,0 +1,163 @@ +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish + + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +from ansible_collections.infoblox.nios_modules.plugins.modules import nios_aaaa_record +from ansible_collections.infoblox.nios_modules.plugins.module_utils import api +from ansible_collections.infoblox.nios_modules.tests.unit.compat.mock import patch, MagicMock, Mock +from ansible.module_utils.common.validation import check_type_dict +from .test_nios_module import TestNiosModule, load_fixture + + +class TestNiosAAAARecordModule(TestNiosModule): + + module = nios_aaaa_record + + def setUp(self): + super(TestNiosAAAARecordModule, self).setUp() + self.module = MagicMock(name='ansible_collections.infoblox.nios_modules.plugins.modules.nios_aaaa_record.WapiModule') + self.module.check_mode = False + self.module.params = {'provider': None} + self.mock_wapi = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_aaaa_record.WapiModule') + self.exec_command = self.mock_wapi.start() + self.mock_wapi_run = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_aaaa_record.WapiModule.run') + self.mock_wapi_run.start() + self.load_config = self.mock_wapi_run.start() + self.mock_check_type_dict = patch('ansible.module_utils.common.validation.check_type_dict') + self.mock_check_type_dict_obj = self.mock_check_type_dict.start() + + def tearDown(self): + super(TestNiosAAAARecordModule, self).tearDown() + self.mock_wapi.stop() + self.mock_wapi_run.stop() + self.mock_check_type_dict.stop() + + def _get_wapi(self, test_object): + wapi = api.WapiModule(self.module) + wapi.get_object = Mock(name='get_object', return_value=test_object) + wapi.create_object = Mock(name='create_object') + wapi.update_object = Mock(name='update_object') + wapi.delete_object = Mock(name='delete_object') + return wapi + + def load_fixtures(self, commands=None): + self.exec_command.return_value = (0, load_fixture('nios_result.txt').strip(), None) + self.load_config.return_value = dict(diff=None, session='session') + + def test_nios_aaaa_record_create(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'aaaa.ansible.com', + 'ipv6': '2001:0db8:85a3:0000:0000:8a2e:0370:7334', 'comment': None, 'extattrs': None} + + test_object = None + + test_spec = { + "name": {"ib_req": True}, + "ipv6": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + print("WAPI: ", wapi.__dict__) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'name': 'aaaa.ansible.com', + 'ipv6': '2001:0db8:85a3:0000:0000:8a2e:0370:7334'}) + + def test_nios_aaaa_record_update_comment(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'aaaa.ansible.com', + 'ipv6': '2001:0db8:85a3:0000:0000:8a2e:0370:7334', 'comment': 'updated comment', 'extattrs': None} + + test_object = [ + { + "comment": "test comment", + "_ref": "aaaarecord/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": "aaaa.ansible.com", + "ipv6": "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + "extattrs": {} + } + ] + + test_spec = { + "name": {"ib_req": True}, + "ipv6": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + + def test_nios_aaaa_record_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'name': 'aaaa.ansible.com', + 'ipv6': '2001:0db8:85a3:0000:0000:8a2e:0370:7334', 'comment': None, 'extattrs': None} + + ref = "aaaarecord/ZG5zLm5ldHdvcmtfdmlldyQw:default/false" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "name": "aaaa.ansible.com", + "ipv6": "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "name": {"ib_req": True}, + "ipv6": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) + + def test_nios_aaaa_record_update_record_name(self): + self.module.params = {'provider': None, 'state': 'present', 'name': {'new_name': 'aaaa_new.ansible.com', 'old_name': 'aaaa.ansible.com'}, + 'comment': 'comment', 'extattrs': None} + + test_object = [ + { + "comment": "test comment", + "_ref": "aaaarecord/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": "aaaa_new.ansible.com", + "old_name": "aaaa.ansible.com", + "extattrs": {} + } + ] + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.update_object.called_once_with(test_object) diff --git a/tests/unit/plugins/modules/test_nios_cname_record.py b/tests/unit/plugins/modules/test_nios_cname_record.py new file mode 100644 index 00000000..3df06300 --- /dev/null +++ b/tests/unit/plugins/modules/test_nios_cname_record.py @@ -0,0 +1,137 @@ +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish + + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +from ansible_collections.infoblox.nios_modules.plugins.modules import nios_cname_record +from ansible_collections.infoblox.nios_modules.plugins.module_utils import api +from ansible_collections.infoblox.nios_modules.tests.unit.compat.mock import patch, MagicMock, Mock +from ansible.module_utils.common.validation import check_type_dict +from .test_nios_module import TestNiosModule, load_fixture + + +class TestNiosCNameRecordModule(TestNiosModule): + + module = nios_cname_record + + def setUp(self): + super(TestNiosCNameRecordModule, self).setUp() + self.module = MagicMock(name='ansible_collections.infoblox.nios_modules.plugins.modules.nios_cname_record.WapiModule') + self.module.check_mode = False + self.module.params = {'provider': None} + self.mock_wapi = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_cname_record.WapiModule') + self.exec_command = self.mock_wapi.start() + self.mock_wapi_run = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_cname_record.WapiModule.run') + self.mock_wapi_run.start() + self.load_config = self.mock_wapi_run.start() + self.mock_check_type_dict = patch('ansible.module_utils.common.validation.check_type_dict') + self.mock_check_type_dict_obj = self.mock_check_type_dict.start() + + def tearDown(self): + super(TestNiosCNameRecordModule, self).tearDown() + self.mock_wapi.stop() + self.mock_wapi_run.stop() + self.mock_check_type_dict.stop() + + def _get_wapi(self, test_object): + wapi = api.WapiModule(self.module) + wapi.get_object = Mock(name='get_object', return_value=test_object) + wapi.create_object = Mock(name='create_object') + wapi.update_object = Mock(name='update_object') + wapi.delete_object = Mock(name='delete_object') + return wapi + + def load_fixtures(self, commands=None): + self.exec_command.return_value = (0, load_fixture('nios_result.txt').strip(), None) + self.load_config.return_value = dict(diff=None, session='session') + + def test_nios_cname_record_create(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'cname.ansible.com', + 'canonical': 'realhost.ansible.com', 'comment': None, 'extattrs': None} + + test_object = None + + test_spec = { + "name": {"ib_req": True}, + "canonical": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + print("WAPI: ", wapi.__dict__) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'name': 'cname.ansible.com', + 'canonical': 'realhost.ansible.com'}) + + def test_nios_cname_record_update_comment(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'cname.ansible.com', + 'canonical': 'realhost.ansible.com', 'comment': 'updated comment', 'extattrs': None} + + test_object = [ + { + "comment": "test comment", + "_ref": "cnamerecord/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": "cname.ansible.com", + "canonical": "realhost.ansible.com", + "extattrs": {} + } + ] + + test_spec = { + "name": {"ib_req": True}, + "canonical": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + + def test_nios_cname_record_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'name': 'cname.ansible.com', + 'canonical': 'realhost.ansible.com', 'comment': None, 'extattrs': None} + + ref = "cnamerecord/ZG5zLm5ldHdvcmtfdmlldyQw:default/false" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "name": "cname.ansible.com", + "canonical": "realhost.ansible.com", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "name": {"ib_req": True}, + "canonical": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) diff --git a/tests/unit/plugins/modules/test_nios_dns_view.py b/tests/unit/plugins/modules/test_nios_dns_view.py new file mode 100644 index 00000000..a59f50f5 --- /dev/null +++ b/tests/unit/plugins/modules/test_nios_dns_view.py @@ -0,0 +1,131 @@ +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish + + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +from ansible_collections.infoblox.nios_modules.plugins.modules import nios_dns_view +from ansible_collections.infoblox.nios_modules.plugins.module_utils import api +from ansible_collections.infoblox.nios_modules.tests.unit.compat.mock import patch, MagicMock, Mock +from ansible.module_utils.common.validation import check_type_dict +from .test_nios_module import TestNiosModule, load_fixture + + +class TestNiosDnsViewModule(TestNiosModule): + + module = nios_dns_view + + def setUp(self): + super(TestNiosDnsViewModule, self).setUp() + self.module = MagicMock(name='ansible_collections.infoblox.nios_modules.plugins.modules.nios_dns_view.WapiModule') + self.module.check_mode = False + self.module.params = {'provider': None} + self.mock_wapi = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_dns_view.WapiModule') + self.exec_command = self.mock_wapi.start() + self.mock_wapi_run = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_dns_view.WapiModule.run') + self.mock_wapi_run.start() + self.load_config = self.mock_wapi_run.start() + self.mock_check_type_dict = patch('ansible.module_utils.common.validation.check_type_dict') + self.mock_check_type_dict_obj = self.mock_check_type_dict.start() + + def tearDown(self): + super(TestNiosDnsViewModule, self).tearDown() + self.mock_wapi.stop() + self.mock_wapi_run.stop() + self.mock_check_type_dict.stop() + + def _get_wapi(self, test_object): + wapi = api.WapiModule(self.module) + wapi.get_object = Mock(name='get_object', return_value=test_object) + wapi.create_object = Mock(name='create_object') + wapi.update_object = Mock(name='update_object') + wapi.delete_object = Mock(name='delete_object') + return wapi + + def load_fixtures(self, commands=None): + self.exec_command.return_value = (0, load_fixture('nios_result.txt').strip(), None) + self.load_config.return_value = dict(diff=None, session='session') + + def test_nios_dns_view_create(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'ansible-dns', + 'comment': None, 'extattrs': None} + + test_object = None + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + print("WAPI: ", wapi) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'name': 'ansible-dns'}) + + def test_nios_dns_view_update_comment(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'ansible-dns', + 'comment': 'updated comment', 'extattrs': None} + + test_object = [ + { + "comment": "test comment", + "_ref": "dnsview/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": "ansible-dns", + "extattrs": {} + } + ] + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + + def test_nios_dns_view_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'name': 'ansible-dns', + 'comment': None, 'extattrs': None} + + ref = "dnsview/ZG5zLm5ldHdvcmtfdmlldyQw:ansible/false" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "name": "ansible-dns", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) diff --git a/tests/unit/plugins/modules/test_nios_fixed_address.py b/tests/unit/plugins/modules/test_nios_fixed_address.py new file mode 100644 index 00000000..ae373fd3 --- /dev/null +++ b/tests/unit/plugins/modules/test_nios_fixed_address.py @@ -0,0 +1,201 @@ +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +from ansible_collections.infoblox.nios_modules.plugins.modules import nios_fixed_address +from ansible_collections.infoblox.nios_modules.plugins.module_utils import api +from ansible_collections.infoblox.nios_modules.tests.unit.compat.mock import patch, MagicMock, Mock +from .test_nios_module import TestNiosModule, load_fixture + + +class TestNiosFixedAddressModule(TestNiosModule): + + module = nios_fixed_address + + def setUp(self): + super(TestNiosFixedAddressModule, self).setUp() + self.module = MagicMock(name='ansible_collections.infoblox.nios_modules.plugins.modules.nios_fixed_address.WapiModule') + self.module.check_mode = False + self.module.params = {'provider': None} + self.mock_wapi = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_fixed_address.WapiModule') + self.exec_command = self.mock_wapi.start() + self.mock_wapi_run = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_fixed_address.WapiModule.run') + self.mock_wapi_run.start() + self.load_config = self.mock_wapi_run.start() + + def tearDown(self): + super(TestNiosFixedAddressModule, self).tearDown() + self.mock_wapi.stop() + self.mock_wapi_run.stop() + + def load_fixtures(self, commands=None): + self.exec_command.return_value = (0, load_fixture('nios_result.txt').strip(), None) + self.load_config.return_value = dict(diff=None, session='session') + + def _get_wapi(self, test_object): + wapi = api.WapiModule(self.module) + wapi.get_object = Mock(name='get_object', return_value=test_object) + wapi.create_object = Mock(name='create_object') + wapi.update_object = Mock(name='update_object') + wapi.delete_object = Mock(name='delete_object') + return wapi + + def test_nios_fixed_address_ipv4_create(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'test_fa', 'ipaddr': '192.168.10.1', 'mac': '08:6d:41:e8:fd:e8', + 'network': '192.168.10.0/24', 'network_view': 'default', 'comment': None, 'extattrs': None} + + test_object = None + test_spec = { + "name": {}, + "ipaddr": {"ib_req": True}, + "mac": {"ib_req": True}, + "network": {"ib_req": True}, + "network_view": {}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'name': 'test_fa', 'ipaddr': '192.168.10.1', 'mac': '08:6d:41:e8:fd:e8', + 'network': '192.168.10.0/24', 'network_view': 'default'}) + + def test_nios_fixed_address_ipv4_dhcp_update(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'test_fa', 'ipaddr': '192.168.10.1', 'mac': '08:6d:41:e8:fd:e8', + 'network': '192.168.10.0/24', 'network_view': 'default', 'comment': 'updated comment', 'extattrs': None} + + test_object = [ + { + "comment": "test comment", + "name": "test_fa", + "_ref": "network/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "ipaddr": "192.168.10.1", + "mac": "08:6d:41:e8:fd:e8", + "network": "192.168.10.0/24", + "network_view": "default", + "extattrs": {'options': {'name': 'test', 'value': 'ansible.com'}} + } + ] + + test_spec = { + "name": {}, + "ipaddr": {"ib_req": True}, + "mac": {"ib_req": True}, + "network": {"ib_req": True}, + "network_view": {}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + + def test_nios_fixed_address_ipv4_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'name': 'test_fa', 'ipaddr': '192.168.10.1', 'mac': '08:6d:41:e8:fd:e8', + 'network': '192.168.10.0/24', 'network_view': 'default', 'comment': None, 'extattrs': None} + + ref = "fixedaddress/ZG5zLm5ldHdvcmtfdmlldyQw:ansible/false" + + test_object = [{ + "comment": "test comment", + "name": "test_fa", + "_ref": ref, + "ipaddr": "192.168.10.1", + "mac": "08:6d:41:e8:fd:e8", + "network": "192.168.10.0/24", + "network_view": "default", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "name": {}, + "ipaddr": {"ib_req": True}, + "mac": {"ib_req": True}, + "network": {"ib_req": True}, + "network_view": {}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) + + def test_nios_fixed_address_ipv6_create(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'test_fa', 'ipaddr': 'fe80::1/10', 'mac': '08:6d:41:e8:fd:e8', + 'network': 'fe80::/64', 'network_view': 'default', 'comment': None, 'extattrs': None} + + test_object = None + + test_spec = { + "name": {}, + "ipaddr": {"ib_req": True}, + "mac": {"ib_req": True}, + "network": {"ib_req": True}, + "network_view": {}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + print("WAPI: ", wapi) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'name': 'test_fa', 'ipaddr': 'fe80::1/10', 'mac': '08:6d:41:e8:fd:e8', + 'network': 'fe80::/64', 'network_view': 'default'}) + + def test_nios_fixed_address_ipv6_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'name': 'test_fa', 'ipaddr': 'fe80::1/10', 'mac': '08:6d:41:e8:fd:e8', + 'network': 'fe80::/64', 'network_view': 'default', 'comment': None, 'extattrs': None} + + ref = "ipv6fixedaddress/ZG5zLm5ldHdvcmtfdmlldyQw:ansible/false" + + test_object = [{ + "comment": "test comment", + "name": "test_fa", + "_ref": ref, + "ipaddr": "fe80::1/10", + "mac": "08:6d:41:e8:fd:e8", + "network": "fe80::/64", + "network_view": "default", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "name": {}, + "ipaddr": {"ib_req": True}, + "mac": {"ib_req": True}, + "network": {"ib_req": True}, + "network_view": {}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) diff --git a/tests/unit/plugins/modules/test_nios_host_record.py b/tests/unit/plugins/modules/test_nios_host_record.py new file mode 100644 index 00000000..11489960 --- /dev/null +++ b/tests/unit/plugins/modules/test_nios_host_record.py @@ -0,0 +1,156 @@ +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +from ansible_collections.infoblox.nios_modules.plugins.modules import nios_host_record +from ansible_collections.infoblox.nios_modules.plugins.module_utils import api +from ansible_collections.infoblox.nios_modules.tests.unit.compat.mock import patch, MagicMock, Mock +from ansible.module_utils.common.validation import check_type_dict +from .test_nios_module import TestNiosModule, load_fixture + + +class TestNiosHostRecordModule(TestNiosModule): + + module = nios_host_record + + def setUp(self): + + super(TestNiosHostRecordModule, self).setUp() + self.module = MagicMock(name='ansible_collections.infoblox.nios_modules.plugins.modules.nios_host_record.WapiModule') + self.module.check_mode = False + self.module.params = {'provider': None} + + self.mock_wapi = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_host_record.WapiModule') + self.exec_command = self.mock_wapi.start() + self.mock_wapi_run = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_host_record.WapiModule.run') + self.mock_wapi_run.start() + + self.load_config = self.mock_wapi_run.start() + self.mock_check_type_dict = patch('ansible.module_utils.common.validation.check_type_dict') + self.mock_check_type_dict_obj = self.mock_check_type_dict.start() + + def tearDown(self): + super(TestNiosHostRecordModule, self).tearDown() + self.mock_wapi.stop() + self.mock_check_type_dict.stop() + + def _get_wapi(self, test_object): + wapi = api.WapiModule(self.module) + wapi.get_object = Mock(name='get_object', return_value=test_object) + wapi.create_object = Mock(name='create_object') + wapi.update_object = Mock(name='update_object') + wapi.delete_object = Mock(name='delete_object') + return wapi + + def load_fixtures(self, commands=None): + self.exec_command.return_value = (0, load_fixture('nios_result.txt').strip(), None) + self.load_config.return_value = dict(diff=None, session='session') + + def test_nios_host_record_create(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'ansible', + 'comment': None, 'extattrs': None} + + test_object = None + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + print("WAPI: ", wapi) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'name': 'ansible'}) + + def test_nios_host_record_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'name': 'ansible', + 'comment': None, 'extattrs': None} + + ref = "record:host/ZG5zLm5ldHdvcmtfdmlldyQw:ansible/false" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "name": "ansible", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) + + def test_nios_host_record_update_comment(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'default', + 'comment': 'updated comment', 'extattrs': None} + + test_object = [ + { + "comment": "test comment", + "_ref": "record:host/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": "default", + "extattrs": {} + } + ] + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.update_object.called_once_with(test_object) + + def test_nios_host_record_update_record_name(self): + self.module.params = {'provider': None, 'state': 'present', 'name': {'new_name': 'default', 'old_name': 'old_default'}, + 'comment': 'comment', 'extattrs': None} + + test_object = [ + { + "comment": "test comment", + "_ref": "record:host/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": "default", + "old_name": "old_default", + "extattrs": {} + } + ] + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.update_object.called_once_with(test_object) diff --git a/tests/unit/plugins/modules/test_nios_member.py b/tests/unit/plugins/modules/test_nios_member.py new file mode 100644 index 00000000..a65b5df1 --- /dev/null +++ b/tests/unit/plugins/modules/test_nios_member.py @@ -0,0 +1,162 @@ +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +from ansible_collections.infoblox.nios_modules.plugins.modules import nios_member +from ansible_collections.infoblox.nios_modules.plugins.module_utils import api +from ansible_collections.infoblox.nios_modules.tests.unit.compat.mock import patch, MagicMock, Mock +from .test_nios_module import TestNiosModule, load_fixture + + +class TestNiosMemberModule(TestNiosModule): + + module = nios_member + + def setUp(self): + super(TestNiosMemberModule, self).setUp() + self.module = MagicMock(name='ansible_collections.infoblox.nios_modules.plugins.modules.nios_member.WapiModule') + self.module.check_mode = False + self.module.params = {'provider': None} + self.mock_wapi = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_member.WapiModule') + self.exec_command = self.mock_wapi.start() + self.mock_wapi_run = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_member.WapiModule.run') + self.mock_wapi_run.start() + self.load_config = self.mock_wapi_run.start() + + def tearDown(self): + super(TestNiosMemberModule, self).tearDown() + self.mock_wapi.stop() + self.mock_wapi_run.stop() + + def load_fixtures(self, commands=None): + self.exec_command.return_value = (0, load_fixture('nios_result.txt').strip(), None) + self.load_config.return_value = dict(diff=None, session='session') + + def _get_wapi(self, test_object): + wapi = api.WapiModule(self.module) + wapi.get_object = Mock(name='get_object', return_value=test_object) + wapi.create_object = Mock(name='create_object') + wapi.update_object = Mock(name='update_object') + wapi.delete_object = Mock(name='delete_object') + return wapi + + def test_nios_member_create(self): + self.module.params = {'provider': None, 'state': 'present', 'host_name': 'test_member', + 'vip_setting': {'address': '192.168.1.110', 'subnet_mask': '255.255.255.0', 'gateway': '192.168.1.1'}, + 'config_addr_type': 'IPV4', 'platform': 'VNIOS', 'comment': None, 'extattrs': None} + + test_object = None + test_spec = { + "host_name": {"ib_req": True}, + "vip_setting": {}, + "config_addr_type": {}, + "platform": {}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'host_name': 'test_member', + 'vip_setting': {'address': '192.168.1.110', 'subnet_mask': '255.255.255.0', + 'gateway': '192.168.1.1'}, + 'config_addr_type': 'IPV4', 'platform': 'VNIOS'}) + + def test_nios_member_update(self): + self.module.params = {'provider': None, 'state': 'present', 'host_name': 'test_member', + 'vip_setting': {'address': '192.168.1.110', 'subnet_mask': '255.255.255.0', 'gateway': '192.168.1.1'}, + 'config_addr_type': 'IPV4', 'platform': 'VNIOS', 'comment': 'updated comment', 'extattrs': None} + + test_object = [ + { + "comment": "Created with Ansible", + "_ref": "member/b25lLnZpcnR1YWxfbm9kZSQ3:member01.ansible-dev.com", + "config_addr_type": "IPV4", + "host_name": "member01.ansible-dev.com", + "platform": "VNIOS", + "service_type_configuration": "ALL_V4", + "vip_setting": + { + "address": "192.168.1.100", + "dscp": 0, + "gateway": "192.168.1.1", + "primary": True, + "subnet_mask": "255.255.255.0", + "use_dscp": False + } + } + ] + + test_spec = { + "host_name": {"ib_req": True}, + "vip_setting": {}, + "config_addr_type": {}, + "platform": {}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + + def test_nios_member_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'host_name': 'test_member', + 'vip_setting': {'address': '192.168.1.110', 'subnet_mask': '255.255.255.0', 'gateway': '192.168.1.1'}, + 'config_addr_type': 'IPV4', 'platform': 'VNIOS', 'comment': 'updated comment', 'extattrs': None} + + ref = "member/b25lLnZpcnR1YWxfbm9kZSQ3:member01.ansible-dev.com" + + test_object = [ + { + "comment": "Created with Ansible", + "_ref": "member/b25lLnZpcnR1YWxfbm9kZSQ3:member01.ansible-dev.com", + "config_addr_type": "IPV4", + "host_name": "member01.ansible-dev.com", + "platform": "VNIOS", + "service_type_configuration": "ALL_V4", + "vip_setting": + { + "address": "192.168.1.100", + "dscp": 0, + "gateway": "192.168.1.1", + "primary": True, + "subnet_mask": "255.255.255.0", + "use_dscp": False + } + } + ] + + test_spec = { + "host_name": {"ib_req": True}, + "vip_setting": {}, + "config_addr_type": {}, + "platform": {}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) diff --git a/tests/unit/plugins/modules/test_nios_module.py b/tests/unit/plugins/modules/test_nios_module.py new file mode 100644 index 00000000..6ffaa1f7 --- /dev/null +++ b/tests/unit/plugins/modules/test_nios_module.py @@ -0,0 +1,88 @@ +# (c) 2018 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import json + +from ansible_collections.infoblox.nios_modules.tests.unit.plugins.modules.utils import AnsibleExitJson, AnsibleFailJson, ModuleTestCase + + +fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures') +fixture_data = {} + + +def load_fixture(name): + path = os.path.join(fixture_path, name) + + if path in fixture_data: + return fixture_data[path] + + with open(path) as f: + data = f.read() + + try: + data = json.loads(data) + except Exception: + pass + + fixture_data[path] = data + return data + + +class TestNiosModule(ModuleTestCase): + + def execute_module(self, failed=False, changed=False, commands=None, sort=True, defaults=False): + + self.load_fixtures(commands) + + if failed: + result = self.failed() + self.assertTrue(result['failed'], result) + else: + result = self.changed(changed) + self.assertEqual(result['changed'], changed, result) + + if commands is not None: + if sort: + self.assertEqual(sorted(commands), sorted(result['commands']), result['commands']) + else: + self.assertEqual(commands, result['commands'], result['commands']) + + return result + + def failed(self): + with self.assertRaises(AnsibleFailJson) as exc: + self.module.main() + + result = exc.exception.args[0] + self.assertTrue(result['failed'], result) + return result + + def changed(self, changed=False): + with self.assertRaises(AnsibleExitJson) as exc: + self.module.main() + + result = exc.exception.args[0] + self.assertEqual(result['changed'], changed, result) + return result + + def load_fixtures(self, commands=None): + pass diff --git a/tests/unit/plugins/modules/test_nios_mx_record.py b/tests/unit/plugins/modules/test_nios_mx_record.py new file mode 100644 index 00000000..e28cd0e1 --- /dev/null +++ b/tests/unit/plugins/modules/test_nios_mx_record.py @@ -0,0 +1,141 @@ +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish + + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +from ansible_collections.infoblox.nios_modules.plugins.modules import nios_mx_record +from ansible_collections.infoblox.nios_modules.plugins.module_utils import api +from ansible_collections.infoblox.nios_modules.tests.unit.compat.mock import patch, MagicMock, Mock +from ansible.module_utils.common.validation import check_type_dict +from .test_nios_module import TestNiosModule, load_fixture + + +class TestNiosMXRecordModule(TestNiosModule): + + module = nios_mx_record + + def setUp(self): + super(TestNiosMXRecordModule, self).setUp() + self.module = MagicMock(name='ansible_collections.infoblox.nios_modules.plugins.modules.nios_mx_record.WapiModule') + self.module.check_mode = False + self.module.params = {'provider': None} + self.mock_wapi = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_mx_record.WapiModule') + self.exec_command = self.mock_wapi.start() + self.mock_wapi_run = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_mx_record.WapiModule.run') + self.mock_wapi_run.start() + self.load_config = self.mock_wapi_run.start() + self.mock_check_type_dict = patch('ansible.module_utils.common.validation.check_type_dict') + self.mock_check_type_dict_obj = self.mock_check_type_dict.start() + + def tearDown(self): + super(TestNiosMXRecordModule, self).tearDown() + self.mock_wapi.stop() + self.mock_wapi_run.stop() + self.mock_check_type_dict.stop() + + def _get_wapi(self, test_object): + wapi = api.WapiModule(self.module) + wapi.get_object = Mock(name='get_object', return_value=test_object) + wapi.create_object = Mock(name='create_object') + wapi.update_object = Mock(name='update_object') + wapi.delete_object = Mock(name='delete_object') + return wapi + + def load_fixtures(self, commands=None): + self.exec_command.return_value = (0, load_fixture('nios_result.txt').strip(), None) + self.load_config.return_value = dict(diff=None, session='session') + + def test_nios_mx_record_create(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'ansible.com', + 'mx': 'mailhost.ansible.com', 'preference': 0, 'comment': None, 'extattrs': None} + + test_object = None + + test_spec = { + "name": {"ib_req": True}, + "mx": {"ib_req": True}, + "preference": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + print("WAPI: ", wapi) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'name': 'ansible.com', + 'mx': 'mailhost.ansible.com', 'preference': 0}) + + def test_nios_mx_record_update_comment(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'ansible.com', 'mx': 'mailhost.ansible.com', + 'preference': 0, 'comment': 'updated comment', 'extattrs': None} + + test_object = [ + { + "comment": "test comment", + "_ref": "mxrecord/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": "ansible.com", + "mx": "mailhost.ansible.com", + "preference": 0, + "extattrs": {} + } + ] + + test_spec = { + "name": {"ib_req": True}, + "mx": {"ib_req": True}, + "preference": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + + def test_nios_mx_record_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'name': 'ansible.com', 'mx': 'mailhost.ansible.com', + 'preference': 0, 'comment': None, 'extattrs': None} + + ref = "mxrecord/ZG5zLm5ldHdvcmtfdmlldyQw:default/false" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "name": "ansible.com", + "mx": "mailhost.ansible.com", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "name": {"ib_req": True}, + "mx": {"ib_req": True}, + "preference": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) diff --git a/tests/unit/plugins/modules/test_nios_naptr_record.py b/tests/unit/plugins/modules/test_nios_naptr_record.py new file mode 100644 index 00000000..a546a90a --- /dev/null +++ b/tests/unit/plugins/modules/test_nios_naptr_record.py @@ -0,0 +1,151 @@ +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish + + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +from ansible_collections.infoblox.nios_modules.plugins.modules import nios_naptr_record +from ansible_collections.infoblox.nios_modules.plugins.module_utils import api +from ansible_collections.infoblox.nios_modules.tests.unit.compat.mock import patch, MagicMock, Mock +from ansible.module_utils.common.validation import check_type_dict +from .test_nios_module import TestNiosModule, load_fixture + + +class TestNiosNAPTRRecordModule(TestNiosModule): + + module = nios_naptr_record + + def setUp(self): + super(TestNiosNAPTRRecordModule, self).setUp() + self.module = MagicMock(name='ansible_collections.infoblox.nios_modules.plugins.modules.nios_naptr_record.WapiModule') + self.module.check_mode = False + self.module.params = {'provider': None} + self.mock_wapi = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_naptr_record.WapiModule') + self.exec_command = self.mock_wapi.start() + self.mock_wapi_run = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_naptr_record.WapiModule.run') + self.mock_wapi_run.start() + self.load_config = self.mock_wapi_run.start() + self.mock_check_type_dict = patch('ansible.module_utils.common.validation.check_type_dict') + self.mock_check_type_dict_obj = self.mock_check_type_dict.start() + + def tearDown(self): + super(TestNiosNAPTRRecordModule, self).tearDown() + self.mock_wapi.stop() + self.mock_wapi_run.stop() + self.mock_check_type_dict.stop() + + def _get_wapi(self, test_object): + wapi = api.WapiModule(self.module) + wapi.get_object = Mock(name='get_object', return_value=test_object) + wapi.create_object = Mock(name='create_object') + wapi.update_object = Mock(name='update_object') + wapi.delete_object = Mock(name='delete_object') + return wapi + + def load_fixtures(self, commands=None): + self.exec_command.return_value = (0, load_fixture('nios_result.txt').strip(), None) + self.load_config.return_value = dict(diff=None, session='session') + + def test_nios_naptr_record_create(self): + self.module.params = {'provider': None, 'state': 'present', 'name': '*.subscriber-100.ansiblezone.com', + 'order': '1000', 'preference': '10', 'replacement': 'replacement1.network.ansiblezone.com', + 'comment': None, 'extattrs': None} + + test_object = None + + test_spec = { + "name": {"ib_req": True}, + "order": {"ib_req": True}, + "preference": {"ib_req": True}, + "replacement": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + print("WAPI: ", wapi.__dict__) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'name': '*.subscriber-100.ansiblezone.com', + 'order': '1000', 'preference': '10', + 'replacement': 'replacement1.network.ansiblezone.com'}) + + def test_nios_naptr_record_update_comment(self): + self.module.params = {'provider': None, 'state': 'present', 'name': '*.subscriber-100.ansiblezone.com', + 'order': '1000', 'preference': '10', 'replacement': 'replacement1.network.ansiblezone.com', + 'comment': 'updated comment', 'extattrs': None} + + test_object = [ + { + "comment": "test comment", + "_ref": "naptrrecord/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": "*.subscriber-100.ansiblezone.com", + "order": "1000", + "preference": "10", + "replacement": "replacement1.network.ansiblezone.com", + "extattrs": {} + } + ] + + test_spec = { + "name": {"ib_req": True}, + "order": {"ib_req": True}, + "preference": {"ib_req": True}, + "replacement": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + + def test_nios_naptr_record_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'name': '*.subscriber-100.ansiblezone.com', + 'order': '1000', 'preference': '10', 'replacement': 'replacement1.network.ansiblezone.com', + 'comment': None, 'extattrs': None} + + ref = "naptrrecord/ZG5zLm5ldHdvcmtfdmlldyQw:default/false" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "name": "*.subscriber-100.ansiblezone.com", + "order": "1000", + "preference": "10", + "replacement": "replacement1.network.ansiblezone.com", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "name": {"ib_req": True}, + "order": {"ib_req": True}, + "preference": {"ib_req": True}, + "replacement": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) diff --git a/tests/unit/plugins/modules/test_nios_network.py b/tests/unit/plugins/modules/test_nios_network.py new file mode 100644 index 00000000..0fad5aaa --- /dev/null +++ b/tests/unit/plugins/modules/test_nios_network.py @@ -0,0 +1,248 @@ +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +from ansible_collections.infoblox.nios_modules.plugins.modules import nios_network +from ansible_collections.infoblox.nios_modules.plugins.module_utils import api +from ansible_collections.infoblox.nios_modules.tests.unit.compat.mock import patch, MagicMock, Mock +from .test_nios_module import TestNiosModule, load_fixture + + +class TestNiosNetworkModule(TestNiosModule): + + module = nios_network + + def setUp(self): + super(TestNiosNetworkModule, self).setUp() + self.module = MagicMock(name='ansible_collections.infoblox.nios_modules.plugins.modules.nios_network.WapiModule') + self.module.check_mode = False + self.module.params = {'provider': None} + self.mock_wapi = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_network.WapiModule') + self.exec_command = self.mock_wapi.start() + self.mock_wapi_run = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_network.WapiModule.run') + self.mock_wapi_run.start() + self.load_config = self.mock_wapi_run.start() + + def tearDown(self): + super(TestNiosNetworkModule, self).tearDown() + self.mock_wapi.stop() + self.mock_wapi_run.stop() + + def load_fixtures(self, commands=None): + self.exec_command.return_value = (0, load_fixture('nios_result.txt').strip(), None) + self.load_config.return_value = dict(diff=None, session='session') + + def _get_wapi(self, test_object): + wapi = api.WapiModule(self.module) + wapi.get_object = Mock(name='get_object', return_value=test_object) + wapi.create_object = Mock(name='create_object') + wapi.update_object = Mock(name='update_object') + wapi.delete_object = Mock(name='delete_object') + return wapi + + def test_nios_network_ipv4_create(self): + self.module.params = {'provider': None, 'state': 'present', 'network': '192.168.10.0/24', + 'comment': None, 'extattrs': None} + + test_object = None + test_spec = { + "network": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + print("WAPI: ", wapi) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'network': '192.168.10.0/24'}) + + def test_nios_network_ipv4_dhcp_update(self): + self.module.params = {'provider': None, 'state': 'present', 'network': '192.168.10.0/24', + 'comment': 'updated comment', 'extattrs': None} + + test_object = [ + { + "comment": "test comment", + "_ref": "network/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "network": "192.168.10.0/24", + "extattrs": {'options': {'name': 'test', 'value': 'ansible.com'}} + } + ] + + test_spec = { + "network": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + + def test_nios_network_ipv6_dhcp_update(self): + self.module.params = {'provider': None, 'state': 'present', 'ipv6network': 'fe80::/64', + 'comment': 'updated comment', 'extattrs': None} + + test_object = [ + { + "comment": "test comment", + "_ref": "ipv6network/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "ipv6network": "fe80::/64", + "extattrs": {'options': {'name': 'test', 'value': 'ansible.com'}} + } + ] + + test_spec = { + "ipv6network": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + self.assertTrue(res['changed']) + + def test_nios_network_ipv4_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'network': '192.168.10.0/24', + 'comment': None, 'extattrs': None} + + ref = "network/ZG5zLm5ldHdvcmtfdmlldyQw:ansible/false" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "network": "192.168.10.0/24", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "network": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) + + def test_nios_network_ipv6_create(self): + self.module.params = {'provider': None, 'state': 'present', 'ipv6network': 'fe80::/64', + 'comment': None, 'extattrs': None} + + test_object = None + + test_spec = { + "ipv6network": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'ipv6network': 'fe80::/64'}) + + def test_nios_network_ipv6_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'ipv6network': 'fe80::/64', + 'comment': None, 'extattrs': None} + + ref = "ipv6network/ZG5zLm5ldHdvcmtfdmlldyQw:ansible/false" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "ipv6network": "fe80::/64", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "ipv6network": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) + + def test_nios_networkcontainer_ipv4_create(self): + self.module.params = {'provider': None, 'state': 'present', 'networkcontainer': '192.168.10.0/24', + 'comment': None, 'extattrs': None} + + test_object = None + test_spec = { + "networkcontainer": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'networkcontainer': '192.168.10.0/24'}) + + def test_nios_networkcontainer_ipv4_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'networkcontainer': '192.168.10.0/24', + 'comment': None, 'extattrs': None} + + ref = "networkcontainer/ZG5zLm5ldHdvcmtfdmlldyQw:ansible/false" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "networkcontainer": "192.168.10.0/24" + }] + + test_spec = { + "networkcontainer": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) + + def test_nios_networkcontainer_ipv6_create(self): + self.module.params = {'provider': None, 'state': 'present', 'ipv6networkcontainer': 'fe80::/64', + 'comment': None, 'extattrs': None} + + test_object = None + test_spec = { + "ipv6networkcontainer": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'ipv6networkcontainer': 'fe80::/64'}) diff --git a/tests/unit/plugins/modules/test_nios_network_view.py b/tests/unit/plugins/modules/test_nios_network_view.py new file mode 100644 index 00000000..4756127c --- /dev/null +++ b/tests/unit/plugins/modules/test_nios_network_view.py @@ -0,0 +1,160 @@ +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish + + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +from ansible_collections.infoblox.nios_modules.plugins.modules import nios_network_view +from ansible_collections.infoblox.nios_modules.plugins.module_utils import api +from ansible_collections.infoblox.nios_modules.tests.unit.compat.mock import patch, MagicMock, Mock +from ansible.module_utils.common.validation import check_type_dict +from .test_nios_module import TestNiosModule, load_fixture + + +class TestNiosNetworkViewModule(TestNiosModule): + + module = nios_network_view + + def setUp(self): + super(TestNiosNetworkViewModule, self).setUp() + self.module = MagicMock(name='ansible_collections.infoblox.nios_modules.plugins.modules.nios_network_view.WapiModule') + self.module.check_mode = False + self.module.params = {'provider': None} + self.mock_wapi = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_network_view.WapiModule') + self.exec_command = self.mock_wapi.start() + self.mock_wapi_run = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_network_view.WapiModule.run') + self.mock_wapi_run.start() + self.load_config = self.mock_wapi_run.start() + self.mock_check_type_dict = patch('ansible.module_utils.common.validation.check_type_dict') + self.mock_check_type_dict_obj = self.mock_check_type_dict.start() + + def tearDown(self): + super(TestNiosNetworkViewModule, self).tearDown() + self.mock_wapi.stop() + self.mock_wapi_run.stop() + self.mock_check_type_dict.stop() + + def _get_wapi(self, test_object): + wapi = api.WapiModule(self.module) + wapi.get_object = Mock(name='get_object', return_value=test_object) + wapi.create_object = Mock(name='create_object') + wapi.update_object = Mock(name='update_object') + wapi.delete_object = Mock(name='delete_object') + return wapi + + def load_fixtures(self, commands=None): + self.exec_command.return_value = (0, load_fixture('nios_result.txt').strip(), None) + self.load_config.return_value = dict(diff=None, session='session') + + def test_nios_network_view_create(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'ansible', + 'comment': None, 'extattrs': None} + + test_object = None + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {}, + + } + + wapi = self._get_wapi(test_object) + print("WAPI: ", wapi) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'name': 'ansible'}) + + def test_nios_network_view_update_comment(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'default', + 'comment': 'updated comment', 'extattrs': None, 'network_view': 'default'} + + test_object = [ + { + "comment": "test comment", + "_ref": "networkview/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": "default", + "extattrs": {}, + "network_view": "default" + } + ] + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.update_object.called_once_with(test_object) + + def test_nios_network_view_update_name(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'default', 'old_name': 'old_default', + 'comment': 'updated comment', 'extattrs': None, 'network_view': 'default'} + + test_object = [ + { + "comment": "test comment", + "_ref": "networkview/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": "default", + "old_name": "old_default", + "extattrs": {}, + "network_view": "default" + } + ] + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.update_object.called_once_with(test_object) + + def test_nios_network_view_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'name': 'ansible', + 'comment': None, 'extattrs': None} + + ref = "networkview/ZG5zLm5ldHdvcmtfdmlldyQw:ansible/false" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "name": "ansible", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) diff --git a/tests/unit/plugins/modules/test_nios_nsgroup.py b/tests/unit/plugins/modules/test_nios_nsgroup.py new file mode 100644 index 00000000..d8ca9667 --- /dev/null +++ b/tests/unit/plugins/modules/test_nios_nsgroup.py @@ -0,0 +1,130 @@ +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +from ansible_collections.infoblox.nios_modules.plugins.modules import nios_nsgroup +from ansible_collections.infoblox.nios_modules.plugins.module_utils import api +from ansible_collections.infoblox.nios_modules.tests.unit.compat.mock import patch, MagicMock, Mock +from ansible.module_utils.common.validation import check_type_dict +from .test_nios_module import TestNiosModule, load_fixture + + +class TestNiosNSGroupModule(TestNiosModule): + + module = nios_nsgroup + + def setUp(self): + + super(TestNiosNSGroupModule, self).setUp() + self.module = MagicMock(name='ansible_collections.infoblox.nios_modules.plugins.modules.nios_nsgroup.WapiModule') + self.module.check_mode = False + self.module.params = {'provider': None} + + self.mock_wapi = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_nsgroup.WapiModule') + self.exec_command = self.mock_wapi.start() + self.mock_wapi_run = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_nsgroup.WapiModule.run') + self.mock_wapi_run.start() + + self.load_config = self.mock_wapi_run.start() + + self.mock_check_type_dict = patch('ansible.module_utils.common.validation.check_type_dict') + self.mock_check_type_dict_obj = self.mock_check_type_dict.start() + + def tearDown(self): + super(TestNiosNSGroupModule, self).tearDown() + self.mock_wapi.stop() + self.mock_check_type_dict.stop() + + def _get_wapi(self, test_object): + wapi = api.WapiModule(self.module) + wapi.get_object = Mock(name='get_object', return_value=test_object) + wapi.create_object = Mock(name='create_object') + wapi.update_object = Mock(name='update_object') + wapi.delete_object = Mock(name='delete_object') + return wapi + + def load_fixtures(self, commands=None): + self.exec_command.return_value = (0, load_fixture('nios_result.txt').strip(), None) + self.load_config.return_value = dict(diff=None, session='session') + + def test_nios_nsgroup_create(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'my-simple-group', + 'comment': None, 'grid_primary': None} + + test_object = None + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "grid_primary": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'name': 'my-simple-group'}) + + def test_nios_nsgroup_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'name': 'my-simple-group', + 'comment': None, 'grid_primary': None} + + ref = "nsgroup/ZG5zLm5ldHdvcmtfdmlldyQw:ansible/false" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "name": "my-simple-group", + "grid_primary": {'name': 'infoblox-test.example.com'} + }] + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "grid_primary": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) + + def test_nios_nsgroup_update_comment(self): + self.module.params = {'provider': None, 'state': 'present', 'name': 'default', + 'comment': 'updated comment', 'grid_primary': None} + + test_object = [ + { + "comment": "test comment", + "_ref": "nsgroup/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": "default", + "grid_primary": {} + } + ] + + test_spec = { + "name": {"ib_req": True}, + "comment": {}, + "grid_primary": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.update_object.called_once_with(test_object) diff --git a/tests/unit/plugins/modules/test_nios_ptr_record.py b/tests/unit/plugins/modules/test_nios_ptr_record.py new file mode 100644 index 00000000..5ffd6487 --- /dev/null +++ b/tests/unit/plugins/modules/test_nios_ptr_record.py @@ -0,0 +1,184 @@ +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +from ansible_collections.infoblox.nios_modules.plugins.modules import nios_ptr_record +from ansible_collections.infoblox.nios_modules.plugins.module_utils import api +from ansible_collections.infoblox.nios_modules.tests.unit.compat.mock import patch, MagicMock, Mock +from .test_nios_module import TestNiosModule, load_fixture + + +class TestNiosPTRRecordModule(TestNiosModule): + + module = nios_ptr_record + + def setUp(self): + + super(TestNiosPTRRecordModule, self).setUp() + self.module = MagicMock(name='ansible_collections.infoblox.nios_modules.plugins.modules.nios_ptr_record.WapiModule') + self.module.check_mode = False + self.module.params = {'provider': None} + + self.mock_wapi = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_ptr_record.WapiModule') + self.exec_command = self.mock_wapi.start() + self.mock_wapi_run = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_ptr_record.WapiModule.run') + self.mock_wapi_run.start() + + self.load_config = self.mock_wapi_run.start() + + def tearDown(self): + super(TestNiosPTRRecordModule, self).tearDown() + self.mock_wapi.stop() + + def _get_wapi(self, test_object): + wapi = api.WapiModule(self.module) + wapi.get_object = Mock(name='get_object', return_value=test_object) + wapi.create_object = Mock(name='create_object') + wapi.update_object = Mock(name='update_object') + wapi.delete_object = Mock(name='delete_object') + return wapi + + def load_fixtures(self, commands=None): + self.exec_command.return_value = (0, load_fixture('nios_result.txt').strip(), None) + self.load_config.return_value = dict(diff=None, session='session') + + def test_nios_ptr_record_create(self): + self.module.params = {'provider': None, 'state': 'present', 'ptrdname': 'ansible.test.com', + 'ipv4addr': '10.36.241.14', 'comment': None, 'extattrs': None, 'view': 'default'} + + test_object = None + test_spec = { + "ipv4addr": {"ib_req": True}, + "ptrdname": {"ib_req": True}, + "comment": {}, + "extattrs": {}, + "view": {"ib_req": True} + } + + wapi = self._get_wapi(test_object) + print("WAPI: ", wapi) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'ipv4addr': '10.36.241.14', 'ptrdname': 'ansible.test.com', 'view': 'default'}) + + def test_nios_ptr_record_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'ptrdname': 'ansible.test.com', + 'ipv4addr': '10.36.241.14', 'comment': None, 'extattrs': None, 'view': 'default'} + + ref = "record:ptr/ZG5zLm5ldHdvcmtfdmlldyQw:14.241.36.10.in-addr.arpa/default" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "ptrdname": "ansible.test.com", + "ipv4addr": "10.36.241.14", + "view": "default", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "ipv4addr": {"ib_req": True}, + "ptrdname": {"ib_req": True}, + "comment": {}, + "extattrs": {}, + "view": {"ib_req": True} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) + + def test_nios_ptr_record_update_comment(self): + self.module.params = {'provider': None, 'state': 'present', 'ptrdname': 'ansible.test.com', + 'ipv4addr': '10.36.241.14', 'comment': 'updated comment', 'extattrs': None, 'view': 'default'} + + test_object = [ + { + "comment": "test comment", + "_ref": "record:ptr/ZG5zLm5ldHdvcmtfdmlldyQw:14.241.36.10.in-addr.arpa/default", + "ptrdname": "ansible.test.com", + "ipv4addr": "10.36.241.14", + "extattrs": {}, + "view": "default" + } + ] + + test_spec = { + "ipv4addr": {"ib_req": True}, + "ptrdname": {"ib_req": True}, + "comment": {}, + "extattrs": {}, + "view": {"ib_req": True} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.update_object.called_once_with(test_object) + + def test_nios_ptr_record_update_record_ptrdname(self): + self.module.params = {'provider': None, 'state': 'present', 'ptrdname': 'ansible.test.org', + 'ipv4addr': '10.36.241.14', 'comment': 'comment', 'extattrs': None, 'view': 'default'} + + test_object = [ + { + "comment": "test comment", + "_ref": "record:ptr/ZG5zLm5ldHdvcmtfdmlldyQw:14.241.36.10.in-addr.arpa/default", + "ptrdname": "ansible.test.com", + "ipv4addr": "10.36.241.14", + "extattrs": {}, + "view": "default" + } + ] + + test_spec = { + "ipv4addr": {"ib_req": True}, + "ptrdname": {"ib_req": True}, + "comment": {}, + "extattrs": {}, + "view": {"ib_req": True} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.update_object.called_once_with(test_object) + + def test_nios_ptr6_record_create(self): + self.module.params = {'provider': None, 'state': 'present', 'ptrdname': 'ansible6.test.com', + 'ipv6addr': '2002:8ac3:802d:1242:20d:60ff:fe38:6d16', 'comment': None, 'extattrs': None, 'view': 'default'} + + test_object = None + test_spec = {"ipv6addr": {"ib_req": True}, + "ptrdname": {"ib_req": True}, + "comment": {}, + "extattrs": {}, + "view": {"ib_req": True}} + + wapi = self._get_wapi(test_object) + print("WAPI: ", wapi) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'ipv6addr': '2002:8ac3:802d:1242:20d:60ff:fe38:6d16', + 'ptrdname': 'ansible6.test.com', 'view': 'default'}) diff --git a/tests/unit/plugins/modules/test_nios_srv_record.py b/tests/unit/plugins/modules/test_nios_srv_record.py new file mode 100644 index 00000000..3d7e6c98 --- /dev/null +++ b/tests/unit/plugins/modules/test_nios_srv_record.py @@ -0,0 +1,157 @@ +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish + + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +from ansible_collections.infoblox.nios_modules.plugins.modules import nios_srv_record +from ansible_collections.infoblox.nios_modules.plugins.module_utils import api +from ansible_collections.infoblox.nios_modules.tests.unit.compat.mock import patch, MagicMock, Mock +from ansible.module_utils.common.validation import check_type_dict +from .test_nios_module import TestNiosModule, load_fixture + + +class TestNiosSRVRecordModule(TestNiosModule): + + module = nios_srv_record + + def setUp(self): + super(TestNiosSRVRecordModule, self).setUp() + self.module = MagicMock(name='ansible_collections.infoblox.nios_modules.plugins.modules.nios_srv_record.WapiModule') + self.module.check_mode = False + self.module.params = {'provider': None} + self.mock_wapi = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_srv_record.WapiModule') + self.exec_command = self.mock_wapi.start() + self.mock_wapi_run = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_srv_record.WapiModule.run') + self.mock_wapi_run.start() + self.load_config = self.mock_wapi_run.start() + self.mock_check_type_dict = patch('ansible.module_utils.common.validation.check_type_dict') + self.mock_check_type_dict_obj = self.mock_check_type_dict.start() + + def tearDown(self): + super(TestNiosSRVRecordModule, self).tearDown() + self.mock_wapi.stop() + self.mock_wapi_run.stop() + self.mock_check_type_dict.stop() + + def _get_wapi(self, test_object): + wapi = api.WapiModule(self.module) + wapi.get_object = Mock(name='get_object', return_value=test_object) + wapi.create_object = Mock(name='create_object') + wapi.update_object = Mock(name='update_object') + wapi.delete_object = Mock(name='delete_object') + return wapi + + def load_fixtures(self, commands=None): + self.exec_command.return_value = (0, load_fixture('nios_result.txt').strip(), None) + self.load_config.return_value = dict(diff=None, session='session') + + def test_nios_srv_record_create(self): + self.module.params = {'provider': None, 'state': 'present', 'name': '_sip._tcp.service.ansible.com', + 'port': 5080, 'target': 'service1.ansible.com', 'priority': 10, 'weight': 10, + 'comment': None, 'extattrs': None} + + test_object = None + + test_spec = { + "name": {"ib_req": True}, + "port": {"ib_req": True}, + "target": {"ib_req": True}, + "priority": {"ib_req": True}, + "weight": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + print("WAPI: ", wapi) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'name': '_sip._tcp.service.ansible.com', + 'port': 5080, 'target': 'service1.ansible.com', 'priority': 10, 'weight': 10}) + + def test_nios_srv_record_update_comment(self): + self.module.params = {'provider': None, 'state': 'present', 'name': '_sip._tcp.service.ansible.com', + 'port': 5080, 'target': 'service1.ansible.com', 'priority': 10, 'weight': 10, + 'comment': None, 'extattrs': None} + + test_object = [ + { + "comment": "test comment", + "_ref": "srvrecord/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "name": "_sip._tcp.service.ansible.com", + 'port': 5080, + "target": "mailhost.ansible.com", + "priority": 10, + 'weight': 10, + "extattrs": {} + } + ] + + test_spec = { + "name": {"ib_req": True}, + "port": {"ib_req": True}, + "target": {"ib_req": True}, + "priority": {"ib_req": True}, + "weight": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + + def test_nios_srv_record_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'name': '_sip._tcp.service.ansible.com', + 'port': 5080, 'target': 'service1.ansible.com', 'priority': 10, 'weight': 10, + 'comment': None, 'extattrs': None} + + ref = "srvrecord/ZG5zLm5ldHdvcmtfdmlldyQw:default/false" + + test_object = [ + { + "comment": "test comment", + "_ref": ref, + "name": "_sip._tcp.service.ansible.com", + "port": 5080, + "target": "mailhost.ansible.com", + "priority": 10, + "weight": 10, + "extattrs": {'Site': {'value': 'test'}} + } + ] + + test_spec = { + "name": {"ib_req": True}, + "port": {"ib_req": True}, + "target": {"ib_req": True}, + "priority": {"ib_req": True}, + "weight": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) diff --git a/tests/unit/plugins/modules/test_nios_zone.py b/tests/unit/plugins/modules/test_nios_zone.py new file mode 100644 index 00000000..693ab060 --- /dev/null +++ b/tests/unit/plugins/modules/test_nios_zone.py @@ -0,0 +1,287 @@ +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish + + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +from ansible_collections.infoblox.nios_modules.plugins.modules import nios_zone +from ansible_collections.infoblox.nios_modules.plugins.module_utils import api +from ansible_collections.infoblox.nios_modules.tests.unit.compat.mock import patch, MagicMock, Mock +from .test_nios_module import TestNiosModule, load_fixture + + +class TestNiosZoneModule(TestNiosModule): + + module = nios_zone + + def setUp(self): + super(TestNiosZoneModule, self).setUp() + self.module = MagicMock(name='ansible_collections.infoblox.nios_modules.plugins.modules.nios_zone.WapiModule') + self.module.check_mode = False + self.module.params = {'provider': None} + self.mock_wapi = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_zone.WapiModule') + self.exec_command = self.mock_wapi.start() + self.mock_wapi_run = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_zone.WapiModule.run') + self.mock_wapi_run.start() + self.load_config = self.mock_wapi_run.start() + + def tearDown(self): + super(TestNiosZoneModule, self).tearDown() + self.mock_wapi.stop() + self.mock_wapi_run.stop() + + def _get_wapi(self, test_object): + wapi = api.WapiModule(self.module) + wapi.get_object = Mock(name='get_object', return_value=test_object) + wapi.create_object = Mock(name='create_object') + wapi.update_object = Mock(name='update_object') + wapi.delete_object = Mock(name='delete_object') + return wapi + + def load_fixtures(self, commands=None): + self.exec_command.return_value = (0, load_fixture('nios_result.txt').strip(), None) + self.load_config.return_value = dict(diff=None, session='session') + + def test_nios_zone_create(self): + self.module.params = {'provider': None, 'state': 'present', 'fqdn': 'ansible.com', + 'comment': None, 'extattrs': None} + + test_object = None + + test_spec = { + "fqdn": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + print("WAPI: ", wapi) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'fqdn': 'ansible.com'}) + + def test_nios_zone_remove(self): + self.module.params = {'provider': None, 'state': 'absent', 'fqdn': 'ansible.com', + 'comment': None, 'extattrs': None} + + ref = "zone/ZG5zLm5ldHdvcmtfdmlldyQw:ansible/false" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "fqdn": "ansible.com", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "fqdn": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) + + def test_nios_zone_update_comment(self): + self.module.params = {'provider': None, 'state': 'present', 'fqdn': 'ansible.com', + 'comment': 'updated comment', 'extattrs': None} + + test_object = [ + { + "comment": "test comment", + "_ref": "zone/ZG5zLm5ldHdvcmtfdmlldyQw:default/true", + "fqdn": "ansible.com", + "extattrs": {'Site': {'value': 'test'}} + } + ] + + test_spec = { + "fqdn": {"ib_req": True}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + + def test_nios_zone_create_using_grid_primary_secondaries(self): + self.module.params = {'provider': None, 'state': 'present', 'fqdn': 'ansible.com', + 'grid_primary': [{"name": "gridprimary.grid.com"}], + 'grid_secondaries': [{"name": "gridsecondary1.grid.com"}, + {"name": "gridsecondary2.grid.com"}], + 'restart_if_needed': True, + 'comment': None, 'extattrs': None} + + test_object = None + grid_spec = dict( + name=dict(required=True), + ) + test_spec = { + "fqdn": {"ib_req": True}, + "grid_primary": {}, + "grid_secondaries": {}, + "restart_if_needed": {}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + print("WAPI: ", wapi) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'fqdn': 'ansible.com', + "grid_primary": [{"name": "gridprimary.grid.com"}], + "grid_secondaries": [{"name": "gridsecondary1.grid.com"}, + {"name": "gridsecondary2.grid.com"}], + "restart_if_needed": True + }) + + def test_nios_zone_remove_using_grid_primary_secondaries(self): + self.module.params = {'provider': None, 'state': 'absent', 'fqdn': 'ansible.com', + 'grid_primary': [{"name": "gridprimary.grid.com"}], + 'grid_secondaries': [{"name": "gridsecondary1.grid.com"}, + {"name": "gridsecondary2.grid.com"}], + 'restart_if_needed': True, + 'comment': None, 'extattrs': None} + + ref = "zone/ZG5zLm5ldHdvcmtfdmlldyQw:ansible/false" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "fqdn": "ansible.com", + "grid_primary": [{"name": "gridprimary.grid.com"}], + "grid_secondaries": [{"name": "gridsecondary1.grid.com"}, {"name": "gridsecondary2.grid.com"}], + "restart_if_needed": True, + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "fqdn": {"ib_req": True}, + "grid_primary": {}, + "grid_secondaries": {}, + "restart_if_needed": {}, + "comment": {}, + "extattrs": {} + } + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) + + def test_nios_zone_create_using_name_server_group(self): + self.module.params = {'provider': None, 'state': 'present', 'fqdn': 'ansible.com', + 'ns_group': 'examplensg', 'comment': None, 'extattrs': None} + + test_object = None + + test_spec = { + "fqdn": {"ib_req": True}, + "ns_group": {}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + print("WAPI: ", wapi) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'fqdn': 'ansible.com', + 'ns_group': 'examplensg'}) + + def test_nios_zone_remove_using_name_server_group(self): + self.module.params = {'provider': None, 'state': 'absent', 'fqdn': 'ansible.com', + 'ns_group': 'examplensg', 'comment': None, 'extattrs': None} + + ref = "zone/ZG5zLm5ldHdvcmtfdmlldyQw:ansible/false" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "fqdn": "ansible.com", + "ns_group": "examplensg", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "fqdn": {"ib_req": True}, + "ns_group": {}, + "comment": {}, + "extattrs": {} + } + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) + + def test_nios_zone_create_using_zone_format(self): + self.module.params = {'provider': None, 'state': 'present', 'fqdn': '10.10.10.in-addr.arpa', + 'zone_format': 'IPV4', 'comment': None, 'extattrs': None} + + test_object = None + + test_spec = { + "fqdn": {"ib_req": True}, + "zone_format": {}, + "comment": {}, + "extattrs": {} + } + + wapi = self._get_wapi(test_object) + print("WAPI: ", wapi) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.create_object.assert_called_once_with('testobject', {'fqdn': '10.10.10.in-addr.arpa', + 'zone_format': 'IPV4'}) + + def test_nios_zone_remove_using_using_zone_format(self): + self.module.params = {'provider': None, 'state': 'absent', 'fqdn': 'ansible.com', + 'zone_format': 'IPV4', 'comment': None, 'extattrs': None} + + ref = "zone/ZG5zLm5ldHdvcmtfdmlldyQw:ansible/false" + + test_object = [{ + "comment": "test comment", + "_ref": ref, + "fqdn": "ansible.com", + "zone_format": "IPV4", + "extattrs": {'Site': {'value': 'test'}} + }] + + test_spec = { + "fqdn": {"ib_req": True}, + "zone_format": {}, + "comment": {}, + "extattrs": {} + } + wapi = self._get_wapi(test_object) + res = wapi.run('testobject', test_spec) + + self.assertTrue(res['changed']) + wapi.delete_object.assert_called_once_with(ref) diff --git a/tests/unit/plugins/modules/utils.py b/tests/unit/plugins/modules/utils.py new file mode 100644 index 00000000..6a00fd25 --- /dev/null +++ b/tests/unit/plugins/modules/utils.py @@ -0,0 +1,52 @@ +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import json + +from ansible_collections.community.general.tests.unit.compat import unittest +from ansible_collections.community.general.tests.unit.compat.mock import patch +from ansible.module_utils import basic +from ansible.module_utils.common.text.converters import to_bytes + + +def set_module_args(args): + if '_ansible_remote_tmp' not in args: + args['_ansible_remote_tmp'] = '/tmp' + if '_ansible_keep_remote_files' not in args: + args['_ansible_keep_remote_files'] = False + + args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) + basic._ANSIBLE_ARGS = to_bytes(args) + + +class AnsibleExitJson(Exception): + pass + + +class AnsibleFailJson(Exception): + pass + + +def exit_json(*args, **kwargs): + if 'changed' not in kwargs: + kwargs['changed'] = False + raise AnsibleExitJson(kwargs) + + +def fail_json(*args, **kwargs): + kwargs['failed'] = True + raise AnsibleFailJson(kwargs) + + +class ModuleTestCase(unittest.TestCase): + + def setUp(self): + self.mock_module = patch.multiple(basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json) + self.mock_module.start() + self.mock_sleep = patch('time.sleep') + self.mock_sleep.start() + set_module_args({}) + self.addCleanup(self.mock_module.stop) + self.addCleanup(self.mock_sleep.stop) diff --git a/tests/unit/requirements.txt b/tests/unit/requirements.txt new file mode 100644 index 00000000..a0a2eb7e --- /dev/null +++ b/tests/unit/requirements.txt @@ -0,0 +1,8 @@ +infoblox-client +pytest +pytest-forked +pytest-xdist +mock +pytest-mock +pytest-cov +coverage==4.5.4