diff --git a/lib/ansible/modules/network/aci/aci_firmware_source.py b/lib/ansible/modules/network/aci/aci_firmware_source.py index df9f56a7b9..1d0ce73bd4 100644 --- a/lib/ansible/modules/network/aci/aci_firmware_source.py +++ b/lib/ansible/modules/network/aci/aci_firmware_source.py @@ -31,12 +31,12 @@ options: polling_interval: description: - Polling interval in minutes. - protocol: + url_protocol: description: - The Firmware download protocol. choices: [ http, local, scp, usbkey ] default: scp - aliases: [ proto ] + aliases: [ url_proto ] url: description: The firmware URL for the image(s) on the source. @@ -56,7 +56,38 @@ extends_documentation_fragment: aci ''' EXAMPLES = r''' -# +- name: Add firmware source + aci_firmware_source: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + source: aci-msft-pkg-3.1.1i.zip + url: foobar.cisco.com/download/cisco/aci/aci-msft-pkg-3.1.1i.zip + url_protocol: http + state: present + +- name: Remove firmware source + aci_firmware_source: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + source: aci-msft-pkg-3.1.1i.zip + state: absent + +- name: Query all firmware sources + aci_firmware_source: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + state: query + +- name: Query a specific firmware source + aci_firmware_source: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + source: aci-msft-pkg-3.1.1i.zip + state: query ''' RETURN = r''' @@ -174,10 +205,10 @@ def main(): argument_spec.update( source=dict(type='str', aliases=['name', 'source_name']), # Not required for querying all objects polling_interval=dict(type='int'), - protocol=dict(type='str', default='scp', choices=['http', 'local', 'scp', 'usbkey'], aliases=['proto']), url=dict(type='str'), url_username=dict(type='str'), url_password=dict(type='str', no_log=True), + url_protocol=dict(type='str', default='scp', choices=['http', 'local', 'scp', 'usbkey'], aliases=['url_proto']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) @@ -186,12 +217,12 @@ def main(): supports_check_mode=True, required_if=[ ['state', 'absent', ['source']], - ['state', 'present', ['protocol', 'source', 'url']], + ['state', 'present', ['url_protocol', 'source', 'url']], ], ) polling_interval = module.params['polling_interval'] - protocol = module.params['protocol'] + url_protocol = module.params['url_protocol'] state = module.params['state'] source = module.params['source'] url = module.params['url'] @@ -218,7 +249,7 @@ def main(): url=url, password=url_password, pollingInterval=polling_interval, - proto=protocol, + proto=url_protocol, user=url_username, ), ) diff --git a/test/integration/targets/aci_firmware_source/aliases b/test/integration/targets/aci_firmware_source/aliases new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/integration/targets/aci_firmware_source/tasks/main.yml b/test/integration/targets/aci_firmware_source/tasks/main.yml new file mode 100644 index 0000000000..3dc2171839 --- /dev/null +++ b/test/integration/targets/aci_firmware_source/tasks/main.yml @@ -0,0 +1,189 @@ +# Test code for the ACI modules +# Copyright: (c) 2018, Dag Wieers (@dagwieers) + +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + + +# CLEAN ENVIRONMENT +- name: Remove firmware source + aci_firmware_source: &source_absent + 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: info + source: aci-msft-pkg-3.1.1i.zip + state: absent + + +# ADD SOURCE +#- name: Add source (check_mode) +# aci_firmware_source: &source_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: info +# source: aci-msft-pkg-3.1.1i.zip +# url: foobar.cisco.com/download/cisco/aci/aci-msft-pkg-3.1.1i.zip +# url_protocol: http +# state: present +# check_mode: yes +# register: cm_add_source +# +#- name: Add source (normal mode) +# aci_firmware_source: *source_present +# register: nm_add_source +# +#- name: Verify add_source +# assert: +# that: +# - cm_add_source.changed == nm_add_source.changed == true +# - 'cm_add_source.sent == nm_add_source.sent == {"firmwareOSource": {"attributes": {"name": "aci-msft-pkg-3.1.1i.zip", "proto": "http", "url": "foobar.cisco.com/download/cisco/aci/aci-msft-pkg-3.1.1i.zip"}}}' +# - 'cm_add_source.proposed == nm_add_source.proposed == {"firmwareOSource": {"attributes": {"name": "aci-msft-pkg-3.1.1i.zip", "proto": "http", "url": "foobar.cisco.com/download/cisco/aci/aci-msft-pkg-3.1.1i.zip"}}}' +# - cm_add_source.current == cm_add_source.previous == nm_add_source.previous == [] +# - nm_add_source.current.0.firmwareOSource.attributes.name == 'aci-msft-pkg-3.1.1i.zip' +# - nm_add_source.current.0.firmwareOSource.attributes.proto == 'http' +# - nm_add_source.current.0.firmwareOSource.attributes.url == 'foobar.cisco.com/download/cisco/aci/aci-msft-pkg-3.1.1i.zip' +# +#- name: Add source again (check_mode) +# aci_firmware_source: *source_present +# check_mode: yes +# register: cm_add_source_again +# +#- name: Add source again (normal mode) +# aci_firmware_source: *souce_present +# register: nm_add_source_again +# +#- name: Verify add_source_again +# assert: +# that: +# - cm_add_source_again.changed == nm_add_source_again.changed == false + + +# QUERY ALL SOURCES +- name: Query all sources (check_mode) + aci_firmware_source: &source_query + 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) }}' + state: query + check_mode: yes + register: cm_query_all_sources + +- name: Query all sources (normal mode) + aci_firmware_source: *source_query + register: nm_query_all_sources + +- name: Verify query_all_sources + assert: + that: + - cm_query_all_sources.changed == nm_query_all_sources.changed == false + - cm_query_all_sources == nm_query_all_sources +# - nm_query_all_sources.current|length >= 1 + + +# QUERY A SOURCE +#- name: Query our source (check_mode) +# aci_firmware_source: +# <<: *source_query +# source: aci-msft-pkg-3.1.1i.zip +# check_mode: yes +# register: cm_query_source +# +#- name: Query our source (normal mode) +# aci_firmware_source: +# <<: *source_query +# source: aci-msft-pkg-3.1.1i.zip +# register: nm_query_source +# +#- name: Verify query_source +# assert: +# that: +# - cm_query_source.changed == nm_query_source.changed == false +# - cm_query_source == nm_query_source +# - nm_query_source.current.0.infraRsDomP.attributes.dn == 'uni/infra/attentp-test_aep/rsdomP-[uni/phys-phys_dom]' +# - nm_query_source.current.0.infraRsDomP.attributes.tCl == 'physDomP' +# - nm_query_source.current.0.infraRsDomP.attributes.tDn == 'uni/phys-phys_dom' + + +# REMOVE SOURCE +#- name: Remove source (check_mode) +# aci_firmware_source: *source_absent +# check_mode: yes +# register: cm_remove_source + +#- name: Remove source (normal mode) +# aci_firmware_source: *source_absent +# register: nm_remove_source +# +#- name: Verify remove_source +# assert: +# that: +# - cm_remove_source.changed == nm_remove_source.changed == true +# - 'cm_remove_source.current == cm_remove_source.previous == nm_remove_source.previous == [{"infraRsDomP": {"attributes": {"dn": "uni/infra/attentp-test_aep/rsdomP-[uni/phys-phys_dom]", "tDn": "uni/phys-phys_dom"}}}]' +# - nm_remove_source.current == [] +# +#- name: Remove source again (check_mode) +# aci_firmware_source: *source_absent +# check_mode: yes +# register: cm_remove_source_again +# +#- name: Remove source again (normal mode) +# aci_firmware_source: *source_absent +# register: nm_remove_source_again +# +#- name: Verify remove_source_again +# assert: +# that: +# - cm_remove_source_again.changed == nm_remove_source_again.changed == false + + +# QUERY NON-EXISTING SOURCE +#- name: Query non-existing source (check_mode) +# aci_firmware_source: +# <<: *source_query +# source: aci-msft-pkg-3.1.1i.zip +# check_mode: yes +# register: cm_query_non_source +# +#- name: Query non-existing source (normal mode) +# aci_firmware_source: +# <<: *source_query +# source: aci-msft-pkg-3.1.1i.zip +# register: nm_query_non_source +# +#- name: Verify query_non_source +# assert: +# that: +# - cm_query_non_source.changed == nm_query_non_source.changed == false +# - cm_query_non_source == nm_query_non_source +# - nm_query_non_source.current == [] + + +# PROVOKE ERRORS +- name: Error when required parameter is missing + aci_firmware_source: + 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: info + state: present + ignore_errors: yes + register: error_on_missing_required_param + +- name: Verify error_on_missing_required_param + assert: + that: + - error_on_missing_required_param.failed == true + - 'error_on_missing_required_param.msg == "state is present but all of the following are missing: source, url"'