From 53c45245784ee8615472161d8fb31e91d9700f33 Mon Sep 17 00:00:00 2001 From: Sean Holung Date: Thu, 3 Nov 2016 10:37:32 -0500 Subject: [PATCH 1/5] added module for meta api --- clc_ansible_module/clc_meta.py | 96 ++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 clc_ansible_module/clc_meta.py diff --git a/clc_ansible_module/clc_meta.py b/clc_ansible_module/clc_meta.py new file mode 100644 index 0000000..490c432 --- /dev/null +++ b/clc_ansible_module/clc_meta.py @@ -0,0 +1,96 @@ +#!/usr/bin/python + +import requests + +class ClcMetaFact: + + def __init__(self, module): + self.module = module + self.api_url = '' + self.headers = {} + + self._set_clc_credentials_from_env() + + def _set_clc_credentials_from_env(self): + """ + Set the CLC Credentials by reading environment variables + :return: none + """ + env = os.environ + v2_api_token = env.get('CLC_V2_API_TOKEN', False) + self.api_url = env.get('RUNNER_META_API_URL', '') + self.headers = { + "Authorization": "Bearer " + v2_api_token + } + + + def create_meta(self, accountAlias, refId, attributes): + # requests.post(self.api_url, payload, header) + changed = False + url = self.api_url + "/" + accountAlias + json = {'referenceId': refId, + 'attributes': attributes} + result = requests.post(url, json=json, headers=self.headers) + if result.status_code == 200: + changed = True + return changed, result.json() + + def find_meta(self, accountAlias, refId): + url = self.api_url + "/" + accountAlias + "?referenceId=" + refId + return False, requests.get(url, headers=self.headers).json() + + def delete_meta(self, accountAlias, id): + changed = False + url = self.api_url + "/" + accountAlias + "/" + id + result = requests.delete(url, headers=self.headers) + if result.status_code == 204: + changed = True + return changed, {} + else: + self.module.fail_json("Unable to delete the meta data " + result.content) + + + def process_request(self): + params = self.module.params + action = params.get('action') + if action == 'create': + return self.create_meta(params.get('accountAlias'), params.get('referenceId'), params.get('attributes')) + elif action == 'fetch': + return self.find_meta(params.get('accountAlias'), params.get('referenceId')) + elif action == 'delete': + return self.delete_meta(params.get('accountAlias'), params.get('id')) + + + @staticmethod + def _define_module_argument_spec(): + """ + Define the argument spec for the ansible module + :return: argument spec dictionary + """ + argument_spec = dict( + accountAlias=dict(type='str'), + referenceId=dict(type='str'), + attributes=dict(type='dict'), + id=dict(type='str'), + action=dict(type='str')) + + + return {"argument_spec": argument_spec} + + +def main(): + """ + The main function. Instantiates the module and calls process_request. + :return: none + """ + argument_dict = ClcMetaFact._define_module_argument_spec() + module = AnsibleModule(supports_check_mode=True, **argument_dict) + clc_meta_fact = ClcMetaFact(module) + + changed, response = clc_meta_fact.process_request() + module.exit_json(changed=changed, meta=response) + +from ansible.module_utils.basic import * # pylint: disable=W0614 + +if __name__ == '__main__': + main() From abc5b5ec9a6ece053cc72a0dd2450a33ee7aabc9 Mon Sep 17 00:00:00 2001 From: markramach Date: Mon, 19 Dec 2016 13:37:59 -0600 Subject: [PATCH 2/5] meta api refactor --- clc_ansible_module/clc_meta.py | 129 ++++++++++++++++++++++----------- 1 file changed, 88 insertions(+), 41 deletions(-) diff --git a/clc_ansible_module/clc_meta.py b/clc_ansible_module/clc_meta.py index 490c432..7251102 100644 --- a/clc_ansible_module/clc_meta.py +++ b/clc_ansible_module/clc_meta.py @@ -1,14 +1,23 @@ #!/usr/bin/python -import requests +try: + import requests +except ImportError: + REQUESTS_FOUND = False +else: + REQUESTS_FOUND = True class ClcMetaFact: def __init__(self, module): + + if not REQUESTS_FOUND: + self.module.fail_json( + msg='requests library is required for this module') + self.module = module self.api_url = '' self.headers = {} - self._set_clc_credentials_from_env() def _set_clc_credentials_from_env(self): @@ -18,47 +27,83 @@ def _set_clc_credentials_from_env(self): """ env = os.environ v2_api_token = env.get('CLC_V2_API_TOKEN', False) - self.api_url = env.get('RUNNER_META_API_URL', '') - self.headers = { - "Authorization": "Bearer " + v2_api_token - } + v2_api_username = env.get('CLC_V2_API_USERNAME', False) + v2_api_passwd = env.get('CLC_V2_API_PASSWD', False) + clc_alias = env.get('CLC_ACCT_ALIAS', False) + self.api_url = env.get('CLC_V2_API_URL', 'https://api.ctl.io') + self.meta_api_url = env.get('META_API_URL', 'https://api.runner.io') + + if v2_api_token and clc_alias: + + self.v2_api_token = v2_api_token + self.clc_alias = clc_alias + elif v2_api_username and v2_api_passwd: + + r = requests.post(self.api_url + '/v2/authentication/login', json={ + 'username': v2_api_username, + 'password': v2_api_passwd + }) + + if r.status_code not in [200]: + self.module.fail_json( + msg='Failed to authenticate with clc V2 api.') + + r = r.json() + self.v2_api_token = r['bearerToken'] + self.clc_alias = r['accountAlias'] - def create_meta(self, accountAlias, refId, attributes): - # requests.post(self.api_url, payload, header) - changed = False - url = self.api_url + "/" + accountAlias - json = {'referenceId': refId, - 'attributes': attributes} - result = requests.post(url, json=json, headers=self.headers) - if result.status_code == 200: - changed = True - return changed, result.json() - - def find_meta(self, accountAlias, refId): - url = self.api_url + "/" + accountAlias + "?referenceId=" + refId - return False, requests.get(url, headers=self.headers).json() - - def delete_meta(self, accountAlias, id): - changed = False - url = self.api_url + "/" + accountAlias + "/" + id - result = requests.delete(url, headers=self.headers) - if result.status_code == 204: - changed = True - return changed, {} else: - self.module.fail_json("Unable to delete the meta data " + result.content) + return self.module.fail_json( + msg="You must set the CLC_V2_API_USERNAME and CLC_V2_API_PASSWD " + "environment variables") + + + def create_meta(self, params): + + model = { + 'accountAlias' : self.clc_alias, + 'jobId' : params.get('jobId'), + 'executionId' : params.get('executionId'), + 'referenceId' : params.get('referenceId'), + 'name' : params.get('name'), + 'description' : params.get('description'), + 'data' : params.get('data') + } + + state = 'created' + r = requests.post(self.meta_api_url + '/meta/' + self.clc_alias + '/references/' + params.get('referenceId'), + json=model, headers={ 'Authorization': 'Bearer ' + self.v2_api_token }, verify=False) + + if r.status_code in [409]: + state = 'updated' + r = requests.put(self.meta_api_url + '/meta/' + self.clc_alias + '/references/' + params.get('referenceId') + '/values/' + params.get('name'), + json=model, headers={ 'Authorization': 'Bearer ' + self.v2_api_token }, verify=False) + + if r.status_code not in [200]: + self.module.fail_json(msg='Failed to create or update metadata. name:[%s]' % params.get('name')) + + self.module.exit_json(changed=True, content={ 'state' : state, 'payload' : model }) + + def delete_meta(self, params): + + state = 'deleted' + r = requests.delete(self.meta_api_url + '/meta/' + self.clc_alias + '/references/' + params.get('referenceId') + '/values/' + params.get('name'), + headers={ 'Authorization': 'Bearer ' + self.v2_api_token }, verify=False) + + if r.status_code not in [200, 404]: + self.module.fail_json(msg='Failed to delete metadata. name:[%s]' % params.get('name')) + + self.module.exit_json(changed=True, content={ 'state' : state }) def process_request(self): params = self.module.params - action = params.get('action') - if action == 'create': - return self.create_meta(params.get('accountAlias'), params.get('referenceId'), params.get('attributes')) - elif action == 'fetch': - return self.find_meta(params.get('accountAlias'), params.get('referenceId')) - elif action == 'delete': - return self.delete_meta(params.get('accountAlias'), params.get('id')) + state = params.get('state') + if state == 'present': + return self.create_meta(params) + elif state == 'absent': + return self.delete_meta(params) @staticmethod @@ -68,11 +113,13 @@ def _define_module_argument_spec(): :return: argument spec dictionary """ argument_spec = dict( - accountAlias=dict(type='str'), - referenceId=dict(type='str'), - attributes=dict(type='dict'), - id=dict(type='str'), - action=dict(type='str')) + jobId=dict(required=True), + executionId=dict(required=True), + referenceId=dict(required=True), + name=dict(required=True), + description=dict(required=True), + data=dict(required=True), + state=dict(choices=['present', 'absent'])) return {"argument_spec": argument_spec} From 9919ee5c6d94708e20b919615139b5547921effe Mon Sep 17 00:00:00 2001 From: markramach Date: Mon, 19 Dec 2016 14:25:58 -0600 Subject: [PATCH 3/5] adding fact module and example playbook --- clc_ansible_module/clc_meta.py | 6 +- clc_ansible_module/clc_meta_fact.py | 110 ++++++++++++++++++ .../example_clc_meta_playbook.yml | 47 ++++++++ 3 files changed, 160 insertions(+), 3 deletions(-) create mode 100644 clc_ansible_module/clc_meta_fact.py create mode 100644 example-playbooks/example_clc_meta_playbook.yml diff --git a/clc_ansible_module/clc_meta.py b/clc_ansible_module/clc_meta.py index 7251102..38be707 100644 --- a/clc_ansible_module/clc_meta.py +++ b/clc_ansible_module/clc_meta.py @@ -7,7 +7,7 @@ else: REQUESTS_FOUND = True -class ClcMetaFact: +class ClcMeta: def __init__(self, module): @@ -130,9 +130,9 @@ def main(): The main function. Instantiates the module and calls process_request. :return: none """ - argument_dict = ClcMetaFact._define_module_argument_spec() + argument_dict = ClcMeta._define_module_argument_spec() module = AnsibleModule(supports_check_mode=True, **argument_dict) - clc_meta_fact = ClcMetaFact(module) + clc_meta_fact = ClcMeta(module) changed, response = clc_meta_fact.process_request() module.exit_json(changed=changed, meta=response) diff --git a/clc_ansible_module/clc_meta_fact.py b/clc_ansible_module/clc_meta_fact.py new file mode 100644 index 0000000..94cea46 --- /dev/null +++ b/clc_ansible_module/clc_meta_fact.py @@ -0,0 +1,110 @@ +#!/usr/bin/python + +try: + import requests +except ImportError: + REQUESTS_FOUND = False +else: + REQUESTS_FOUND = True + +class ClcMetaFact: + + def __init__(self, module): + + if not REQUESTS_FOUND: + self.module.fail_json( + msg='requests library is required for this module') + + self.module = module + self.api_url = '' + self.headers = {} + self._set_clc_credentials_from_env() + + def _set_clc_credentials_from_env(self): + """ + Set the CLC Credentials by reading environment variables + :return: none + """ + env = os.environ + v2_api_token = env.get('CLC_V2_API_TOKEN', False) + v2_api_username = env.get('CLC_V2_API_USERNAME', False) + v2_api_passwd = env.get('CLC_V2_API_PASSWD', False) + clc_alias = env.get('CLC_ACCT_ALIAS', False) + self.api_url = env.get('CLC_V2_API_URL', 'https://api.ctl.io') + self.meta_api_url = env.get('META_API_URL', 'https://api.runner.io') + + if v2_api_token and clc_alias: + + self.v2_api_token = v2_api_token + self.clc_alias = clc_alias + + elif v2_api_username and v2_api_passwd: + + r = requests.post(self.api_url + '/v2/authentication/login', json={ + 'username': v2_api_username, + 'password': v2_api_passwd + }) + + if r.status_code not in [200]: + self.module.fail_json( + msg='Failed to authenticate with clc V2 api.') + + r = r.json() + self.v2_api_token = r['bearerToken'] + self.clc_alias = r['accountAlias'] + + else: + return self.module.fail_json( + msg="You must set the CLC_V2_API_USERNAME and CLC_V2_API_PASSWD " + "environment variables") + + def process_request(self): + params = self.module.params + criteria = ' referenceId: "' + params.get('referenceId') + '" ' + if params.get('jobId'): + criteria += ' jobId: "' + params.get('jobId') + '" ' + if params.get('executionId'): + criteria += ' jobId: "' + params.get('jobId') + '" ' + if params.get('name'): + criteria += ' name: "' + params.get('name') + '" ' + + gq = '{ metadata(' + criteria + ') { id referenceId jobId executionId name description data { ... on Config { type key value } ... on Instance { type value } } } }' + + r = requests.post(self.meta_api_url + '/meta/' + self.clc_alias, + data=gq, headers={ 'Authorization': 'Bearer ' + self.v2_api_token, 'Content-Type' : 'text/plain' }, verify=False) + + if r.status_code not in [200]: + # self.module.fail_json(msg='Failed to fetch metadata facts.') + self.module.exit_json(changed=True, content={ 'data' : r.text }) + + self.module.exit_json(changed=True, content={ 'data' : r.json() }) + + + @staticmethod + def _define_module_argument_spec(): + """ + Define the argument spec for the ansible module + :return: argument spec dictionary + """ + argument_spec = dict( + jobId=dict(required=False, default=False), + executionId=dict(required=False, default=False), + referenceId=dict(required=True), + name=dict(required=False, default=False)) + + return {"argument_spec": argument_spec} + + +def main(): + """ + The main function. Instantiates the module and calls process_request. + :return: none + """ + argument_dict = ClcMetaFact._define_module_argument_spec() + module = AnsibleModule(supports_check_mode=True, **argument_dict) + ClcMetaFact(module).process_request() + +from ansible.module_utils.basic import * # pylint: disable=W0614 + +if __name__ == '__main__': + main() diff --git a/example-playbooks/example_clc_meta_playbook.yml b/example-playbooks/example_clc_meta_playbook.yml new file mode 100644 index 0000000..edc5d20 --- /dev/null +++ b/example-playbooks/example_clc_meta_playbook.yml @@ -0,0 +1,47 @@ +--- +- name: Meta Test + hosts: localhost + connection: local + gather_facts: false + tasks: + + - name: Set CLC Metadata Config + clc_meta: + state: present + referenceId: demo + jobId: "{{ jobId }}" + executionId: "{{ executionId }}" + name: configuration_value + description: Configuration value description. + data: + type: CONFIG + key: asdf + value: fdsamodified + register: result + + - debug: msg={{result}} + + - name: Set CLC Metadata Instance + clc_meta: + state: present + referenceId: demo + jobId: "{{ jobId }}" + executionId: "{{ executionId }}" + name: instance_value + description: Instance value description. + data: + type: INSTANCE + value: UC1WFTCTEST02 + register: result + + - debug: msg={{result}} + + - name: Get CLC Metadata Instance + clc_meta_fact: + referenceId: demo + name: configuration_value + jobId: "{{ jobId }}" + executionId: "{{ executionId }}" + register: result + + - debug: msg={{result}} From e371d3cd56cd9d3c01c69e3cc965a5ed17ee0e6a Mon Sep 17 00:00:00 2001 From: markramach Date: Wed, 4 Jan 2017 13:09:01 -0600 Subject: [PATCH 4/5] incorrect parameter name --- clc_ansible_module/clc_meta_fact.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clc_ansible_module/clc_meta_fact.py b/clc_ansible_module/clc_meta_fact.py index 94cea46..402b0a9 100644 --- a/clc_ansible_module/clc_meta_fact.py +++ b/clc_ansible_module/clc_meta_fact.py @@ -64,7 +64,7 @@ def process_request(self): if params.get('jobId'): criteria += ' jobId: "' + params.get('jobId') + '" ' if params.get('executionId'): - criteria += ' jobId: "' + params.get('jobId') + '" ' + criteria += ' executionId: "' + params.get('executionId') + '" ' if params.get('name'): criteria += ' name: "' + params.get('name') + '" ' From f26e128810297318cb39b6c700d5b34f1dbf2cad Mon Sep 17 00:00:00 2001 From: markramach Date: Tue, 17 Jan 2017 09:00:07 -0600 Subject: [PATCH 5/5] all fields are optional --- clc_ansible_module/clc_meta_fact.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/clc_ansible_module/clc_meta_fact.py b/clc_ansible_module/clc_meta_fact.py index 402b0a9..0284c1f 100644 --- a/clc_ansible_module/clc_meta_fact.py +++ b/clc_ansible_module/clc_meta_fact.py @@ -60,7 +60,9 @@ def _set_clc_credentials_from_env(self): def process_request(self): params = self.module.params - criteria = ' referenceId: "' + params.get('referenceId') + '" ' + criteria = '' + if params.get('referenceId'): + criteria += ' referenceId: "' + params.get('referenceId') + '" ' if params.get('jobId'): criteria += ' jobId: "' + params.get('jobId') + '" ' if params.get('executionId'): @@ -89,7 +91,7 @@ def _define_module_argument_spec(): argument_spec = dict( jobId=dict(required=False, default=False), executionId=dict(required=False, default=False), - referenceId=dict(required=True), + referenceId=dict(required=False, default=False), name=dict(required=False, default=False)) return {"argument_spec": argument_spec}