From 338605882e6062aa5e174b23c6a4388fbc3fe269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Fri, 26 Oct 2018 16:20:00 +0200 Subject: [PATCH] Add support for adding custom query parameters to URL (#46390) --- lib/ansible/module_utils/scaleway.py | 40 ++++++----- .../cloud/scaleway/scaleway_compute.py | 4 +- .../utils/module_docs_fragments/scaleway.py | 5 ++ .../roles/scaleway_compute/defaults/main.yml | 2 + .../roles/scaleway_compute/tasks/main.yml | 1 + .../scaleway_compute/tasks/pagination.yml | 71 +++++++++++++++++++ 6 files changed, 105 insertions(+), 18 deletions(-) create mode 100644 test/legacy/roles/scaleway_compute/tasks/pagination.yml diff --git a/lib/ansible/module_utils/scaleway.py b/lib/ansible/module_utils/scaleway.py index cd0cc137f9d..d6a49bac2a7 100644 --- a/lib/ansible/module_utils/scaleway.py +++ b/lib/ansible/module_utils/scaleway.py @@ -4,6 +4,7 @@ import sys from ansible.module_utils.basic import env_fallback from ansible.module_utils.urls import fetch_url +from ansible.module_utils.six.moves.urllib.parse import urlencode def scaleway_argument_spec(): @@ -12,6 +13,7 @@ def scaleway_argument_spec(): no_log=True, aliases=['oauth_token']), api_url=dict(fallback=(env_fallback, ['SCW_API_URL']), default='https://api.scaleway.com', aliases=['base_url']), api_timeout=dict(type='int', default=30, aliases=['timeout']), + query_parameters=dict(type='dict', default={}), validate_certs=dict(default=True, type='bool'), ) @@ -103,13 +105,19 @@ class Scaleway(object): return results.json.get(self.name) - def _url_builder(self, path): + def _url_builder(self, path, params): + d = self.module.params.get('query_parameters') + if params is not None: + d.update(params) + query_string = urlencode(d, doseq=True) + if path[0] == '/': path = path[1:] - return '%s/%s' % (self.module.params.get('api_url'), path) + return '%s/%s?%s' % (self.module.params.get('api_url'), path, query_string) - def send(self, method, path, data=None, headers=None): - url = self._url_builder(path) + def send(self, method, path, data=None, headers=None, params=None): + url = self._url_builder(path=path, params=params) + self.warn(url) data = self.module.jsonify(data) if headers is not None: @@ -130,23 +138,23 @@ class Scaleway(object): def get_user_agent_string(module): return "ansible %s Python %s" % (module.ansible_version, sys.version.split(' ')[0]) - def get(self, path, data=None, headers=None): - return self.send('GET', path, data, headers) + def get(self, path, data=None, headers=None, params=None): + return self.send(method='GET', path=path, data=data, headers=headers, params=params) - def put(self, path, data=None, headers=None): - return self.send('PUT', path, data, headers) + def put(self, path, data=None, headers=None, params=None): + return self.send(method='PUT', path=path, data=data, headers=headers, params=params) - def post(self, path, data=None, headers=None): - return self.send('POST', path, data, headers) + def post(self, path, data=None, headers=None, params=None): + return self.send(method='POST', path=path, data=data, headers=headers, params=params) - def delete(self, path, data=None, headers=None): - return self.send('DELETE', path, data, headers) + def delete(self, path, data=None, headers=None, params=None): + return self.send(method='DELETE', path=path, data=data, headers=headers, params=params) - def patch(self, path, data=None, headers=None): - return self.send("PATCH", path, data, headers) + def patch(self, path, data=None, headers=None, params=None): + return self.send(method="PATCH", path=path, data=data, headers=headers, params=params) - def update(self, path, data=None, headers=None): - return self.send("UPDATE", path, data, headers) + def update(self, path, data=None, headers=None, params=None): + return self.send(method="UPDATE", path=path, data=data, headers=headers, params=params) def warn(self, x): self.module.warn(str(x)) diff --git a/lib/ansible/modules/cloud/scaleway/scaleway_compute.py b/lib/ansible/modules/cloud/scaleway/scaleway_compute.py index 7193c3f3de9..11925232237 100644 --- a/lib/ansible/modules/cloud/scaleway/scaleway_compute.py +++ b/lib/ansible/modules/cloud/scaleway/scaleway_compute.py @@ -570,8 +570,8 @@ state_strategy = { def find(compute_api, wished_server, per_page=1): compute_api.module.debug("Getting inside find") # Only the name attribute is accepted in the Compute query API - url = 'servers?name=%s&per_page=%d' % (urlquote(wished_server["name"]), per_page) - response = compute_api.get(url) + response = compute_api.get("servers", params={"name": wished_server["name"], + "per_page": per_page}) if not response.ok: msg = 'Error during server search: (%s) %s' % (response.status_code, response.json) diff --git a/lib/ansible/utils/module_docs_fragments/scaleway.py b/lib/ansible/utils/module_docs_fragments/scaleway.py index 69b13695298..b21cad2aa1c 100644 --- a/lib/ansible/utils/module_docs_fragments/scaleway.py +++ b/lib/ansible/utils/module_docs_fragments/scaleway.py @@ -22,6 +22,11 @@ options: - HTTP timeout to Scaleway API in seconds. default: 30 aliases: ['timeout'] + query_parameters: + description: + - List of parameters passed to the query string + type: dict + default: {} validate_certs: description: - Validate SSL certs of the Scaleway API. diff --git a/test/legacy/roles/scaleway_compute/defaults/main.yml b/test/legacy/roles/scaleway_compute/defaults/main.yml index 8f5c90c1786..269c367bd78 100644 --- a/test/legacy/roles/scaleway_compute/defaults/main.yml +++ b/test/legacy/roles/scaleway_compute/defaults/main.yml @@ -5,3 +5,5 @@ scaleway_organization: '{{ scw_org }}' scaleway_region: ams1 scaleway_commerial_type: START1-S scaleway_name: scaleway_compute_test +first_server_name: scaleway_compute_test_first +second_server_name: scaleway_compute_test_second diff --git a/test/legacy/roles/scaleway_compute/tasks/main.yml b/test/legacy/roles/scaleway_compute/tasks/main.yml index 74c542c2305..922b1ea30f6 100644 --- a/test/legacy/roles/scaleway_compute/tasks/main.yml +++ b/test/legacy/roles/scaleway_compute/tasks/main.yml @@ -3,3 +3,4 @@ - include_tasks: state.yml - include_tasks: ip.yml - include_tasks: security_group.yml +- include_tasks: pagination.yml diff --git a/test/legacy/roles/scaleway_compute/tasks/pagination.yml b/test/legacy/roles/scaleway_compute/tasks/pagination.yml new file mode 100644 index 00000000000..0ba108b8478 --- /dev/null +++ b/test/legacy/roles/scaleway_compute/tasks/pagination.yml @@ -0,0 +1,71 @@ +- name: Create a first server + scaleway_compute: + name: '{{ first_server_name }}' + state: present + image: '{{ scaleway_image_id }}' + organization: '{{ scaleway_organization }}' + region: '{{ scaleway_region }}' + commercial_type: '{{ scaleway_commerial_type }}' + wait: true + +- name: Create a second server + scaleway_compute: + name: '{{ second_server_name }}' + state: present + image: '{{ scaleway_image_id }}' + organization: '{{ scaleway_organization }}' + region: '{{ scaleway_region }}' + commercial_type: '{{ scaleway_commerial_type }}' + wait: true + +- name: Get server informations of the first page + scaleway_server_facts: + region: par1 + query_parameters: + per_page: 1 + page: 1 + register: first_page + +- debug: var=first_page + +- assert: + that: + - first_page is success + +- name: Get server informations of the second page + scaleway_server_facts: + region: par1 + query_parameters: + per_page: 1 + page: 2 + register: second_page + +- debug: var=second_page + +- assert: + that: + - second_page is success + +- assert: + that: + - first_page.ansible_facts.scaleway_server_facts[0].id != second_page.ansible_facts.scaleway_server_facts[0].id + +- name: Delete first server + scaleway_compute: + name: '{{ first_server_name }}' + state: absent + image: '{{ scaleway_image_id }}' + organization: '{{ scaleway_organization }}' + region: '{{ scaleway_region }}' + commercial_type: '{{ scaleway_commerial_type }}' + wait: true + +- name: Delete second server + scaleway_compute: + name: '{{ second_server_name }}' + state: absent + image: '{{ scaleway_image_id }}' + organization: '{{ scaleway_organization }}' + region: '{{ scaleway_region }}' + commercial_type: '{{ scaleway_commerial_type }}' + wait: true