Bug fixes for GCP modules (#58850)

pull/58850/merge
The Magician 7 years ago committed by ansibot
parent d88f686976
commit eb839c94ea

@ -409,6 +409,20 @@ options:
aliases: aliases:
- zone - zone
version_added: 2.8 version_added: 2.8
kubectl_path:
description:
- The path that the kubectl config file will be written to.
- The file will not be created if this path is unset.
- Any existing file at this path will be completely overwritten.
- This requires the PyYaml library.
required: false
version_added: 2.9
kubectl_context:
description:
- The name of the context for the kubectl config file. Will default to the cluster
name.
required: false
version_added: 2.9
extends_documentation_fragment: gcp extends_documentation_fragment: gcp
''' '''
@ -619,7 +633,7 @@ masterAuth:
description: description:
- The password to use for HTTP basic authentication to the master endpoint. - The password to use for HTTP basic authentication to the master endpoint.
Because the master endpoint is open to the Internet, you should create a strong Because the master endpoint is open to the Internet, you should create a strong
password. password with a minimum of 16 characters.
returned: success returned: success
type: str type: str
clientCertificateConfig: clientCertificateConfig:
@ -924,6 +938,20 @@ location:
- The location where the cluster is deployed. - The location where the cluster is deployed.
returned: success returned: success
type: str type: str
kubectlPath:
description:
- The path that the kubectl config file will be written to.
- The file will not be created if this path is unset.
- Any existing file at this path will be completely overwritten.
- This requires the PyYaml library.
returned: success
type: str
kubectlContext:
description:
- The name of the context for the kubectl config file. Will default to the cluster
name.
returned: success
type: str
''' '''
################################################################################ ################################################################################
@ -1000,6 +1028,8 @@ def main():
enable_tpu=dict(type='bool'), enable_tpu=dict(type='bool'),
tpu_ipv4_cidr_block=dict(type='str'), tpu_ipv4_cidr_block=dict(type='str'),
location=dict(required=True, type='str', aliases=['zone']), location=dict(required=True, type='str', aliases=['zone']),
kubectl_path=dict(type='str'),
kubectl_context=dict(type='str'),
) )
) )
@ -1029,6 +1059,8 @@ def main():
else: else:
fetch = {} fetch = {}
if module.params.get('kubectl_path'):
Kubectl(module).write_file()
fetch.update({'changed': changed}) fetch.update({'changed': changed})
module.exit_json(**fetch) module.exit_json(**fetch)
@ -1231,6 +1263,77 @@ def delete_default_node_pool(module):
return wait_for_operation(module, auth.delete(link)) return wait_for_operation(module, auth.delete(link))
class Kubectl(object):
def __init__(self, module):
self.module = module
"""
Writes a kubectl config file
kubectl_path must be set or this will fail.
"""
def write_file(self):
try:
import yaml
except ImportError:
self.module.fail_json(msg="Please install the pyyaml module")
with open(self.module.params['kubectl_path'], 'w') as f:
f.write(yaml.dump(self._contents()))
"""
Returns the contents of a kubectl file
"""
def _contents(self):
token = self._auth_token()
endpoint = "https://%s" % self.fetch["endpoint"]
context = self.module.params.get('kubectl_context')
if not context:
context = self.module.params['name']
return {
'apiVersion': 'v1',
'clusters': [
{'name': context, 'cluster': {'certificate-authority-data': str(self.fetch['masterAuth']['clusterCaCertificate']), 'server': endpoint}}
],
'contexts': [{'name': context, 'context': {'cluster': context, 'user': context}}],
'current-context': context,
'kind': 'Config',
'preferences': {},
'users': [
{
'name': context,
'user': {
'auth-provider': {
'config': {
'access-token': token,
'cmd-args': 'config config-helper --format=json',
'cmd-path': '/usr/lib64/google-cloud-sdk/bin/gcloud',
'expiry-key': '{.credential.token_expiry}',
'token-key': '{.credential.access_token}',
},
'name': 'gcp',
},
'username': str(self.fetch['masterAuth']['username']),
'password': str(self.fetch['masterAuth']['password']),
},
}
],
}
"""
Returns the auth token used in kubectl
This also sets the 'fetch' variable used in creating the kubectl
"""
def _auth_token(self):
auth = GcpSession(self.module, 'auth')
response = auth.get(self_link(self.module))
self.fetch = response.json()
return response.request.headers['authorization'].split(' ')[1]
class ClusterNodeconfig(object): class ClusterNodeconfig(object):
def __init__(self, request, module): def __init__(self, request, module):
self.module = module self.module = module

@ -256,7 +256,7 @@ resources:
description: description:
- The password to use for HTTP basic authentication to the master endpoint. - The password to use for HTTP basic authentication to the master endpoint.
Because the master endpoint is open to the Internet, you should create Because the master endpoint is open to the Internet, you should create
a strong password. a strong password with a minimum of 16 characters.
returned: success returned: success
type: str type: str
clientCertificateConfig: clientCertificateConfig:

@ -152,6 +152,7 @@ path:
################################################################################ ################################################################################
from ansible.module_utils.gcp_utils import navigate_hash, GcpSession, GcpModule, GcpRequest, replace_resource_dict from ansible.module_utils.gcp_utils import navigate_hash, GcpSession, GcpModule, GcpRequest, replace_resource_dict
from ansible.module_utils._text import to_native
import json import json
import os import os
import mimetypes import mimetypes
@ -204,7 +205,7 @@ def create(module):
auth = GcpSession(module, 'iam') auth = GcpSession(module, 'iam')
json_content = return_if_object(module, auth.post(self_link(module), resource_to_request(module))) json_content = return_if_object(module, auth.post(self_link(module), resource_to_request(module)))
with open(module.params['path'], 'w') as f: with open(module.params['path'], 'w') as f:
private_key_contents = base64.b64decode(json_content['privateKeyData']) private_key_contents = to_native(base64.b64decode(json_content['privateKeyData']))
f.write(private_key_contents) f.write(private_key_contents)

@ -51,6 +51,14 @@ options:
description: description:
- Name of the topic. - Name of the topic.
required: true required: true
kms_key_name:
description:
- The resource name of the Cloud KMS CryptoKey to be used to protect access to
messsages published on this topic. Your project's PubSub service account (`service-{{PROJECT_NUMBER}}@gcp-sa-pubsub.iam.gserviceaccount.com`)
must have `roles/cloudkms.cryptoKeyEncrypterDecrypter` to use this feature.
- The expected format is `projects/*/locations/*/keyRings/*/cryptoKeys/*` .
required: false
version_added: 2.9
labels: labels:
description: description:
- A set of key/value label pairs to assign to this Topic. - A set of key/value label pairs to assign to this Topic.
@ -78,6 +86,14 @@ name:
- Name of the topic. - Name of the topic.
returned: success returned: success
type: str type: str
kmsKeyName:
description:
- The resource name of the Cloud KMS CryptoKey to be used to protect access to messsages
published on this topic. Your project's PubSub service account (`service-{{PROJECT_NUMBER}}@gcp-sa-pubsub.iam.gserviceaccount.com`)
must have `roles/cloudkms.cryptoKeyEncrypterDecrypter` to use this feature.
- The expected format is `projects/*/locations/*/keyRings/*/cryptoKeys/*` .
returned: success
type: str
labels: labels:
description: description:
- A set of key/value label pairs to assign to this Topic. - A set of key/value label pairs to assign to this Topic.
@ -102,7 +118,10 @@ def main():
module = GcpModule( module = GcpModule(
argument_spec=dict( argument_spec=dict(
state=dict(default='present', choices=['present', 'absent'], type='str'), name=dict(required=True, type='str'), labels=dict(type='dict') state=dict(default='present', choices=['present', 'absent'], type='str'),
name=dict(required=True, type='str'),
kms_key_name=dict(type='str'),
labels=dict(type='dict'),
) )
) )
@ -162,7 +181,7 @@ def delete(module, link):
def resource_to_request(module): def resource_to_request(module):
request = {u'name': module.params.get('name'), u'labels': module.params.get('labels')} request = {u'name': module.params.get('name'), u'kmsKeyName': module.params.get('kms_key_name'), u'labels': module.params.get('labels')}
request = encode_request(request, module) request = encode_request(request, module)
return_vals = {} return_vals = {}
for k, v in request.items(): for k, v in request.items():
@ -230,7 +249,7 @@ def is_different(module, response):
# Remove unnecessary properties from the response. # Remove unnecessary properties from the response.
# This is for doing comparisons with Ansible's current parameters. # This is for doing comparisons with Ansible's current parameters.
def response_to_hash(module, response): def response_to_hash(module, response):
return {u'name': module.params.get('name'), u'labels': response.get(u'labels')} return {u'name': module.params.get('name'), u'kmsKeyName': module.params.get('kms_key_name'), u'labels': response.get(u'labels')}
def decode_request(response, module): def decode_request(response, module):

@ -63,6 +63,15 @@ resources:
- Name of the topic. - Name of the topic.
returned: success returned: success
type: str type: str
kmsKeyName:
description:
- The resource name of the Cloud KMS CryptoKey to be used to protect access
to messsages published on this topic. Your project's PubSub service account
(`service-{{PROJECT_NUMBER}}@gcp-sa-pubsub.iam.gserviceaccount.com`) must
have `roles/cloudkms.cryptoKeyEncrypterDecrypter` to use this feature.
- The expected format is `projects/*/locations/*/keyRings/*/cryptoKeys/*` .
returned: success
type: str
labels: labels:
description: description:
- A set of key/value label pairs to assign to this Topic. - A set of key/value label pairs to assign to this Topic.

@ -56,7 +56,7 @@
- name: verify that command succeeded - name: verify that command succeeded
assert: assert:
that: that:
- results['resources'] | length >= 1 - results['resources'] | map(attribute='name') | select("match", ".*myCustomRole2.*") | list | length == 1
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
- name: create a role that already exists - name: create a role that already exists
gcp_iam_role: gcp_iam_role:
@ -106,7 +106,7 @@
- name: verify that command succeeded - name: verify that command succeeded
assert: assert:
that: that:
- results['resources'] | length == 0 - results['resources'] | map(attribute='name') | select("match", ".*myCustomRole2.*") | list | length == 0
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
- name: delete a role that does not exist - name: delete a role that does not exist
gcp_iam_role: gcp_iam_role:

@ -46,7 +46,7 @@
- name: verify that command succeeded - name: verify that command succeeded
assert: assert:
that: that:
- results['resources'] | length >= 1 - results['resources'] | map(attribute='name') | select("match", ".*{{ sa_name }}.*") | list | length == 1
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
- name: create a service account that already exists - name: create a service account that already exists
gcp_iam_service_account: gcp_iam_service_account:
@ -86,7 +86,7 @@
- name: verify that command succeeded - name: verify that command succeeded
assert: assert:
that: that:
- results['resources'] | length == 0 - results['resources'] | map(attribute='name') | select("match", ".*{{ sa_name }}.*") | list | length == 0
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
- name: delete a service account that does not exist - name: delete a service account that does not exist
gcp_iam_service_account: gcp_iam_service_account:

@ -73,7 +73,7 @@
- name: verify that command succeeded - name: verify that command succeeded
assert: assert:
that: that:
- results['resources'] | length >= 1 - results['resources'] | map(attribute='name') | select("match", ".*instance37.*") | list | length == 1
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
- name: create a instance that already exists - name: create a instance that already exists
gcp_redis_instance: gcp_redis_instance:
@ -132,7 +132,7 @@
- name: verify that command succeeded - name: verify that command succeeded
assert: assert:
that: that:
- results['resources'] | length == 0 - results['resources'] | map(attribute='name') | select("match", ".*instance37.*") | list | length == 0
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
- name: delete a instance that does not exist - name: delete a instance that does not exist
gcp_redis_instance: gcp_redis_instance:

@ -50,7 +50,7 @@
- name: verify that command succeeded - name: verify that command succeeded
assert: assert:
that: that:
- results['resources'] | length >= 1 - results['resources'] | map(attribute='name') | select("match", ".*My Sample Project.*") | list | length == 1
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
- name: create a project that already exists - name: create a project that already exists
gcp_resourcemanager_project: gcp_resourcemanager_project:
@ -94,7 +94,7 @@
- name: verify that command succeeded - name: verify that command succeeded
assert: assert:
that: that:
- results['resources'] | length == 0 - results['resources'] | map(attribute='name') | select("match", ".*My Sample Project.*") | list | length == 0
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
- name: delete a project that does not exist - name: delete a project that does not exist
gcp_resourcemanager_project: gcp_resourcemanager_project:

Loading…
Cancel
Save