From ab2b339dd6d27c4b06001e88480eabe9a94a8e92 Mon Sep 17 00:00:00 2001 From: Matt Martz Date: Fri, 2 Oct 2020 14:53:09 -0500 Subject: [PATCH] More explicit argspec tests (#72064) * Add more explicit coverage of argspec functionality * fail_on_missing_params * ci_complete ci_coverage * Remove incidental_aws_step_functions_state_machine * ci_complete ci_coverage * Remove incidental_cs_service_offering * ci_complete ci_coverage --- .../targets/argspec/library/argspec.py | 10 + .../targets/argspec/tasks/main.yml | 35 ++ .../aliases | 2 - .../defaults/main.yml | 4 - .../files/alternative_state_machine.json | 15 - .../files/state_machine.json | 10 - .../state_machines_iam_trust_policy.json | 12 - .../tasks/main.yml | 296 --------- .../incidental_cs_service_offering/aliases | 2 - .../meta/main.yml | 3 - .../tasks/guest_vm_service_offering.yml | 223 ------- .../tasks/main.yml | 3 - .../tasks/system_vm_service_offering.yml | 151 ----- .../aws_step_functions_state_machine.py | 232 ------- ..._step_functions_state_machine_execution.py | 197 ------ .../plugins/modules/cs_service_offering.py | 583 ------------------ 16 files changed, 45 insertions(+), 1733 deletions(-) delete mode 100644 test/integration/targets/incidental_aws_step_functions_state_machine/aliases delete mode 100644 test/integration/targets/incidental_aws_step_functions_state_machine/defaults/main.yml delete mode 100644 test/integration/targets/incidental_aws_step_functions_state_machine/files/alternative_state_machine.json delete mode 100644 test/integration/targets/incidental_aws_step_functions_state_machine/files/state_machine.json delete mode 100644 test/integration/targets/incidental_aws_step_functions_state_machine/files/state_machines_iam_trust_policy.json delete mode 100644 test/integration/targets/incidental_aws_step_functions_state_machine/tasks/main.yml delete mode 100644 test/integration/targets/incidental_cs_service_offering/aliases delete mode 100644 test/integration/targets/incidental_cs_service_offering/meta/main.yml delete mode 100644 test/integration/targets/incidental_cs_service_offering/tasks/guest_vm_service_offering.yml delete mode 100644 test/integration/targets/incidental_cs_service_offering/tasks/main.yml delete mode 100644 test/integration/targets/incidental_cs_service_offering/tasks/system_vm_service_offering.yml delete mode 100644 test/support/integration/plugins/modules/aws_step_functions_state_machine.py delete mode 100644 test/support/integration/plugins/modules/aws_step_functions_state_machine_execution.py delete mode 100644 test/support/integration/plugins/modules/cs_service_offering.py diff --git a/test/integration/targets/argspec/library/argspec.py b/test/integration/targets/argspec/library/argspec.py index 077cd01c4ee..e14df1eac95 100644 --- a/test/integration/targets/argspec/library/argspec.py +++ b/test/integration/targets/argspec/library/argspec.py @@ -42,6 +42,14 @@ def main(): 'another': {}, } }, + 'json': { + 'type': 'json', + }, + 'fail_on_missing_params': { + 'type': 'list', + 'default': [], + }, + 'needed_param': {}, }, required_if=( ('state', 'present', ('path', 'content'), True), @@ -51,6 +59,8 @@ def main(): ), ) + module.fail_on_missing_params(module.params['fail_on_missing_params']) + module.exit_json(**module.params) diff --git a/test/integration/targets/argspec/tasks/main.yml b/test/integration/targets/argspec/tasks/main.yml index f6672f4e0fc..50c2855424e 100644 --- a/test/integration/targets/argspec/tasks/main.yml +++ b/test/integration/targets/argspec/tasks/main.yml @@ -87,6 +87,31 @@ register: argpsec_required_if_fail ignore_errors: true +- argspec: + json: !!str '{"foo": "bar"}' + register: argspec_good_json_string + +- argspec: + json: + foo: bar + register: argspec_good_json_dict + +- argspec: + json: 1 + register: argspec_bad_json + ignore_errors: true + +- argspec: + fail_on_missing_params: + - needed_param + needed_param: whatever + +- argspec: + fail_on_missing_params: + - needed_param + register: argspec_fail_on_missing_params_bad + ignore_errors: true + - assert: that: - argspec_required_if_fail is failed @@ -109,3 +134,13 @@ - argspec_required_together_fail is failed - argpsec_required_if_fail is failed + + - argspec_good_json_string is successful + - > + argspec_good_json_string.json == '{"foo": "bar"}' + - argspec_good_json_dict is successful + - > + argspec_good_json_dict.json == '{"foo": "bar"}' + - argspec_bad_json is failed + + - argspec_fail_on_missing_params_bad is failed diff --git a/test/integration/targets/incidental_aws_step_functions_state_machine/aliases b/test/integration/targets/incidental_aws_step_functions_state_machine/aliases deleted file mode 100644 index 29f60feb446..00000000000 --- a/test/integration/targets/incidental_aws_step_functions_state_machine/aliases +++ /dev/null @@ -1,2 +0,0 @@ -cloud/aws -shippable/aws/incidental diff --git a/test/integration/targets/incidental_aws_step_functions_state_machine/defaults/main.yml b/test/integration/targets/incidental_aws_step_functions_state_machine/defaults/main.yml deleted file mode 100644 index 273a0c783b8..00000000000 --- a/test/integration/targets/incidental_aws_step_functions_state_machine/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -# the random_num is generated in a set_fact task at the start of the testsuite -state_machine_name: "{{ resource_prefix }}_step_functions_state_machine_ansible_test_{{ random_num }}" -step_functions_role_name: "ansible-test-sts-{{ resource_prefix }}-step_functions-role" -execution_name: "{{ resource_prefix }}_sfn_execution" diff --git a/test/integration/targets/incidental_aws_step_functions_state_machine/files/alternative_state_machine.json b/test/integration/targets/incidental_aws_step_functions_state_machine/files/alternative_state_machine.json deleted file mode 100644 index 7b51bebb1a6..00000000000 --- a/test/integration/targets/incidental_aws_step_functions_state_machine/files/alternative_state_machine.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "StartAt": "HelloWorld", - "States": { - "HelloWorld": { - "Type": "Pass", - "Result": "Some other result", - "Next": "Wait" - }, - "Wait": { - "Type": "Wait", - "Seconds": 30, - "End": true - } - } -} \ No newline at end of file diff --git a/test/integration/targets/incidental_aws_step_functions_state_machine/files/state_machine.json b/test/integration/targets/incidental_aws_step_functions_state_machine/files/state_machine.json deleted file mode 100644 index c07d5cebad4..00000000000 --- a/test/integration/targets/incidental_aws_step_functions_state_machine/files/state_machine.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "StartAt": "HelloWorld", - "States": { - "HelloWorld": { - "Type": "Pass", - "Result": "Hello World!", - "End": true - } - } -} \ No newline at end of file diff --git a/test/integration/targets/incidental_aws_step_functions_state_machine/files/state_machines_iam_trust_policy.json b/test/integration/targets/incidental_aws_step_functions_state_machine/files/state_machines_iam_trust_policy.json deleted file mode 100644 index 48d627220fc..00000000000 --- a/test/integration/targets/incidental_aws_step_functions_state_machine/files/state_machines_iam_trust_policy.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Principal": { - "Service": "states.amazonaws.com" - }, - "Action": "sts:AssumeRole" - } - ] -} \ No newline at end of file diff --git a/test/integration/targets/incidental_aws_step_functions_state_machine/tasks/main.yml b/test/integration/targets/incidental_aws_step_functions_state_machine/tasks/main.yml deleted file mode 100644 index 23e71dcebf0..00000000000 --- a/test/integration/targets/incidental_aws_step_functions_state_machine/tasks/main.yml +++ /dev/null @@ -1,296 +0,0 @@ ---- - -- name: Integration test for AWS Step Function state machine module - module_defaults: - iam_role: - aws_access_key: "{{ aws_access_key }}" - aws_secret_key: "{{ aws_secret_key }}" - security_token: "{{ security_token | default(omit) }}" - region: "{{ aws_region }}" - aws_step_functions_state_machine: - aws_access_key: "{{ aws_access_key }}" - aws_secret_key: "{{ aws_secret_key }}" - security_token: "{{ security_token | default(omit) }}" - region: "{{ aws_region }}" - aws_step_functions_state_machine_execution: - aws_access_key: "{{ aws_access_key }}" - aws_secret_key: "{{ aws_secret_key }}" - security_token: "{{ security_token | default(omit) }}" - region: "{{ aws_region }}" - block: - - # ==== Setup ================================================== - - - name: Create IAM service role needed for Step Functions - iam_role: - name: "{{ step_functions_role_name }}" - description: Role with permissions for AWS Step Functions actions. - assume_role_policy_document: "{{ lookup('file', 'state_machines_iam_trust_policy.json') }}" - state: present - register: step_functions_role - - - name: Pause a few seconds to ensure IAM role is available to next task - pause: - seconds: 10 - - # ==== Tests =================================================== - - - name: Create a random component for state machine name - set_fact: - random_num: "{{ 999999999 | random }}" - - - name: Create a new state machine -- check_mode - aws_step_functions_state_machine: - name: "{{ state_machine_name }}" - definition: "{{ lookup('file','state_machine.json') }}" - role_arn: "{{ step_functions_role.iam_role.arn }}" - tags: - project: helloWorld - state: present - register: creation_check - check_mode: yes - - - assert: - that: - - creation_check.changed == True - - creation_check.output == 'State machine would be created.' - - - name: Create a new state machine - aws_step_functions_state_machine: - name: "{{ state_machine_name }}" - definition: "{{ lookup('file','state_machine.json') }}" - role_arn: "{{ step_functions_role.iam_role.arn }}" - tags: - project: helloWorld - state: present - register: creation_output - - - assert: - that: - - creation_output.changed == True - - - name: Pause a few seconds to ensure state machine role is available - pause: - seconds: 5 - - - name: Idempotent rerun of same state function -- check_mode - aws_step_functions_state_machine: - name: "{{ state_machine_name }}" - definition: "{{ lookup('file','state_machine.json') }}" - role_arn: "{{ step_functions_role.iam_role.arn }}" - tags: - project: helloWorld - state: present - register: result - check_mode: yes - - - assert: - that: - - result.changed == False - - result.output == 'State is up-to-date.' - - - name: Idempotent rerun of same state function - aws_step_functions_state_machine: - name: "{{ state_machine_name }}" - definition: "{{ lookup('file','state_machine.json') }}" - role_arn: "{{ step_functions_role.iam_role.arn }}" - tags: - project: helloWorld - state: present - register: result - - - assert: - that: - - result.changed == False - - - name: Update an existing state machine -- check_mode - aws_step_functions_state_machine: - name: "{{ state_machine_name }}" - definition: "{{ lookup('file','alternative_state_machine.json') }}" - role_arn: "{{ step_functions_role.iam_role.arn }}" - tags: - differentTag: different_tag - state: present - register: update_check - check_mode: yes - - - assert: - that: - - update_check.changed == True - - "update_check.output == 'State machine would be updated: {{ creation_output.state_machine_arn }}'" - - - name: Update an existing state machine - aws_step_functions_state_machine: - name: "{{ state_machine_name }}" - definition: "{{ lookup('file','alternative_state_machine.json') }}" - role_arn: "{{ step_functions_role.iam_role.arn }}" - tags: - differentTag: different_tag - state: present - register: update_output - - - assert: - that: - - update_output.changed == True - - update_output.state_machine_arn == creation_output.state_machine_arn - - - name: Start execution of state machine -- check_mode - aws_step_functions_state_machine_execution: - name: "{{ execution_name }}" - execution_input: "{}" - state_machine_arn: "{{ creation_output.state_machine_arn }}" - register: start_execution_output - check_mode: yes - - - assert: - that: - - start_execution_output.changed == True - - "start_execution_output.output == 'State machine execution would be started.'" - - - name: Start execution of state machine - aws_step_functions_state_machine_execution: - name: "{{ execution_name }}" - execution_input: "{}" - state_machine_arn: "{{ creation_output.state_machine_arn }}" - register: start_execution_output - - - assert: - that: - - start_execution_output.changed - - "'execution_arn' in start_execution_output" - - "'start_date' in start_execution_output" - - - name: Start execution of state machine (check for idempotency) (check mode) - aws_step_functions_state_machine_execution: - name: "{{ execution_name }}" - execution_input: "{}" - state_machine_arn: "{{ creation_output.state_machine_arn }}" - register: start_execution_output_idem_check - check_mode: yes - - - assert: - that: - - not start_execution_output_idem_check.changed - - "start_execution_output_idem_check.output == 'State machine execution already exists.'" - - - name: Start execution of state machine (check for idempotency) - aws_step_functions_state_machine_execution: - name: "{{ execution_name }}" - execution_input: "{}" - state_machine_arn: "{{ creation_output.state_machine_arn }}" - register: start_execution_output_idem - - - assert: - that: - - not start_execution_output_idem.changed - - - name: Stop execution of state machine -- check_mode - aws_step_functions_state_machine_execution: - action: stop - execution_arn: "{{ start_execution_output.execution_arn }}" - cause: "cause of the failure" - error: "error code of the failure" - register: stop_execution_output - check_mode: yes - - - name: Stop execution of state machine - aws_step_functions_state_machine_execution: - action: stop - execution_arn: "{{ start_execution_output.execution_arn }}" - cause: "cause of the failure" - error: "error code of the failure" - register: stop_execution_output - - - name: Stop execution of state machine (check for idempotency) - aws_step_functions_state_machine_execution: - action: stop - execution_arn: "{{ start_execution_output.execution_arn }}" - cause: "cause of the failure" - error: "error code of the failure" - register: stop_execution_output - - - name: Try stopping a non-running execution -- check_mode - aws_step_functions_state_machine_execution: - action: stop - execution_arn: "{{ start_execution_output.execution_arn }}" - cause: "cause of the failure" - error: "error code of the failure" - register: stop_execution_output - check_mode: yes - - - assert: - that: - - not stop_execution_output.changed - - "stop_execution_output.output == 'State machine execution is not running.'" - - - name: Try stopping a non-running execution - aws_step_functions_state_machine_execution: - action: stop - execution_arn: "{{ start_execution_output.execution_arn }}" - cause: "cause of the failure" - error: "error code of the failure" - register: stop_execution_output - check_mode: yes - - - assert: - that: - - not stop_execution_output.changed - - - name: Start execution of state machine with the same execution name - aws_step_functions_state_machine_execution: - name: "{{ execution_name }}" - state_machine_arn: "{{ creation_output.state_machine_arn }}" - register: start_execution_output_again - - - assert: - that: - - not start_execution_output_again.changed - - - name: Remove state machine -- check_mode - aws_step_functions_state_machine: - name: "{{ state_machine_name }}" - state: absent - register: deletion_check - check_mode: yes - - - assert: - that: - - deletion_check.changed == True - - "deletion_check.output == 'State machine would be deleted: {{ creation_output.state_machine_arn }}'" - - - name: Remove state machine - aws_step_functions_state_machine: - name: "{{ state_machine_name }}" - state: absent - register: deletion_output - - - assert: - that: - - deletion_output.changed == True - - deletion_output.state_machine_arn == creation_output.state_machine_arn - - - name: Non-existent state machine is absent - aws_step_functions_state_machine: - name: "non_existing_state_machine" - state: absent - register: result - - - assert: - that: - - result.changed == False - - # ==== Cleanup ==================================================== - - always: - - - name: Cleanup - delete state machine - aws_step_functions_state_machine: - name: "{{ state_machine_name }}" - state: absent - ignore_errors: true - - - name: Cleanup - delete IAM role needed for Step Functions test - iam_role: - name: "{{ step_functions_role_name }}" - state: absent - ignore_errors: true diff --git a/test/integration/targets/incidental_cs_service_offering/aliases b/test/integration/targets/incidental_cs_service_offering/aliases deleted file mode 100644 index e50e650e983..00000000000 --- a/test/integration/targets/incidental_cs_service_offering/aliases +++ /dev/null @@ -1,2 +0,0 @@ -cloud/cs -shippable/cs/incidental diff --git a/test/integration/targets/incidental_cs_service_offering/meta/main.yml b/test/integration/targets/incidental_cs_service_offering/meta/main.yml deleted file mode 100644 index d46613c55fc..00000000000 --- a/test/integration/targets/incidental_cs_service_offering/meta/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -dependencies: - - incidental_cs_common diff --git a/test/integration/targets/incidental_cs_service_offering/tasks/guest_vm_service_offering.yml b/test/integration/targets/incidental_cs_service_offering/tasks/guest_vm_service_offering.yml deleted file mode 100644 index f7aee3c8a28..00000000000 --- a/test/integration/targets/incidental_cs_service_offering/tasks/guest_vm_service_offering.yml +++ /dev/null @@ -1,223 +0,0 @@ ---- -- name: setup service offering - cs_service_offering: - name: Micro - state: absent - register: so -- name: verify setup service offering - assert: - that: - - so is successful - -- name: create service offering in check mode - cs_service_offering: - name: Micro - display_text: Micro 512mb 1cpu - cpu_number: 1 - cpu_speed: 2198 - memory: 512 - host_tags: eco - storage_tags: - - eco - - backup - storage_type: local - register: so - check_mode: true -- name: verify create service offering in check mode - assert: - that: - - so is changed - -- name: create service offering - cs_service_offering: - name: Micro - display_text: Micro 512mb 1cpu - cpu_number: 1 - cpu_speed: 2198 - memory: 512 - host_tags: eco - storage_tags: - - eco - - backup - storage_type: local - register: so -- name: verify create service offering - assert: - that: - - so is changed - - so.name == "Micro" - - so.display_text == "Micro 512mb 1cpu" - - so.cpu_number == 1 - - so.cpu_speed == 2198 - - so.memory == 512 - - so.host_tags == ['eco'] - - so.storage_tags == ['eco', 'backup'] - - so.storage_type == "local" - -- name: create service offering idempotence - cs_service_offering: - name: Micro - display_text: Micro 512mb 1cpu - cpu_number: 1 - cpu_speed: 2198 - memory: 512 - host_tags: eco - storage_tags: - - eco - - backup - storage_type: local - register: so -- name: verify create service offering idempotence - assert: - that: - - so is not changed - - so.name == "Micro" - - so.display_text == "Micro 512mb 1cpu" - - so.cpu_number == 1 - - so.cpu_speed == 2198 - - so.memory == 512 - - so.host_tags == ['eco'] - - so.storage_tags == ['eco', 'backup'] - - so.storage_type == "local" - -- name: update service offering in check mode - cs_service_offering: - name: Micro - display_text: Micro RAM 512MB 1vCPU - register: so - check_mode: true -- name: verify create update offering in check mode - assert: - that: - - so is changed - - so.name == "Micro" - - so.display_text == "Micro 512mb 1cpu" - - so.cpu_number == 1 - - so.cpu_speed == 2198 - - so.memory == 512 - - so.host_tags == ['eco'] - - so.storage_tags == ['eco', 'backup'] - - so.storage_type == "local" - -- name: update service offering - cs_service_offering: - name: Micro - display_text: Micro RAM 512MB 1vCPU - register: so -- name: verify update service offerin - assert: - that: - - so is changed - - so.name == "Micro" - - so.display_text == "Micro RAM 512MB 1vCPU" - - so.cpu_number == 1 - - so.cpu_speed == 2198 - - so.memory == 512 - - so.host_tags == ['eco'] - - so.storage_tags == ['eco', 'backup'] - - so.storage_type == "local" - -- name: update service offering idempotence - cs_service_offering: - name: Micro - display_text: Micro RAM 512MB 1vCPU - register: so -- name: verify update service offering idempotence - assert: - that: - - so is not changed - - so.name == "Micro" - - so.display_text == "Micro RAM 512MB 1vCPU" - - so.cpu_number == 1 - - so.cpu_speed == 2198 - - so.memory == 512 - - so.host_tags == ['eco'] - - so.storage_tags == ['eco', 'backup'] - - so.storage_type == "local" - -- name: remove service offering in check mode - cs_service_offering: - name: Micro - state: absent - check_mode: true - register: so -- name: verify remove service offering in check mode - assert: - that: - - so is changed - - so.name == "Micro" - - so.display_text == "Micro RAM 512MB 1vCPU" - - so.cpu_number == 1 - - so.cpu_speed == 2198 - - so.memory == 512 - - so.host_tags == ['eco'] - - so.storage_tags == ['eco', 'backup'] - - so.storage_type == "local" - -- name: remove service offering - cs_service_offering: - name: Micro - state: absent - register: so -- name: verify remove service offering - assert: - that: - - so is changed - - so.name == "Micro" - - so.display_text == "Micro RAM 512MB 1vCPU" - - so.cpu_number == 1 - - so.cpu_speed == 2198 - - so.memory == 512 - - so.host_tags == ['eco'] - - so.storage_tags == ['eco', 'backup'] - - so.storage_type == "local" - -- name: remove service offering idempotence - cs_service_offering: - name: Micro - state: absent - register: so -- name: verify remove service offering idempotence - assert: - that: - - so is not changed - -- name: create custom service offering - cs_service_offering: - name: custom - display_text: custom offer - is_customized: yes - host_tags: eco - storage_tags: - - eco - - backup - storage_type: local - register: so -- name: verify create custom service offering - assert: - that: - - so is changed - - so.name == "custom" - - so.display_text == "custom offer" - - so.is_customized == True - - so.cpu_number is not defined - - so.cpu_speed is not defined - - so.memory is not defined - - so.host_tags == ['eco'] - - so.storage_tags == ['eco', 'backup'] - - so.storage_type == "local" - -- name: remove custom service offering - cs_service_offering: - name: custom - state: absent - register: so -- name: verify remove service offering - assert: - that: - - so is changed - - so.name == "custom" - - so.display_text == "custom offer" - - so.host_tags == ['eco'] - - so.storage_tags == ['eco', 'backup'] - - so.storage_type == "local" diff --git a/test/integration/targets/incidental_cs_service_offering/tasks/main.yml b/test/integration/targets/incidental_cs_service_offering/tasks/main.yml deleted file mode 100644 index 581f7d74de6..00000000000 --- a/test/integration/targets/incidental_cs_service_offering/tasks/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -- import_tasks: guest_vm_service_offering.yml -- import_tasks: system_vm_service_offering.yml \ No newline at end of file diff --git a/test/integration/targets/incidental_cs_service_offering/tasks/system_vm_service_offering.yml b/test/integration/targets/incidental_cs_service_offering/tasks/system_vm_service_offering.yml deleted file mode 100644 index 4c63a4b9c85..00000000000 --- a/test/integration/targets/incidental_cs_service_offering/tasks/system_vm_service_offering.yml +++ /dev/null @@ -1,151 +0,0 @@ ---- -- name: setup system offering - cs_service_offering: - name: System Offering for Ansible - is_system: true - state: absent - register: so -- name: verify setup system offering - assert: - that: - - so is successful - -- name: fail missing storage type and is_system - cs_service_offering: - name: System Offering for Ansible - cpu_number: 1 - cpu_speed: 500 - memory: 512 - host_tag: perf - storage_tag: perf - storage_type: shared - offer_ha: true - limit_cpu_usage: false - is_system: true - register: so - ignore_errors: true -- name: verify create system service offering in check mode - assert: - that: - - so is failed - - so.msg.startswith('missing required arguments:') - -- name: create system service offering in check mode - cs_service_offering: - name: System Offering for Ansible - cpu_number: 1 - cpu_speed: 500 - memory: 512 - host_tag: perf - storage_tag: perf - storage_type: shared - offer_ha: true - limit_cpu_usage: false - system_vm_type: domainrouter - is_system: true - register: so - check_mode: true -- name: verify create system service offering in check mode - assert: - that: - - so is changed - -- name: create system service offering - cs_service_offering: - name: System Offering for Ansible - cpu_number: 1 - cpu_speed: 500 - memory: 512 - host_tag: perf - storage_tag: perf - storage_type: shared - offer_ha: true - limit_cpu_usage: false - system_vm_type: domainrouter - is_system: true - register: so -- name: verify create system service offering - assert: - that: - - so is changed - - so.name == "System Offering for Ansible" - - so.display_text == "System Offering for Ansible" - - so.cpu_number == 1 - - so.cpu_speed == 500 - - so.memory == 512 - - so.host_tags == ['perf'] - - so.storage_tags == ['perf'] - - so.storage_type == "shared" - - so.offer_ha == true - - so.limit_cpu_usage == false - - so.system_vm_type == "domainrouter" - - so.is_system == true - -- name: create system service offering idempotence - cs_service_offering: - name: System Offering for Ansible - cpu_number: 1 - cpu_speed: 500 - memory: 512 - host_tag: perf - storage_tag: perf - storage_type: shared - offer_ha: true - limit_cpu_usage: false - system_vm_type: domainrouter - is_system: true - register: so -- name: verify create system service offering idempotence - assert: - that: - - so is not changed - - so.name == "System Offering for Ansible" - - so.display_text == "System Offering for Ansible" - - so.cpu_number == 1 - - so.cpu_speed == 500 - - so.memory == 512 - - so.host_tags == ['perf'] - - so.storage_tags == ['perf'] - - so.storage_type == "shared" - - so.offer_ha == true - - so.limit_cpu_usage == false - - so.system_vm_type == "domainrouter" - - so.is_system == true - -- name: remove system service offering in check mode - cs_service_offering: - name: System Offering for Ansible - is_system: true - state: absent - check_mode: true - register: so -- name: verify remove system service offering in check mode - assert: - that: - - so is changed - - so.name == "System Offering for Ansible" - - so.is_system == true - -- name: remove system service offering - cs_service_offering: - name: System Offering for Ansible - is_system: true - state: absent - register: so -- name: verify remove system service offering - assert: - that: - - so is changed - - so.name == "System Offering for Ansible" - - so.is_system == true - -- name: remove system service offering idempotence - cs_service_offering: - name: System Offering for Ansible - is_system: true - state: absent - register: so -- name: verify remove system service offering idempotence - assert: - that: - - so is not changed diff --git a/test/support/integration/plugins/modules/aws_step_functions_state_machine.py b/test/support/integration/plugins/modules/aws_step_functions_state_machine.py deleted file mode 100644 index 329ee4283d4..00000000000 --- a/test/support/integration/plugins/modules/aws_step_functions_state_machine.py +++ /dev/null @@ -1,232 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2019, Tom De Keyser (@tdekeyser) -# 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': 'community' -} - -DOCUMENTATION = ''' ---- -module: aws_step_functions_state_machine - -short_description: Manage AWS Step Functions state machines - -version_added: "2.10" - -description: - - Create, update and delete state machines in AWS Step Functions. - - Calling the module in C(state=present) for an existing AWS Step Functions state machine - will attempt to update the state machine definition, IAM Role, or tags with the provided data. - -options: - name: - description: - - Name of the state machine - required: true - type: str - definition: - description: - - The Amazon States Language definition of the state machine. See - U(https://docs.aws.amazon.com/step-functions/latest/dg/concepts-amazon-states-language.html) for more - information on the Amazon States Language. - - "This parameter is required when C(state=present)." - type: json - role_arn: - description: - - The ARN of the IAM Role that will be used by the state machine for its executions. - - "This parameter is required when C(state=present)." - type: str - state: - description: - - Desired state for the state machine - default: present - choices: [ present, absent ] - type: str - tags: - description: - - A hash/dictionary of tags to add to the new state machine or to add/remove from an existing one. - type: dict - purge_tags: - description: - - If yes, existing tags will be purged from the resource to match exactly what is defined by I(tags) parameter. - If the I(tags) parameter is not set then tags will not be modified. - default: yes - type: bool - -extends_documentation_fragment: - - aws - - ec2 - -author: - - Tom De Keyser (@tdekeyser) -''' - -EXAMPLES = ''' -# Create a new AWS Step Functions state machine -- name: Setup HelloWorld state machine - aws_step_functions_state_machine: - name: "HelloWorldStateMachine" - definition: "{{ lookup('file','state_machine.json') }}" - role_arn: arn:aws:iam::987654321012:role/service-role/invokeLambdaStepFunctionsRole - tags: - project: helloWorld - -# Update an existing state machine -- name: Change IAM Role and tags of HelloWorld state machine - aws_step_functions_state_machine: - name: HelloWorldStateMachine - definition: "{{ lookup('file','state_machine.json') }}" - role_arn: arn:aws:iam::987654321012:role/service-role/anotherStepFunctionsRole - tags: - otherTag: aDifferentTag - -# Remove the AWS Step Functions state machine -- name: Delete HelloWorld state machine - aws_step_functions_state_machine: - name: HelloWorldStateMachine - state: absent -''' - -RETURN = ''' -state_machine_arn: - description: ARN of the AWS Step Functions state machine - type: str - returned: always -''' - -from ansible.module_utils.aws.core import AnsibleAWSModule -from ansible.module_utils.ec2 import ansible_dict_to_boto3_tag_list, AWSRetry, compare_aws_tags, boto3_tag_list_to_ansible_dict - -try: - from botocore.exceptions import ClientError, BotoCoreError -except ImportError: - pass # caught by AnsibleAWSModule - - -def manage_state_machine(state, sfn_client, module): - state_machine_arn = get_state_machine_arn(sfn_client, module) - - if state == 'present': - if state_machine_arn is None: - create(sfn_client, module) - else: - update(state_machine_arn, sfn_client, module) - elif state == 'absent': - if state_machine_arn is not None: - remove(state_machine_arn, sfn_client, module) - - check_mode(module, msg='State is up-to-date.') - module.exit_json(changed=False) - - -def create(sfn_client, module): - check_mode(module, msg='State machine would be created.', changed=True) - - tags = module.params.get('tags') - sfn_tags = ansible_dict_to_boto3_tag_list(tags, tag_name_key_name='key', tag_value_key_name='value') if tags else [] - - state_machine = sfn_client.create_state_machine( - name=module.params.get('name'), - definition=module.params.get('definition'), - roleArn=module.params.get('role_arn'), - tags=sfn_tags - ) - module.exit_json(changed=True, state_machine_arn=state_machine.get('stateMachineArn')) - - -def remove(state_machine_arn, sfn_client, module): - check_mode(module, msg='State machine would be deleted: {0}'.format(state_machine_arn), changed=True) - - sfn_client.delete_state_machine(stateMachineArn=state_machine_arn) - module.exit_json(changed=True, state_machine_arn=state_machine_arn) - - -def update(state_machine_arn, sfn_client, module): - tags_to_add, tags_to_remove = compare_tags(state_machine_arn, sfn_client, module) - - if params_changed(state_machine_arn, sfn_client, module) or tags_to_add or tags_to_remove: - check_mode(module, msg='State machine would be updated: {0}'.format(state_machine_arn), changed=True) - - sfn_client.update_state_machine( - stateMachineArn=state_machine_arn, - definition=module.params.get('definition'), - roleArn=module.params.get('role_arn') - ) - sfn_client.untag_resource( - resourceArn=state_machine_arn, - tagKeys=tags_to_remove - ) - sfn_client.tag_resource( - resourceArn=state_machine_arn, - tags=ansible_dict_to_boto3_tag_list(tags_to_add, tag_name_key_name='key', tag_value_key_name='value') - ) - - module.exit_json(changed=True, state_machine_arn=state_machine_arn) - - -def compare_tags(state_machine_arn, sfn_client, module): - new_tags = module.params.get('tags') - current_tags = sfn_client.list_tags_for_resource(resourceArn=state_machine_arn).get('tags') - return compare_aws_tags(boto3_tag_list_to_ansible_dict(current_tags), new_tags if new_tags else {}, module.params.get('purge_tags')) - - -def params_changed(state_machine_arn, sfn_client, module): - """ - Check whether the state machine definition or IAM Role ARN is different - from the existing state machine parameters. - """ - current = sfn_client.describe_state_machine(stateMachineArn=state_machine_arn) - return current.get('definition') != module.params.get('definition') or current.get('roleArn') != module.params.get('role_arn') - - -def get_state_machine_arn(sfn_client, module): - """ - Finds the state machine ARN based on the name parameter. Returns None if - there is no state machine with this name. - """ - target_name = module.params.get('name') - all_state_machines = sfn_client.list_state_machines(aws_retry=True).get('stateMachines') - - for state_machine in all_state_machines: - if state_machine.get('name') == target_name: - return state_machine.get('stateMachineArn') - - -def check_mode(module, msg='', changed=False): - if module.check_mode: - module.exit_json(changed=changed, output=msg) - - -def main(): - module_args = dict( - name=dict(type='str', required=True), - definition=dict(type='json'), - role_arn=dict(type='str'), - state=dict(choices=['present', 'absent'], default='present'), - tags=dict(default=None, type='dict'), - purge_tags=dict(default=True, type='bool'), - ) - module = AnsibleAWSModule( - argument_spec=module_args, - required_if=[('state', 'present', ['role_arn']), ('state', 'present', ['definition'])], - supports_check_mode=True - ) - - sfn_client = module.client('stepfunctions', retry_decorator=AWSRetry.jittered_backoff(retries=5)) - state = module.params.get('state') - - try: - manage_state_machine(state, sfn_client, module) - except (BotoCoreError, ClientError) as e: - module.fail_json_aws(e, msg='Failed to manage state machine') - - -if __name__ == '__main__': - main() diff --git a/test/support/integration/plugins/modules/aws_step_functions_state_machine_execution.py b/test/support/integration/plugins/modules/aws_step_functions_state_machine_execution.py deleted file mode 100644 index a6e0d7182dd..00000000000 --- a/test/support/integration/plugins/modules/aws_step_functions_state_machine_execution.py +++ /dev/null @@ -1,197 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2019, Prasad Katti (@prasadkatti) -# 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': 'community' -} - -DOCUMENTATION = ''' ---- -module: aws_step_functions_state_machine_execution - -short_description: Start or stop execution of an AWS Step Functions state machine. - -version_added: "2.10" - -description: - - Start or stop execution of a state machine in AWS Step Functions. - -options: - action: - description: Desired action (start or stop) for a state machine execution. - default: start - choices: [ start, stop ] - type: str - name: - description: Name of the execution. - type: str - execution_input: - description: The JSON input data for the execution. - type: json - default: {} - state_machine_arn: - description: The ARN of the state machine that will be executed. - type: str - execution_arn: - description: The ARN of the execution you wish to stop. - type: str - cause: - description: A detailed explanation of the cause for stopping the execution. - type: str - default: '' - error: - description: The error code of the failure to pass in when stopping the execution. - type: str - default: '' - -extends_documentation_fragment: - - aws - - ec2 - -author: - - Prasad Katti (@prasadkatti) -''' - -EXAMPLES = ''' -- name: Start an execution of a state machine - aws_step_functions_state_machine_execution: - name: an_execution_name - execution_input: '{ "IsHelloWorldExample": true }' - state_machine_arn: "arn:aws:states:us-west-2:682285639423:stateMachine:HelloWorldStateMachine" - -- name: Stop an execution of a state machine - aws_step_functions_state_machine_execution: - action: stop - execution_arn: "arn:aws:states:us-west-2:682285639423:execution:HelloWorldStateMachineCopy:a1e8e2b5-5dfe-d40e-d9e3-6201061047c8" - cause: "cause of task failure" - error: "error code of the failure" -''' - -RETURN = ''' -execution_arn: - description: ARN of the AWS Step Functions state machine execution. - type: str - returned: if action == start and changed == True - sample: "arn:aws:states:us-west-2:682285639423:execution:HelloWorldStateMachineCopy:a1e8e2b5-5dfe-d40e-d9e3-6201061047c8" -start_date: - description: The date the execution is started. - type: str - returned: if action == start and changed == True - sample: "2019-11-02T22:39:49.071000-07:00" -stop_date: - description: The date the execution is stopped. - type: str - returned: if action == stop - sample: "2019-11-02T22:39:49.071000-07:00" -''' - - -from ansible.module_utils.aws.core import AnsibleAWSModule -from ansible.module_utils.ec2 import camel_dict_to_snake_dict - -try: - from botocore.exceptions import ClientError, BotoCoreError -except ImportError: - pass # caught by AnsibleAWSModule - - -def start_execution(module, sfn_client): - ''' - start_execution uses execution name to determine if a previous execution already exists. - If an execution by the provided name exists, call client.start_execution will not be called. - ''' - - state_machine_arn = module.params.get('state_machine_arn') - name = module.params.get('name') - execution_input = module.params.get('execution_input') - - try: - # list_executions is eventually consistent - page_iterators = sfn_client.get_paginator('list_executions').paginate(stateMachineArn=state_machine_arn) - - for execution in page_iterators.build_full_result()['executions']: - if name == execution['name']: - check_mode(module, msg='State machine execution already exists.', changed=False) - module.exit_json(changed=False) - - check_mode(module, msg='State machine execution would be started.', changed=True) - res_execution = sfn_client.start_execution( - stateMachineArn=state_machine_arn, - name=name, - input=execution_input - ) - except (ClientError, BotoCoreError) as e: - if e.response['Error']['Code'] == 'ExecutionAlreadyExists': - # this will never be executed anymore - module.exit_json(changed=False) - module.fail_json_aws(e, msg="Failed to start execution.") - - module.exit_json(changed=True, **camel_dict_to_snake_dict(res_execution)) - - -def stop_execution(module, sfn_client): - - cause = module.params.get('cause') - error = module.params.get('error') - execution_arn = module.params.get('execution_arn') - - try: - # describe_execution is eventually consistent - execution_status = sfn_client.describe_execution(executionArn=execution_arn)['status'] - if execution_status != 'RUNNING': - check_mode(module, msg='State machine execution is not running.', changed=False) - module.exit_json(changed=False) - - check_mode(module, msg='State machine execution would be stopped.', changed=True) - res = sfn_client.stop_execution( - executionArn=execution_arn, - cause=cause, - error=error - ) - except (ClientError, BotoCoreError) as e: - module.fail_json_aws(e, msg="Failed to stop execution.") - - module.exit_json(changed=True, **camel_dict_to_snake_dict(res)) - - -def check_mode(module, msg='', changed=False): - if module.check_mode: - module.exit_json(changed=changed, output=msg) - - -def main(): - module_args = dict( - action=dict(choices=['start', 'stop'], default='start'), - name=dict(type='str'), - execution_input=dict(type='json', default={}), - state_machine_arn=dict(type='str'), - cause=dict(type='str', default=''), - error=dict(type='str', default=''), - execution_arn=dict(type='str') - ) - module = AnsibleAWSModule( - argument_spec=module_args, - required_if=[('action', 'start', ['name', 'state_machine_arn']), - ('action', 'stop', ['execution_arn']), - ], - supports_check_mode=True - ) - - sfn_client = module.client('stepfunctions') - - action = module.params.get('action') - if action == "start": - start_execution(module, sfn_client) - else: - stop_execution(module, sfn_client) - - -if __name__ == '__main__': - main() diff --git a/test/support/integration/plugins/modules/cs_service_offering.py b/test/support/integration/plugins/modules/cs_service_offering.py deleted file mode 100644 index 3b15fe7f1e6..00000000000 --- a/test/support/integration/plugins/modules/cs_service_offering.py +++ /dev/null @@ -1,583 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# (c) 2017, René Moser -# 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': 'community'} - -DOCUMENTATION = ''' ---- -module: cs_service_offering -description: - - Create and delete service offerings for guest and system VMs. - - Update display_text of existing service offering. -short_description: Manages service offerings on Apache CloudStack based clouds. -version_added: '2.5' -author: René Moser (@resmo) -options: - disk_bytes_read_rate: - description: - - Bytes read rate of the disk offering. - type: int - aliases: [ bytes_read_rate ] - disk_bytes_write_rate: - description: - - Bytes write rate of the disk offering. - type: int - aliases: [ bytes_write_rate ] - cpu_number: - description: - - The number of CPUs of the service offering. - type: int - cpu_speed: - description: - - The CPU speed of the service offering in MHz. - type: int - limit_cpu_usage: - description: - - Restrict the CPU usage to committed service offering. - type: bool - deployment_planner: - description: - - The deployment planner heuristics used to deploy a VM of this offering. - - If not set, the value of global config I(vm.deployment.planner) is used. - type: str - display_text: - description: - - Display text of the service offering. - - If not set, I(name) will be used as I(display_text) while creating. - type: str - domain: - description: - - Domain the service offering is related to. - - Public for all domains and subdomains if not set. - type: str - host_tags: - description: - - The host tags for this service offering. - type: list - aliases: - - host_tag - hypervisor_snapshot_reserve: - description: - - Hypervisor snapshot reserve space as a percent of a volume. - - Only for managed storage using Xen or VMware. - type: int - is_iops_customized: - description: - - Whether compute offering iops is custom or not. - type: bool - aliases: [ disk_iops_customized ] - disk_iops_read_rate: - description: - - IO requests read rate of the disk offering. - type: int - disk_iops_write_rate: - description: - - IO requests write rate of the disk offering. - type: int - disk_iops_max: - description: - - Max. iops of the compute offering. - type: int - disk_iops_min: - description: - - Min. iops of the compute offering. - type: int - is_system: - description: - - Whether it is a system VM offering or not. - type: bool - default: no - is_volatile: - description: - - Whether the virtual machine needs to be volatile or not. - - Every reboot of VM the root disk is detached then destroyed and a fresh root disk is created and attached to VM. - type: bool - memory: - description: - - The total memory of the service offering in MB. - type: int - name: - description: - - Name of the service offering. - type: str - required: true - network_rate: - description: - - Data transfer rate in Mb/s allowed. - - Supported only for non-system offering and system offerings having I(system_vm_type=domainrouter). - type: int - offer_ha: - description: - - Whether HA is set for the service offering. - type: bool - default: no - provisioning_type: - description: - - Provisioning type used to create volumes. - type: str - choices: - - thin - - sparse - - fat - service_offering_details: - description: - - Details for planner, used to store specific parameters. - - A list of dictionaries having keys C(key) and C(value). - type: list - state: - description: - - State of the service offering. - type: str - choices: - - present - - absent - default: present - storage_type: - description: - - The storage type of the service offering. - type: str - choices: - - local - - shared - system_vm_type: - description: - - The system VM type. - - Required if I(is_system=yes). - type: str - choices: - - domainrouter - - consoleproxy - - secondarystoragevm - storage_tags: - description: - - The storage tags for this service offering. - type: list - aliases: - - storage_tag - is_customized: - description: - - Whether the offering is customizable or not. - type: bool - version_added: '2.8' -extends_documentation_fragment: cloudstack -''' - -EXAMPLES = ''' -- name: Create a non-volatile compute service offering with local storage - cs_service_offering: - name: Micro - display_text: Micro 512mb 1cpu - cpu_number: 1 - cpu_speed: 2198 - memory: 512 - host_tags: eco - storage_type: local - delegate_to: localhost - -- name: Create a volatile compute service offering with shared storage - cs_service_offering: - name: Tiny - display_text: Tiny 1gb 1cpu - cpu_number: 1 - cpu_speed: 2198 - memory: 1024 - storage_type: shared - is_volatile: yes - host_tags: eco - storage_tags: eco - delegate_to: localhost - -- name: Create or update a volatile compute service offering with shared storage - cs_service_offering: - name: Tiny - display_text: Tiny 1gb 1cpu - cpu_number: 1 - cpu_speed: 2198 - memory: 1024 - storage_type: shared - is_volatile: yes - host_tags: eco - storage_tags: eco - delegate_to: localhost - -- name: Create or update a custom compute service offering - cs_service_offering: - name: custom - display_text: custom compute offer - is_customized: yes - storage_type: shared - host_tags: eco - storage_tags: eco - delegate_to: localhost - -- name: Remove a compute service offering - cs_service_offering: - name: Tiny - state: absent - delegate_to: localhost - -- name: Create or update a system offering for the console proxy - cs_service_offering: - name: System Offering for Console Proxy 2GB - display_text: System Offering for Console Proxy 2GB RAM - is_system: yes - system_vm_type: consoleproxy - cpu_number: 1 - cpu_speed: 2198 - memory: 2048 - storage_type: shared - storage_tags: perf - delegate_to: localhost - -- name: Remove a system offering - cs_service_offering: - name: System Offering for Console Proxy 2GB - is_system: yes - state: absent - delegate_to: localhost -''' - -RETURN = ''' ---- -id: - description: UUID of the service offering - returned: success - type: str - sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f -cpu_number: - description: Number of CPUs in the service offering - returned: success - type: int - sample: 4 -cpu_speed: - description: Speed of CPUs in MHz in the service offering - returned: success - type: int - sample: 2198 -disk_iops_max: - description: Max iops of the disk offering - returned: success - type: int - sample: 1000 -disk_iops_min: - description: Min iops of the disk offering - returned: success - type: int - sample: 500 -disk_bytes_read_rate: - description: Bytes read rate of the service offering - returned: success - type: int - sample: 1000 -disk_bytes_write_rate: - description: Bytes write rate of the service offering - returned: success - type: int - sample: 1000 -disk_iops_read_rate: - description: IO requests per second read rate of the service offering - returned: success - type: int - sample: 1000 -disk_iops_write_rate: - description: IO requests per second write rate of the service offering - returned: success - type: int - sample: 1000 -created: - description: Date the offering was created - returned: success - type: str - sample: 2017-11-19T10:48:59+0000 -display_text: - description: Display text of the offering - returned: success - type: str - sample: Micro 512mb 1cpu -domain: - description: Domain the offering is into - returned: success - type: str - sample: ROOT -host_tags: - description: List of host tags - returned: success - type: list - sample: [ 'eco' ] -storage_tags: - description: List of storage tags - returned: success - type: list - sample: [ 'eco' ] -is_system: - description: Whether the offering is for system VMs or not - returned: success - type: bool - sample: false -is_iops_customized: - description: Whether the offering uses custom IOPS or not - returned: success - type: bool - sample: false -is_volatile: - description: Whether the offering is volatile or not - returned: success - type: bool - sample: false -limit_cpu_usage: - description: Whether the CPU usage is restricted to committed service offering - returned: success - type: bool - sample: false -memory: - description: Memory of the system offering - returned: success - type: int - sample: 512 -name: - description: Name of the system offering - returned: success - type: str - sample: Micro -offer_ha: - description: Whether HA support is enabled in the offering or not - returned: success - type: bool - sample: false -provisioning_type: - description: Provisioning type used to create volumes - returned: success - type: str - sample: thin -storage_type: - description: Storage type used to create volumes - returned: success - type: str - sample: shared -system_vm_type: - description: System VM type of this offering - returned: success - type: str - sample: consoleproxy -service_offering_details: - description: Additioanl service offering details - returned: success - type: dict - sample: "{'vgpuType': 'GRID K180Q','pciDevice':'Group of NVIDIA Corporation GK107GL [GRID K1] GPUs'}" -network_rate: - description: Data transfer rate in megabits per second allowed - returned: success - type: int - sample: 1000 -is_customized: - description: Whether the offering is customizable or not - returned: success - type: bool - sample: false - version_added: '2.8' -''' - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.cloudstack import ( - AnsibleCloudStack, - cs_argument_spec, - cs_required_together, -) - - -class AnsibleCloudStackServiceOffering(AnsibleCloudStack): - - def __init__(self, module): - super(AnsibleCloudStackServiceOffering, self).__init__(module) - self.returns = { - 'cpunumber': 'cpu_number', - 'cpuspeed': 'cpu_speed', - 'deploymentplanner': 'deployment_planner', - 'diskBytesReadRate': 'disk_bytes_read_rate', - 'diskBytesWriteRate': 'disk_bytes_write_rate', - 'diskIopsReadRate': 'disk_iops_read_rate', - 'diskIopsWriteRate': 'disk_iops_write_rate', - 'maxiops': 'disk_iops_max', - 'miniops': 'disk_iops_min', - 'hypervisorsnapshotreserve': 'hypervisor_snapshot_reserve', - 'iscustomized': 'is_customized', - 'iscustomizediops': 'is_iops_customized', - 'issystem': 'is_system', - 'isvolatile': 'is_volatile', - 'limitcpuuse': 'limit_cpu_usage', - 'memory': 'memory', - 'networkrate': 'network_rate', - 'offerha': 'offer_ha', - 'provisioningtype': 'provisioning_type', - 'serviceofferingdetails': 'service_offering_details', - 'storagetype': 'storage_type', - 'systemvmtype': 'system_vm_type', - 'tags': 'storage_tags', - } - - def get_service_offering(self): - args = { - 'name': self.module.params.get('name'), - 'domainid': self.get_domain(key='id'), - 'issystem': self.module.params.get('is_system'), - 'systemvmtype': self.module.params.get('system_vm_type'), - } - service_offerings = self.query_api('listServiceOfferings', **args) - if service_offerings: - return service_offerings['serviceoffering'][0] - - def present_service_offering(self): - service_offering = self.get_service_offering() - if not service_offering: - service_offering = self._create_offering(service_offering) - else: - service_offering = self._update_offering(service_offering) - - return service_offering - - def absent_service_offering(self): - service_offering = self.get_service_offering() - if service_offering: - self.result['changed'] = True - if not self.module.check_mode: - args = { - 'id': service_offering['id'], - } - self.query_api('deleteServiceOffering', **args) - return service_offering - - def _create_offering(self, service_offering): - self.result['changed'] = True - - system_vm_type = self.module.params.get('system_vm_type') - is_system = self.module.params.get('is_system') - - required_params = [] - if is_system and not system_vm_type: - required_params.append('system_vm_type') - self.module.fail_on_missing_params(required_params=required_params) - - args = { - 'name': self.module.params.get('name'), - 'displaytext': self.get_or_fallback('display_text', 'name'), - 'bytesreadrate': self.module.params.get('disk_bytes_read_rate'), - 'byteswriterate': self.module.params.get('disk_bytes_write_rate'), - 'cpunumber': self.module.params.get('cpu_number'), - 'cpuspeed': self.module.params.get('cpu_speed'), - 'customizediops': self.module.params.get('is_iops_customized'), - 'deploymentplanner': self.module.params.get('deployment_planner'), - 'domainid': self.get_domain(key='id'), - 'hosttags': self.module.params.get('host_tags'), - 'hypervisorsnapshotreserve': self.module.params.get('hypervisor_snapshot_reserve'), - 'iopsreadrate': self.module.params.get('disk_iops_read_rate'), - 'iopswriterate': self.module.params.get('disk_iops_write_rate'), - 'maxiops': self.module.params.get('disk_iops_max'), - 'miniops': self.module.params.get('disk_iops_min'), - 'issystem': is_system, - 'isvolatile': self.module.params.get('is_volatile'), - 'memory': self.module.params.get('memory'), - 'networkrate': self.module.params.get('network_rate'), - 'offerha': self.module.params.get('offer_ha'), - 'provisioningtype': self.module.params.get('provisioning_type'), - 'serviceofferingdetails': self.module.params.get('service_offering_details'), - 'storagetype': self.module.params.get('storage_type'), - 'systemvmtype': system_vm_type, - 'tags': self.module.params.get('storage_tags'), - 'limitcpuuse': self.module.params.get('limit_cpu_usage'), - 'customized': self.module.params.get('is_customized') - } - if not self.module.check_mode: - res = self.query_api('createServiceOffering', **args) - service_offering = res['serviceoffering'] - return service_offering - - def _update_offering(self, service_offering): - args = { - 'id': service_offering['id'], - 'name': self.module.params.get('name'), - 'displaytext': self.get_or_fallback('display_text', 'name'), - } - if self.has_changed(args, service_offering): - self.result['changed'] = True - - if not self.module.check_mode: - res = self.query_api('updateServiceOffering', **args) - service_offering = res['serviceoffering'] - return service_offering - - def get_result(self, service_offering): - super(AnsibleCloudStackServiceOffering, self).get_result(service_offering) - if service_offering: - if 'hosttags' in service_offering: - self.result['host_tags'] = service_offering['hosttags'].split(',') or [service_offering['hosttags']] - - # Prevent confusion, the api returns a tags key for storage tags. - if 'tags' in service_offering: - self.result['storage_tags'] = service_offering['tags'].split(',') or [service_offering['tags']] - if 'tags' in self.result: - del self.result['tags'] - - return self.result - - -def main(): - argument_spec = cs_argument_spec() - argument_spec.update(dict( - name=dict(required=True), - display_text=dict(), - cpu_number=dict(type='int'), - cpu_speed=dict(type='int'), - limit_cpu_usage=dict(type='bool'), - deployment_planner=dict(), - domain=dict(), - host_tags=dict(type='list', aliases=['host_tag']), - hypervisor_snapshot_reserve=dict(type='int'), - disk_bytes_read_rate=dict(type='int', aliases=['bytes_read_rate']), - disk_bytes_write_rate=dict(type='int', aliases=['bytes_write_rate']), - disk_iops_read_rate=dict(type='int'), - disk_iops_write_rate=dict(type='int'), - disk_iops_max=dict(type='int'), - disk_iops_min=dict(type='int'), - is_system=dict(type='bool', default=False), - is_volatile=dict(type='bool'), - is_iops_customized=dict(type='bool', aliases=['disk_iops_customized']), - memory=dict(type='int'), - network_rate=dict(type='int'), - offer_ha=dict(type='bool'), - provisioning_type=dict(choices=['thin', 'sparse', 'fat']), - service_offering_details=dict(type='list'), - storage_type=dict(choices=['local', 'shared']), - system_vm_type=dict(choices=['domainrouter', 'consoleproxy', 'secondarystoragevm']), - storage_tags=dict(type='list', aliases=['storage_tag']), - state=dict(choices=['present', 'absent'], default='present'), - is_customized=dict(type='bool'), - )) - - module = AnsibleModule( - argument_spec=argument_spec, - required_together=cs_required_together(), - supports_check_mode=True - ) - - acs_so = AnsibleCloudStackServiceOffering(module) - - state = module.params.get('state') - if state == "absent": - service_offering = acs_so.absent_service_offering() - else: - service_offering = acs_so.present_service_offering() - - result = acs_so.get_result(service_offering) - module.exit_json(**result) - - -if __name__ == '__main__': - main()