From 227bb026f6c203bf578a3f4238832f74778b0f26 Mon Sep 17 00:00:00 2001 From: Alex Stephen Date: Fri, 1 Mar 2019 02:21:43 +0000 Subject: [PATCH] Ansible - allowing for creds to be passed in as string/env var Signed-off-by: Modular Magician --- lib/ansible/module_utils/gcp_utils.py | 15 ++++++++++++--- lib/ansible/utils/module_docs_fragments/gcp.py | 11 +++++++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/lib/ansible/module_utils/gcp_utils.py b/lib/ansible/module_utils/gcp_utils.py index 15c27e3881971f..0a89db4100876a 100644 --- a/lib/ansible/module_utils/gcp_utils.py +++ b/lib/ansible/module_utils/gcp_utils.py @@ -21,6 +21,7 @@ from ansible.module_utils._text import to_text import ast import os +import json def navigate_hash(source, path, default=None): @@ -143,7 +144,8 @@ def _validate(self): msg="Service Account Email only works with Machine Account-based authentication" ) - if self.module.params.get('service_account_file') is not None and self.module.params['auth_kind'] != 'serviceaccount': + if (self.module.params.get('service_account_file') is not None or + self.module.params.get('service_account_contents') is not None) and self.module.params['auth_kind'] != 'serviceaccount': self.module.fail_json( msg="Service Account File only works with Service Account-based authentication" ) @@ -153,9 +155,12 @@ def _credentials(self): if cred_type == 'application': credentials, project_id = google.auth.default(scopes=self.module.params['scopes']) return credentials - elif cred_type == 'serviceaccount': + elif cred_type == 'serviceaccount' and self.module.params.get('service_account_file'): path = os.path.realpath(os.path.expanduser(self.module.params['service_account_file'])) return service_account.Credentials.from_service_account_file(path).with_scopes(self.module.params['scopes']) + elif cred_type == 'serviceaccount' and self.module.params.get('service_account_contents'): + cred = json.loads(self.module.params.get('service_account_contents')) + return service_account.Credentials.from_service_account_info(cred).with_scopes(self.module.params['scopes']) elif cred_type == 'machineaccount': return google.auth.compute_engine.Credentials( self.module.params['service_account_email']) @@ -199,6 +204,10 @@ def __init__(self, *args, **kwargs): required=False, fallback=(env_fallback, ['GCP_SERVICE_ACCOUNT_FILE']), type='path'), + service_account_contents=dict( + required=False, + fallback=(env_fallback, ['GCP_SERVICE_ACCOUNT_CONTENTS']), + type='str'), scopes=dict( required=False, fallback=(env_fallback, ['GCP_SCOPES']), @@ -211,7 +220,7 @@ def __init__(self, *args, **kwargs): mutual = kwargs['mutually_exclusive'] kwargs['mutually_exclusive'] = mutual.append( - ['service_account_email', 'service_account_file'] + ['service_account_email', 'service_account_file', 'service_account_contents'] ) AnsibleModule.__init__(self, *args, **kwargs) diff --git a/lib/ansible/utils/module_docs_fragments/gcp.py b/lib/ansible/utils/module_docs_fragments/gcp.py index e736e5d4de78a9..c096a5fc7e2599 100644 --- a/lib/ansible/utils/module_docs_fragments/gcp.py +++ b/lib/ansible/utils/module_docs_fragments/gcp.py @@ -18,6 +18,11 @@ class ModuleDocFragment(object): service_account_file: description: - The path of a Service Account JSON file if serviceaccount is selected as type. + service_account_contents: + description: + - A string representing the contents of a Service Account JSON file. + - This should not be passed in as a dictionary, but a string has + the exact contents of a service account json file (valid JSON). service_account_email: description: - An optional service account email address if machineaccount is selected @@ -26,8 +31,10 @@ class ModuleDocFragment(object): description: - Array of scopes to be used. notes: - - For authentication, you can set service_account_file using the - C(GCP_SERVICE_ACCOUNT_FILE) env variable. + - for authentication, you can set service_account_file using the + c(gcp_service_account_file) env variable. + - for authentication, you can set service_account_contents using the + c(GCP_SERVICE_ACCOUNT_CONTENTS) env variable. - For authentication, you can set service_account_email using the C(GCP_SERVICE_ACCOUNT_EMAIL) env variable. - For authentication, you can set auth_kind using the C(GCP_AUTH_KIND) env