Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

377 bug gslbservice module breaks idempotency due to ip parameter not handled correctly #381

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [2.5.1] - 2024-03-11

### Fixed

- Fixed gslbservice idempotency issues ([#377])

## [2.5.0] - 2024-02-22

### Added
Expand Down Expand Up @@ -104,7 +110,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Initial Release

[unreleased]: https://github.com/netscaler/ansible-collection-netscaleradc/compare/2.5.0...HEAD
[unreleased]: https://github.com/netscaler/ansible-collection-netscaleradc/compare/2.5.1...HEAD
[2.5.1]: https://github.com/netscaler/ansible-collection-netscaleradc/compare/2.5.0...2.5.1
[2.5.0]: https://github.com/netscaler/ansible-collection-netscaleradc/compare/2.4.0...2.5.0
[2.4.0]: https://github.com/netscaler/ansible-collection-netscaleradc/compare/2.3.0...2.4.0
[2.3.0]: https://github.com/netscaler/ansible-collection-netscaleradc/compare/2.2.0...2.3.0
Expand Down Expand Up @@ -137,4 +144,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#360]: https://github.com/netscaler/ansible-collection-netscaleradc/issues/360
[#362]: https://github.com/netscaler/ansible-collection-netscaleradc/issues/362
[#365]: https://github.com/netscaler/ansible-collection-netscaleradc/issues/365
[#367]: https://github.com/netscaler/ansible-collection-netscaleradc/issues/367
[#367]: https://github.com/netscaler/ansible-collection-netscaleradc/issues/367
[#377]: https://github.com/netscaler/ansible-collection-netscaleradc/issues/377
2 changes: 1 addition & 1 deletion galaxy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace: netscaler
# The name of the collection. Has the same character restrictions as 'namespace'
name: adc
# The version of the collection. Must be compatible with semantic versioning
version: 2.5.0
version: 2.5.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 <email> (url)
Expand Down
13 changes: 13 additions & 0 deletions plugins/module_utils/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@
"sslcertkey": {"password"},
}

# NITRO accepts some attributes with a name and responsds with a different name in its GET reponse.
# Eg: For "gslbservice" resource, NITRO expects "ip" in POST request
# but expects "ipaddress" in PUT payload and returns "ipaddress" in GET response.
NITRO_ATTRIBUTES_ALIASES = {
# "resource": {
# "attribute": "attribute_alias",
# }
"gslbservice": {
"ip": "ipaddress",
"ipaddress": "ip", # For PUT payloads and GET responses
}
}

# https://docs.ansible.com/ansible/latest/dev_guide/developing_program_flow_modules.html#argument-spec
NETSCALER_COMMON_ARGUMENTS = dict(
nsip=dict(
Expand Down
23 changes: 23 additions & 0 deletions plugins/module_utils/module_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
ATTRIBUTES_NOT_PRESENT_IN_GET_RESPONSE,
HTTP_RESOURCE_ALREADY_EXISTS,
NETSCALER_COMMON_ARGUMENTS,
NITRO_ATTRIBUTES_ALIASES,
)
from .decorators import trace
from .logger import log, loglines
Expand Down Expand Up @@ -175,6 +176,18 @@ def _filter_desired_bindings(self):
% (self.resource_name, self.desired_bindings)
)

@trace
def _add_nitro_attributes_aliases(self, payload):
for k, v in payload.copy().items():
if k in NITRO_ATTRIBUTES_ALIASES[self.resource_name]:
alias_key = NITRO_ATTRIBUTES_ALIASES[self.resource_name][k]
log(
"DEBUG: Found alias key `%s` for `%s`. Adding the alias key to resource_module_params"
% (alias_key, k)
)
payload[alias_key] = v
return payload

@trace
def _filter_resource_module_params(self):
log("DEBUG: self.module.params: %s" % self.module.params)
Expand All @@ -188,6 +201,11 @@ def _filter_resource_module_params(self):
# Also, filter out attributes ending with `_binding` as they are handled separately
if v is not None:
self.resource_module_params[k] = v

if self.resource_name in NITRO_ATTRIBUTES_ALIASES:
self.resource_module_params = self._add_nitro_attributes_aliases(
self.resource_module_params
)
log(
"DEBUG: Desired `%s` module specific params are: %s"
% (self.resource_name, self.resource_module_params)
Expand Down Expand Up @@ -216,6 +234,11 @@ def get_existing_resource(self):

self.existing_resource = existing_resource[0]

if self.resource_name in NITRO_ATTRIBUTES_ALIASES:
self.existing_resource = self._add_nitro_attributes_aliases(
self.existing_resource
)

# The below return is not mandatory. However, required for debugging purpose
return self.existing_resource

Expand Down
3 changes: 3 additions & 0 deletions tests/integration/targets/gslbservice/aliases
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
gather_facts/no
netscaler/cpx/
netscaler/vpx/
147 changes: 147 additions & 0 deletions tests/integration/targets/gslbservice/tasks/main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
---
- name: Include prerequisite tasks
ansible.builtin.include_tasks: setup.yaml
- name: GSLBSERVICE | ADD | --check
delegate_to: localhost
register: result
check_mode: true
tags: test
netscaler.adc.gslbservice:
nsip: "{{ nsip }}"
nitro_user: "{{ nitro_user }}"
nitro_pass: "{{ nitro_pass }}"
nitro_protocol: "{{ nitro_protocol }}"
validate_certs: "{{ validate_certs }}"
save_config: "{{ save_config }}"
state: present
ip: 10.10.10.10
port: 65530
servicename: test-gslb-service
servicetype: TCP
sitename: test-gslbsite
- name: Assert | GSLBSERVICE | ADD | --check
tags: test
ansible.builtin.assert:
that:
- "result.failed==false"
- "result.changed==true"
- name: GSLBSERVICE | ADD
delegate_to: localhost
register: result
check_mode: false
tags: test
netscaler.adc.gslbservice:
nsip: "{{ nsip }}"
nitro_user: "{{ nitro_user }}"
nitro_pass: "{{ nitro_pass }}"
nitro_protocol: "{{ nitro_protocol }}"
validate_certs: "{{ validate_certs }}"
save_config: "{{ save_config }}"
state: present
ip: 10.10.10.10
port: 65530
servicename: test-gslb-service
servicetype: TCP
sitename: test-gslbsite
- name: Assert | GSLBSERVICE | ADD
ansible.builtin.assert:
that:
- "result.failed==false"
- "result.changed==true"
- name: GSLBSERVICE | ADD | idempotent
delegate_to: localhost
register: result
check_mode: false
tags: test
netscaler.adc.gslbservice:
nsip: "{{ nsip }}"
nitro_user: "{{ nitro_user }}"
nitro_pass: "{{ nitro_pass }}"
nitro_protocol: "{{ nitro_protocol }}"
validate_certs: "{{ validate_certs }}"
save_config: "{{ save_config }}"
state: present
ip: 10.10.10.10
port: 65530
servicename: test-gslb-service
servicetype: TCP
sitename: test-gslbsite
- name: Assert | GSLBSERVICE | ADD | idempotent
tags: test
ansible.builtin.assert:
that:
- "result.failed==false"
- "result.changed==false"
- name: GSLBSERVICE | DELETE | --check
delegate_to: localhost
register: result
check_mode: true
tags: test
netscaler.adc.gslbservice:
nsip: "{{ nsip }}"
nitro_user: "{{ nitro_user }}"
nitro_pass: "{{ nitro_pass }}"
nitro_protocol: "{{ nitro_protocol }}"
validate_certs: "{{ validate_certs }}"
save_config: "{{ save_config }}"
state: absent
ip: 10.10.10.10
port: 65530
servicename: test-gslb-service
servicetype: TCP
sitename: test-gslbsite
- name: Assert | GSLBSERVICE | DELETE | --check
tags: test
ansible.builtin.assert:
that:
- "result.failed==false"
- "result.changed==true"
- name: GSLBSERVICE | DELETE
delegate_to: localhost
register: result
check_mode: false
tags: test
netscaler.adc.gslbservice:
nsip: "{{ nsip }}"
nitro_user: "{{ nitro_user }}"
nitro_pass: "{{ nitro_pass }}"
nitro_protocol: "{{ nitro_protocol }}"
validate_certs: "{{ validate_certs }}"
save_config: "{{ save_config }}"
state: absent
ip: 10.10.10.10
port: 65530
servicename: test-gslb-service
servicetype: TCP
sitename: test-gslbsite
- name: Assert | GSLBSERVICE | DELETE
ansible.builtin.assert:
that:
- "result.failed==false"
- "result.changed==true"
- name: GSLBSERVICE | DELETE | idempotent
delegate_to: localhost
register: result
check_mode: false
tags: test
netscaler.adc.gslbservice:
nsip: "{{ nsip }}"
nitro_user: "{{ nitro_user }}"
nitro_pass: "{{ nitro_pass }}"
nitro_protocol: "{{ nitro_protocol }}"
validate_certs: "{{ validate_certs }}"
save_config: "{{ save_config }}"
state: absent
ip: 10.10.10.10
port: 65530
servicename: test-gslb-service
servicetype: TCP
sitename: test-gslbsite
- name: Assert | GSLBSERVICE | DELETE | idempotent
tags: test
ansible.builtin.assert:
that:
- "result.failed==false"
- "result.changed==false"
- name: Include prerequisite tasks
ansible.builtin.include_tasks: teardown.yaml
13 changes: 13 additions & 0 deletions tests/integration/targets/gslbservice/tasks/setup.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
- name: Sample Task | service
delegate_to: localhost
netscaler.adc.gslbsite:
nsip: "{{ nsip }}"
nitro_user: "{{ nitro_user }}"
nitro_pass: "{{ nitro_pass }}"
nitro_protocol: "{{ nitro_protocol }}"
validate_certs: "{{ validate_certs }}"
save_config: "{{ save_config }}"
state: present
sitename: test-gslbsite
siteipaddress: 10.10.10.10
13 changes: 13 additions & 0 deletions tests/integration/targets/gslbservice/tasks/teardown.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
- name: Sample Task | service
delegate_to: localhost
netscaler.adc.gslbsite:
nsip: "{{ nsip }}"
nitro_user: "{{ nitro_user }}"
nitro_pass: "{{ nitro_pass }}"
nitro_protocol: "{{ nitro_protocol }}"
validate_certs: "{{ validate_certs }}"
save_config: "{{ save_config }}"
state: absent
sitename: test-gslbsite
siteipaddress: 10.10.10.10
3 changes: 3 additions & 0 deletions tests/integration/targets/gslbsite/aliases
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
gather_facts/no
netscaler/cpx/
netscaler/vpx/
Loading