diff --git a/lib/ansible/modules/network/netscaler/netscaler_servicegroup.py b/lib/ansible/modules/network/netscaler/netscaler_servicegroup.py index e39aec53d7..74da6ac452 100644 --- a/lib/ansible/modules/network/netscaler/netscaler_servicegroup.py +++ b/lib/ansible/modules/network/netscaler/netscaler_servicegroup.py @@ -314,6 +314,16 @@ options: description: - Weight to assign to the binding between the monitor and servicegroup. + disabled: + description: + - When set to C(yes) the service group state will be set to DISABLED. + - When set to C(no) the service group state will be set to ENABLED. + - >- + Note that due to limitations of the underlying NITRO API a C(disabled) state change alone + does not cause the module result to report a changed status. + type: bool + default: false + extends_documentation_fragment: netscaler requirements: @@ -618,6 +628,16 @@ def diff(client, module, servicegroup_proxy): return diff_object +def do_state_change(client, module, servicegroup_proxy): + if module.params['disabled']: + log('Disabling service') + result = servicegroup.disable(client, servicegroup_proxy.actual) + else: + log('Enabling service') + result = servicegroup.enable(client, servicegroup_proxy.actual) + return result + + def main(): module_specific_arguments = dict( @@ -730,6 +750,10 @@ def main(): hand_inserted_arguments = dict( servicemembers=dict(type='list'), monitorbindings=dict(type='list'), + disabled=dict( + type='bool', + default=False, + ), ) argument_spec = dict() @@ -912,6 +936,12 @@ def main(): client.save_config() module_result['changed'] = True + if not module.check_mode: + res = do_state_change(client, module, servicegroup_proxy) + if res.errorcode != 0: + msg = 'Error when setting disabled state. errorcode: %s message: %s' % (res.errorcode, res.message) + module.fail_json(msg=msg, **module_result) + # Sanity check for state if not module.check_mode: log('Sanity checks for state present') diff --git a/test/integration/roles/netscaler_servicegroup/tests/nitro/flap_disabled.yaml b/test/integration/roles/netscaler_servicegroup/tests/nitro/flap_disabled.yaml new file mode 100644 index 0000000000..23b6a03194 --- /dev/null +++ b/test/integration/roles/netscaler_servicegroup/tests/nitro/flap_disabled.yaml @@ -0,0 +1,9 @@ +--- + +- include: "{{ role_path }}/tests/nitro/flap_disabled/setup.yaml" + vars: + check_mode: no + +- include: "{{ role_path }}/tests/nitro/flap_disabled/remove.yaml" + vars: + check_mode: no diff --git a/test/integration/roles/netscaler_servicegroup/tests/nitro/flap_disabled/remove.yaml b/test/integration/roles/netscaler_servicegroup/tests/nitro/flap_disabled/remove.yaml new file mode 100644 index 0000000000..3d76e7cf98 --- /dev/null +++ b/test/integration/roles/netscaler_servicegroup/tests/nitro/flap_disabled/remove.yaml @@ -0,0 +1,16 @@ +--- + +- name: Remove servicegroup + delegate_to: localhost + register: result + check_mode: "{{ check_mode }}" + netscaler_servicegroup: + + nitro_user: "{{nitro_user}}" + nitro_pass: "{{nitro_pass}}" + nsip: "{{nsip}}" + + state: absent + + servicegroupname: service-group-1 + servicetype: HTTP diff --git a/test/integration/roles/netscaler_servicegroup/tests/nitro/flap_disabled/setup.yaml b/test/integration/roles/netscaler_servicegroup/tests/nitro/flap_disabled/setup.yaml new file mode 100644 index 0000000000..833b449606 --- /dev/null +++ b/test/integration/roles/netscaler_servicegroup/tests/nitro/flap_disabled/setup.yaml @@ -0,0 +1,47 @@ +--- + +- name: Flap servicegroup + delegate_to: localhost + register: result + check_mode: "{{ check_mode }}" + netscaler_servicegroup: + + nitro_user: "{{nitro_user}}" + nitro_pass: "{{nitro_pass}}" + nsip: "{{nsip}}" + state: present + + + servicegroupname: service-group-1 + servicetype: HTTP + servicemembers: + - ip: 10.78.78.78 + port: 80 + weight: 100 + + disabled: "{{ item|int % 2 }}" + with_sequence: count=20 + delay: 1 + +- name: Flap servicegroup + delegate_to: localhost + register: result + check_mode: "{{ check_mode }}" + netscaler_servicegroup: + + nitro_user: "{{nitro_user}}" + nitro_pass: "{{nitro_pass}}" + nsip: "{{nsip}}" + state: present + + + servicegroupname: service-group-1 + servicetype: HTTP + servicemembers: + - ip: 10.78.78.78 + port: 80 + weight: 100 + + disabled: "{{ item|int % 2 }}" + with_sequence: count=20 + delay: 5 diff --git a/test/units/modules/network/netscaler/test_netscaler_servicegroup.py b/test/units/modules/network/netscaler/test_netscaler_servicegroup.py index 7a51233762..05c56acb73 100644 --- a/test/units/modules/network/netscaler/test_netscaler_servicegroup.py +++ b/test/units/modules/network/netscaler/test_netscaler_servicegroup.py @@ -163,6 +163,7 @@ class TestNetscalerServicegroupModule(TestModule): ConfigProxy=m, servicegroup_exists=servicegroup_exists_mock, servicemembers_identical=Mock(side_effect=[False, True]), + do_state_change=Mock(return_value=Mock(errorcode=0)), nitro_exception=self.MockException, ): self.module = netscaler_servicegroup @@ -191,6 +192,7 @@ class TestNetscalerServicegroupModule(TestModule): servicegroup_identical=servicegroup_identical_mock, monitor_bindings_identical=monitor_bindings_identical_mock, servicemembers_identical=Mock(side_effect=[True, True]), + do_state_change=Mock(return_value=Mock(errorcode=0)), nitro_exception=self.MockException, ): self.module = netscaler_servicegroup @@ -222,6 +224,7 @@ class TestNetscalerServicegroupModule(TestModule): nitro_exception=self.MockException, servicemembers_identical=Mock(side_effect=[True, True]), sync_monitor_bindings=sync_monitor_bindings_mock, + do_state_change=Mock(return_value=Mock(errorcode=0)), ): self.module = netscaler_servicegroup result = self.exited() @@ -250,7 +253,7 @@ class TestNetscalerServicegroupModule(TestModule): sync_monitor_bindings=Mock(), servicemembers_identical=Mock(side_effect=[False, True]), sync_service_members=sync_mock, - + do_state_change=Mock(return_value=Mock(errorcode=0)), ): self.module = netscaler_servicegroup result = self.exited() @@ -304,7 +307,7 @@ class TestNetscalerServicegroupModule(TestModule): servicemembers_identical=Mock(side_effect=[False, True]), nitro_exception=self.MockException, sync_service_members=sync_mock, - + do_state_change=Mock(return_value=Mock(errorcode=0)), ): self.module = netscaler_servicegroup result = self.failed() @@ -332,7 +335,7 @@ class TestNetscalerServicegroupModule(TestModule): servicemembers_identical=Mock(side_effect=[False, True]), nitro_exception=self.MockException, sync_service_members=sync_mock, - + do_state_change=Mock(return_value=Mock(errorcode=0)), ): self.module = netscaler_servicegroup result = self.failed() @@ -360,7 +363,7 @@ class TestNetscalerServicegroupModule(TestModule): servicemembers_identical=Mock(side_effect=[False, False]), nitro_exception=self.MockException, sync_service_members=sync_mock, - + do_state_change=Mock(return_value=Mock(errorcode=0)), ): self.module = netscaler_servicegroup result = self.failed() @@ -388,7 +391,7 @@ class TestNetscalerServicegroupModule(TestModule): servicemembers_identical=Mock(side_effect=[True, True]), nitro_exception=self.MockException, sync_service_members=sync_mock, - + do_state_change=Mock(return_value=Mock(errorcode=0)), ): self.module = netscaler_servicegroup result = self.failed() @@ -415,6 +418,7 @@ class TestNetscalerServicegroupModule(TestModule): servicegroup_identical=servicegroup_identical_mock, servicemembers_identical=Mock(side_effect=[True, True]), monitor_bindings_identical=monitor_bindings_identical_mock, + do_state_change=Mock(return_value=Mock(errorcode=0)), nitro_exception=self.MockException, ): self.module = netscaler_servicegroup