diff options
author | Petr Ospalý <p.ospaly@partner.samsung.com> | 2019-03-26 22:13:00 +0100 |
---|---|---|
committer | Petr Ospalý <p.ospaly@partner.samsung.com> | 2019-04-17 10:49:58 +0200 |
commit | 2bfe0f938efb70dba4454ea9a68a4af304fe6afc (patch) | |
tree | fc685202209e6cbd609822192cbf844edb4273f8 /ansible | |
parent | 45fa0030abb4c013722f68c1ef23d53ba1d1620e (diff) |
Add support for rancher 1.6 API
- New ansible module to handle rancher API
- Setting up of the cattle db and log related options
to achieve lower space usage.
As of this moment it does what was intended:
- it setups new values for db and log related options
- it can be used for any other setting options
Change-Id: I25048469df0cb035cc6eac39740210cdfa175ada
Issue-ID: OOM-1681
Signed-off-by: Petr Ospalý <p.ospaly@partner.samsung.com>
Diffstat (limited to 'ansible')
-rw-r--r-- | ansible/library/rancher1_api.py | 242 | ||||
-rw-r--r-- | ansible/roles/rancher/defaults/main.yml | 17 | ||||
-rw-r--r-- | ansible/roles/rancher/tasks/rancher_server.yml | 23 |
3 files changed, 282 insertions, 0 deletions
diff --git a/ansible/library/rancher1_api.py b/ansible/library/rancher1_api.py new file mode 100644 index 00000000..ce3df1b8 --- /dev/null +++ b/ansible/library/rancher1_api.py @@ -0,0 +1,242 @@ +#!/usr/bin/python + +from ansible.module_utils.basic import AnsibleModule + +import requests +import json +import functools + +DOCUMENTATION = """ +--- +module: rancher1_api +short_description: Client library for rancher API +description: + - This module modifies a rancher 1.6 using it's API (v1). + - WIP, as of now it can only change a current value to a new one. + +options: + rancher: + description: + - The domain name or the IP address and the port of the rancher + where API is exposed. + - For example: http://10.0.0.1:8080 + required: true + aliases: + - server + - rancher_url + - rancher_api + - api + - url + category: + description: + - The path in JSON API without the last element. + required: false + default: settings + aliases: + - rancher_category + - api_category + option: + description: + - The name of the settings option. + required: true + aliases: + - name + - key + - settings + value: + description: + - A new value to replace the current one. + required: true + timeout: + description: + - How long in seconds to wait for a response before raising error + required: false + default: 10.0 +""" + + +def _decorate_rancher_api_request(request_method): + + @functools.wraps(request_method) + def wrap_request(*args, **kwargs): + + response = request_method(*args, **kwargs) + + if response.status_code != requests.codes.ok: + response.raise_for_status() + + try: + json_data = response.json() + except Exception: + json_data = None + + return json_data + + return wrap_request + + +@_decorate_rancher_api_request +def get_rancher_api_value(url, headers=None, timeout=10.0, + username=None, password=None): + + if username and password: + return requests.get(url, headers=headers, + timeout=timeout, + allow_redirects=False, + auth=(username, password)) + else: + return requests.get(url, headers=headers, + timeout=timeout, + allow_redirects=False) + + +@_decorate_rancher_api_request +def set_rancher_api_value(url, payload, headers=None, timeout=10.0, + username=None, password=None): + + if username and password: + return requests.put(url, headers=headers, + timeout=timeout, + allow_redirects=False, + data=json.dumps(payload), + auth=(username, password)) + else: + return requests.put(url, headers=headers, + timeout=timeout, + allow_redirects=False, + data=json.dumps(payload)) + + +def create_rancher_api_payload(json_data, new_value): + + payload = {} + + try: + api_id = json_data['id'] + api_activeValue = json_data['activeValue'] + api_name = json_data['name'] + api_source = json_data['source'] + except Exception: + raise ValueError + + payload.update({"activeValue": api_activeValue, + "id": api_id, + "name": api_name, + "source": api_source, + "value": new_value}) + + if api_activeValue != new_value: + differs = True + else: + differs = False + + return differs, payload + + +def is_valid_rancher_api_option(json_data): + + try: + api_activeValue = json_data['activeValue'] + api_source = json_data['source'] + except Exception: + return False + + if api_activeValue is None and api_source is None: + return False + + return True + + +def main(): + module = AnsibleModule( + argument_spec=dict( + rancher=dict(type='str', required=True, + aliases=['server', + 'rancher_api', + 'rancher_url', + 'api', + 'url']), + category=dict(type='str', default='settings', + aliases=['rancher_category', 'api_category']), + option=dict(type='str', required=True, + aliases=['name', 'key', 'settings']), + value=dict(type='str', required=True), + timeout=dict(type='float', default=10.0), + ), + supports_check_mode=True + ) + + rancher_url = module.params['rancher'].strip('/') + rancher_option = module.params['option'].strip('/') + rancher_category = module.params['category'] + rancher_value = module.params['value'] + rancher_timeout = module.params['timeout'] + # cattle_access_key = '' + # cattle_secret_key = '' + + # Assemble API url + request_url = rancher_url + '/v1/' + rancher_category + '/' \ + + rancher_option + + http_headers = {'Content-Type': 'application/json', + 'Accept': 'application/json'} + + # API get current value + try: + json_response = get_rancher_api_value(request_url, + headers=http_headers, + timeout=rancher_timeout) + except requests.HTTPError as e: + module.fail_json(msg=str(e)) + except requests.Timeout as e: + module.fail_json(msg=str(e)) + + if not json_response: + module.fail_json(msg='ERROR: BAD RESPONSE (GET) - no json value \ + in the response') + + if is_valid_rancher_api_option(json_response): + valid = True + try: + differs, payload = create_rancher_api_payload(json_response, + rancher_value) + except ValueError: + module.fail_json(msg='ERROR: INVALID JSON - missing json values \ + in the response') + else: + valid = False + + if valid and differs and module.check_mode: + # ansible dry-run mode + changed = True + elif valid and differs: + # API set new value + try: + json_response = set_rancher_api_value(request_url, + payload, + headers=http_headers, + timeout=rancher_timeout) + except requests.HTTPError as e: + module.fail_json(msg=str(e)) + except requests.Timeout as e: + module.fail_json(msg=str(e)) + + if not json_response: + module.fail_json(msg='ERROR: BAD RESPONSE (PUT) - no json value \ + in the response') + else: + changed = True + else: + changed = False + + if changed: + msg = "Option '%s' is now set to the new value: %s" \ + % (rancher_option, rancher_value) + else: + msg = "Option '%s' is unchanged." % (rancher_option) + + module.exit_json(changed=changed, msg=msg) + + +if __name__ == '__main__': + main() diff --git a/ansible/roles/rancher/defaults/main.yml b/ansible/roles/rancher/defaults/main.yml index 6ab52e64..67e581cd 100644 --- a/ansible/roles/rancher/defaults/main.yml +++ b/ansible/roles/rancher/defaults/main.yml @@ -4,3 +4,20 @@ rancher_remove_other_env: true rancher_redeploy_k8s_env: true rancher_cluster_health_state: healthy rancher_cluster_health_check_retries: 30 +rancher: + # The following variables can be set via the UI under advanced/settings. + # All of these affect tables in the cattle db and are uninteresting + # to the user (they serve the internal logic of the cattle), but + # they can eat a lot of space when a deployment is busy or faulty. + # + # Audit-Log is the only user-facing option here and it is represented + # in the UI. + # + # Auto-purge deleted entries from most tables after this long (seconds) + main_tables_purge_after_seconds: 28800 # 8 hours + # Auto-purge Event entries after this long (seconds) + events_purge_after_seconds: 28800 # 8 hours + # Auto-purge Service Log entries after this long (seconds) + service_log_purge_after_seconds: 86400 # 1 day + # Auto-purge Audit Log entries after this long (seconds) + audit_log_purge_after_seconds: 2592000 # 30 days diff --git a/ansible/roles/rancher/tasks/rancher_server.yml b/ansible/roles/rancher/tasks/rancher_server.yml index e1eb5a5d..add7b3c9 100644 --- a/ansible/roles/rancher/tasks/rancher_server.yml +++ b/ansible/roles/rancher/tasks/rancher_server.yml @@ -39,3 +39,26 @@ key_private: "{{ env.data.apikey.private }}" rancher_agent_image: "{{ env.data.registration_tokens.image }}" rancher_agent_reg_url: "{{ env.data.registration_tokens.reg_url }}" + +- name: Configure the size of the rancher cattle db and logs + block: + - name: Main tables + rancher1_api: + server: "{{ rancher_server_url }}" + option: main_tables.purge.after.seconds + value: "{{ rancher.main_tables_purge_after_seconds }}" + - name: Events + rancher1_api: + server: "{{ rancher_server_url }}" + option: events.purge.after.seconds + value: "{{ rancher.events_purge_after_seconds }}" + - name: Service log + rancher1_api: + server: "{{ rancher_server_url }}" + option: service_log.purge.after.seconds + value: "{{ rancher.service_log_purge_after_seconds }}" + - name: Audit log + rancher1_api: + server: "{{ rancher_server_url }}" + option: audit_log.purge.after.seconds + value: "{{ rancher.audit_log_purge_after_seconds }}" |