Skip to content
Open
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
5 changes: 3 additions & 2 deletions plugins/doc_fragments/gcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ModuleDocFragment(object):
- The type of credential used.
type: str
required: true
choices: [ application, machineaccount, serviceaccount ]
choices: [ application, machineaccount, serviceaccount, impersonation ]
service_account_contents:
description:
- The contents of a Service Account JSON file, either in a dictionary or as a JSON string that represents it.
Expand All @@ -33,7 +33,8 @@ class ModuleDocFragment(object):
service_account_email:
description:
- An optional service account email address if machineaccount is selected
and the user does not wish to use the default email.
and the user does not wish to use the default email. This field must be set
if auth_kind is impersonation.
type: str
scopes:
description:
Expand Down
10 changes: 4 additions & 6 deletions plugins/filter/gcp_kms_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@

# Usage:
# vars:
# encrypted_myvar: "{{ var | b64encode | gcp_kms_encrypt(auth_kind='serviceaccount',
# service_account_file='gcp_service_account_file', projects='default',
# encrypted_myvar: "{{ var | b64encode | gcp_kms_encrypt(projects='default',
# key_ring='key_ring', crypto_key='crypto_key') }}"
# decrypted_myvar: "{{ encrypted_myvar | gcp_kms_decrypt(auth_kind='serviceaccount',
# service_account_file=gcp_service_account_file, projects='default',
# decrypted_myvar: "{{ encrypted_myvar | gcp_kms_decrypt(projects='default',
# key_ring='key_ring', crypto_key='crypto_key') }}"

from __future__ import (absolute_import, division, print_function)
Expand Down Expand Up @@ -36,12 +34,12 @@ def run(self, method, **kwargs):
'projects': kwargs.get('projects', None),
'scopes': kwargs.get('scopes', None),
'locations': kwargs.get('locations', 'global'),
'auth_kind': kwargs.get('auth_kind', None),
'auth_kind': kwargs.get('auth_kind', 'application'),
'service_account_file': kwargs.get('service_account_file', None),
'service_account_email': kwargs.get('service_account_email', None),
}
if not params['scopes']:
params['scopes'] = ['https://www.googleapis.com/auth/cloudkms']
params['scopes'] = ['https://www.googleapis.com/auth/cloud-platform']
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is technically a backwards-incompatible change (the default value of a field changing).

Is there a specific reason this needs to be done in this change?

fake_module = GcpMockModule(params)
if method == "encrypt":
return self.kms_encrypt(fake_module)
Expand Down
60 changes: 60 additions & 0 deletions plugins/filter/gcp_secret_filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# (c) 2019, Eric Anderson <[email protected]>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this copyright is incorrect? seems like copy-pasted code from a separate file.

It should reflect the author of the code.

# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

# Usage:
# vars:
# encrypted_myvar: "{{ var | b64encode | gcp_kms_encrypt(projects='default',
# key_ring='key_ring', crypto_key='crypto_key') }}"
# decrypted_myvar: "{{ encrypted_myvar | gcp_kms_decrypt(projects='default',
# key_ring='key_ring', crypto_key='crypto_key') }}"

from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

from ansible.errors import AnsibleError
from ansible_collections.google.cloud.plugins.module_utils.gcp_utils import GcpSession


class GcpMockModule(object):
def __init__(self, params):
self.params = params

def fail_json(self, *args, **kwargs):
raise AnsibleError(kwargs['msg'])


class GcpSecretFilter():
def run(self, method, **kwargs):
params = {
'secret': kwargs.get('secret', None),
'versions': kwargs.get('version', 'latest'),
'projects': kwargs.get('projects', None),
'scopes': kwargs.get('scopes', None),
'auth_kind': kwargs.get('auth_kind', 'application'),
'service_account_file': kwargs.get('service_account_file', None),
'service_account_email': kwargs.get('service_account_email', None),
}
if not params['scopes']:
params['scopes'] = ['https://www.googleapis.com/auth/cloud-platform']
fake_module = GcpMockModule(params)
if method == "decode":
return self.secret_decode(fake_module)

def secret_decode(self, module):
payload = {"ciphertext": module.params['ciphertext']}

auth = GcpSession(module, 'secretmanager')
url = "https://secretmanager.googleapis.com/v1/projects/{projects}/secrets/{secret}/" \
"versions/{version}:access".format(**module.params)
response = auth.get(url, body=payload)
return response.json()['payload']['data']

def gcp_secret_decode(plaintext, **kwargs):
return GcpKmsFilter().run('decode', plaintext=plaintext, **kwargs)

class FilterModule(object):

def filters(self):
return {
'gcp_secret_decode': gcp_secret_decode,
}
5 changes: 3 additions & 2 deletions plugins/inventory/gcp_compute.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
description:
- The type of credential used.
required: True
choices: ['application', 'serviceaccount', 'machineaccount']
choices: ['application', 'serviceaccount', 'machineaccount', 'impersonation']
env:
- name: GCP_AUTH_KIND
version_added: "2.8.2"
Expand Down Expand Up @@ -83,7 +83,8 @@
service_account_email:
description:
- An optional service account email address if machineaccount is selected
and the user does not wish to use the default email.
and the user does not wish to use the default email. This field must be set
if auth_kind is impersonation.
env:
- name: GCP_SERVICE_ACCOUNT_EMAIL
version_added: "2.8.2"
Expand Down
10 changes: 9 additions & 1 deletion plugins/module_utils/gcp_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,14 @@ def _credentials(self):
elif cred_type == 'machineaccount':
return google.auth.compute_engine.Credentials(
self.module.params['service_account_email'])
elif cred_type == 'impersonation' and self.module.params['service_account_email']:
source_credentials, project_id = google.auth.default()
return google.auth.impersonated_credentials.Credentials(
source_credentials=source_credentials,
target_principal=self.module.params['service_account_email'],
target_scopes=self.module.params['scopes'],
lifetime=3600,
)
else:
self.module.fail_json(msg="Credential type '%s' not implemented" % cred_type)

Expand Down Expand Up @@ -270,7 +278,7 @@ def __init__(self, *args, **kwargs):
auth_kind=dict(
required=True,
fallback=(env_fallback, ['GCP_AUTH_KIND']),
choices=['machineaccount', 'serviceaccount', 'application'],
choices=['machineaccount', 'serviceaccount', 'application', 'impersonation'],
type='str'),
service_account_email=dict(
required=False,
Expand Down