# Test code for the ACI modules # Copyright: (c) 2017, Jacob McGill (@jmcgill298) # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - name: Test that we have an ACI APIC host, ACI username and ACI password fail: msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.' when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined - name: ensure tenant exists for tests to kick off aci_tenant: &aci_tenant_present host: "{{ aci_hostname }}" username: "{{ aci_username }}" password: "{{ aci_password }}" validate_certs: '{{ aci_validate_certs | default(false) }}' use_ssl: '{{ aci_use_ssl | default(true) }}' use_proxy: '{{ aci_use_proxy | default(true) }}' output_level: debug state: present tenant: anstest register: tenant_present - name: ensure bd exists for tests to kick off aci_bd: &aci_bd_present <<: *aci_tenant_present bd: anstest register: bd_present - name: ensure subnet does not exist for tests to kick off aci_bd_subnet: &aci_subnet_absent <<: *aci_bd_present state: absent gateway: 10.100.100.1 mask: 24 - name: ensure subnet does not exist for tests to kick off aci_bd_subnet: &aci_subnet2_absent <<: *aci_subnet_absent gateway: 10.100.101.1 mask: 25 - name: create subnet - check mode works aci_bd_subnet: &aci_subnet_present <<: *aci_subnet_absent state: present subnet_name: anstest descr: Ansible Test check_mode: yes register: create_check_mode - name: create subnet - creation works aci_bd_subnet: <<: *aci_subnet_present register: create_subnet - name: create new subnet - creation works aci_bd_subnet: &aci_subnet2_present <<: *aci_subnet2_absent state: present descr: Ansible Test scope: [private, shared] route_profile: default route_profile_l3_out: default register: create_subnet2 - name: create subnet again - idempotency works aci_bd_subnet: <<: *aci_subnet2_present register: create_idempotency - name: modify subnet - update works aci_bd_subnet: <<: *aci_subnet_present scope: [shared, public] subnet_control: querier_ip register: modify_subnet - name: create subnet with bad scope - failure message works aci_bd_subnet: <<: *aci_subnet_present scope: [private, public] register: create_bad_scope ignore_errors: yes - name: create subnet without all necessary params - failure message works aci_bd_subnet: <<: *aci_subnet_present bd: "{{ fake_var | default(omit) }}" register: create_incomplete_data ignore_errors: yes - name: asserts for subnet creation tasks assert: that: - create_check_mode.changed == true - 'create_check_mode.sent == {"fvSubnet": {"attributes": {"descr": "Ansible Test", "ip": "10.100.100.1/24", "name": "anstest"}}}' - create_subnet.changed == true - 'create_subnet.sent == {"fvSubnet": {"attributes": {"descr": "Ansible Test", "ip": "10.100.100.1/24", "name": "anstest"}}}' - 'create_subnet.previous == []' - create_subnet2.changed == true - create_subnet2.sent == create_subnet2.proposed - 'create_subnet2.sent.fvSubnet.attributes.scope == "private,shared"' - 'create_subnet2.sent.fvSubnet.children.0.fvRsBDSubnetToProfile.attributes == {"tnL3extOutName": "default", "tnRtctrlProfileName": "default"}' - create_idempotency.changed == false - create_idempotency.previous != [] - modify_subnet.changed == true - modify_subnet.previous != [] - modify_subnet.changed != modify_subnet.proposed - 'modify_subnet.sent == {"fvSubnet": {"attributes": {"ctrl": "querier", "scope": "public,shared"}}}' - create_bad_scope.failed == true - create_bad_scope.msg.startswith("Parameter 'scope' cannot be both 'private' and 'public'") - create_incomplete_data.failed == true - 'create_incomplete_data.msg == "state is present but all of the following are missing: bd"' - name: get all subnets aci_bd_subnet: &aci_query <<: *aci_tenant_present state: query tenant: "{{ fake_var | default(omit) }}" register: get_all - name: get all in tenant aci_bd_subnet: <<: *aci_query tenant: anstest register: get_all_tenant - name: get all in bd aci_bd_subnet: <<: *aci_query bd: anstest register: get_all_bd - name: get all tenant and bd aci_bd_subnet: <<: *aci_bd_present state: query register: get_all_tenant_bd - name: get subnet in tenant aci_bd_subnet: <<: *aci_subnet_present state: query bd: "{{ fake_var | default(omit) }}" register: get_subnet_tenant - name: get subnet in bd aci_bd_subnet: <<: *aci_subnet_present state: query tenant: "{{ fake_var | default(omit) }}" register: get_subnet_bd - name: get specific subnet aci_bd_subnet: <<: *aci_subnet_present state: query register: get_subnet - name: get all subnets matching gateway aci_bd_subnet: <<: *aci_subnet_present state: query tenant: "{{ fake_var | default(omit) }}" bd: "{{ fake_var | default(omit) }}" register: get_subnets_gateway - name: asserts for query tasks assert: that: - get_all.changed == false - get_all.current | length > 1 - get_all_tenant.changed == false - '"tn-anstest.json" in get_all_tenant.url' - get_all_bd.changed == false - '"query-target-filter=eq(fvBD.name, \"anstest\")" in get_all_bd.filter_string' - '"class/fvBD.json" in get_all_bd.url' - get_all_tenant_bd.changed == false - '"tn-anstest/BD-anstest.json" in get_all_tenant_bd.url' - get_all_tenant_bd.current.0.fvBD.children | length > 1 - get_subnet_tenant.changed == false - '"rsp-subtree-filter=eq(fvSubnet.ip, \"10.100.100.1/24\")" in get_subnet_tenant.filter_string' - '"tn-anstest.json" in get_subnet_tenant.url' - get_subnet_bd.changed == false - '"query-target-filter=eq(fvBD.name, \"anstest\")" and "rsp-subtree-filter=eq(fvSubnet.ip, \"10.100.100.1/24\")" in get_subnet_bd.filter_string' - '"class/fvBD.json" in get_subnet_bd.url' - get_subnet.changed == false - get_subnet.current | length == 1 - '"tn-anstest/BD-anstest/subnet-[10.100.100.1/24].json" in get_subnet.url' - get_subnets_gateway.changed == false - '"query-target-filter=eq(fvSubnet.ip, \"10.100.100.1/24\")" in get_subnets_gateway.filter_string' - '"class/fvSubnet.json" in get_subnets_gateway.url' - name: delete subnet - check mode works aci_bd_subnet: <<: *aci_subnet_absent check_mode: yes register: delete_check_mode - name: delete subnet - delete works aci_bd_subnet: <<: *aci_subnet_absent register: delete_subnet - name: delete subnet - cleanup aci_bd_subnet: <<: *aci_subnet2_absent - name: delete subnet again - idempotency works aci_bd_subnet: <<: *aci_subnet2_absent register: delete_idempotency - name: asserts for deletion task assert: that: - delete_check_mode.changed == true - delete_check_mode.proposed == {} - delete_subnet.changed == true - delete_subnet.previous != [] - 'delete_subnet.method == "DELETE"' - delete_idempotency.changed == false - delete_idempotency.previous == [] - name: delete bd - cleanup before ending tests aci_bd: <<: *aci_bd_present state: absent when: bd_present.changed == true - name: delete tenant - cleanup before ending tests aci_tenant: <<: *aci_tenant_present state: absent when: tenant_present.changed == true