Bug fixes for GCP modules (#58850)
This commit is contained in:
parent
d88f686976
commit
eb839c94ea
9 changed files with 146 additions and 14 deletions
|
@ -409,6 +409,20 @@ options:
|
|||
aliases:
|
||||
- zone
|
||||
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
|
||||
'''
|
||||
|
||||
|
@ -619,7 +633,7 @@ masterAuth:
|
|||
description:
|
||||
- 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
|
||||
password.
|
||||
password with a minimum of 16 characters.
|
||||
returned: success
|
||||
type: str
|
||||
clientCertificateConfig:
|
||||
|
@ -924,6 +938,20 @@ location:
|
|||
- The location where the cluster is deployed.
|
||||
returned: success
|
||||
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'),
|
||||
tpu_ipv4_cidr_block=dict(type='str'),
|
||||
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:
|
||||
fetch = {}
|
||||
|
||||
if module.params.get('kubectl_path'):
|
||||
Kubectl(module).write_file()
|
||||
fetch.update({'changed': changed})
|
||||
|
||||
module.exit_json(**fetch)
|
||||
|
@ -1231,6 +1263,77 @@ def delete_default_node_pool(module):
|
|||
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):
|
||||
def __init__(self, request, module):
|
||||
self.module = module
|
||||
|
|
|
@ -256,7 +256,7 @@ resources:
|
|||
description:
|
||||
- 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 password.
|
||||
a strong password with a minimum of 16 characters.
|
||||
returned: success
|
||||
type: str
|
||||
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._text import to_native
|
||||
import json
|
||||
import os
|
||||
import mimetypes
|
||||
|
@ -204,7 +205,7 @@ def create(module):
|
|||
auth = GcpSession(module, 'iam')
|
||||
json_content = return_if_object(module, auth.post(self_link(module), resource_to_request(module)))
|
||||
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)
|
||||
|
||||
|
||||
|
|
|
@ -51,6 +51,14 @@ options:
|
|||
description:
|
||||
- Name of the topic.
|
||||
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:
|
||||
description:
|
||||
- A set of key/value label pairs to assign to this Topic.
|
||||
|
@ -78,6 +86,14 @@ name:
|
|||
- Name of the topic.
|
||||
returned: success
|
||||
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:
|
||||
description:
|
||||
- A set of key/value label pairs to assign to this Topic.
|
||||
|
@ -102,7 +118,10 @@ def main():
|
|||
|
||||
module = GcpModule(
|
||||
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):
|
||||
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)
|
||||
return_vals = {}
|
||||
for k, v in request.items():
|
||||
|
@ -230,7 +249,7 @@ def is_different(module, response):
|
|||
# Remove unnecessary properties from the response.
|
||||
# This is for doing comparisons with Ansible's current parameters.
|
||||
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):
|
||||
|
|
|
@ -63,6 +63,15 @@ resources:
|
|||
- Name of the topic.
|
||||
returned: success
|
||||
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:
|
||||
description:
|
||||
- A set of key/value label pairs to assign to this Topic.
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
- name: verify that command succeeded
|
||||
assert:
|
||||
that:
|
||||
- results['resources'] | length >= 1
|
||||
- results['resources'] | map(attribute='name') | select("match", ".*myCustomRole2.*") | list | length == 1
|
||||
# ----------------------------------------------------------------------------
|
||||
- name: create a role that already exists
|
||||
gcp_iam_role:
|
||||
|
@ -106,7 +106,7 @@
|
|||
- name: verify that command succeeded
|
||||
assert:
|
||||
that:
|
||||
- results['resources'] | length == 0
|
||||
- results['resources'] | map(attribute='name') | select("match", ".*myCustomRole2.*") | list | length == 0
|
||||
# ----------------------------------------------------------------------------
|
||||
- name: delete a role that does not exist
|
||||
gcp_iam_role:
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
- name: verify that command succeeded
|
||||
assert:
|
||||
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
|
||||
gcp_iam_service_account:
|
||||
|
@ -86,7 +86,7 @@
|
|||
- name: verify that command succeeded
|
||||
assert:
|
||||
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
|
||||
gcp_iam_service_account:
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
- name: verify that command succeeded
|
||||
assert:
|
||||
that:
|
||||
- results['resources'] | length >= 1
|
||||
- results['resources'] | map(attribute='name') | select("match", ".*instance37.*") | list | length == 1
|
||||
# ----------------------------------------------------------------------------
|
||||
- name: create a instance that already exists
|
||||
gcp_redis_instance:
|
||||
|
@ -132,7 +132,7 @@
|
|||
- name: verify that command succeeded
|
||||
assert:
|
||||
that:
|
||||
- results['resources'] | length == 0
|
||||
- results['resources'] | map(attribute='name') | select("match", ".*instance37.*") | list | length == 0
|
||||
# ----------------------------------------------------------------------------
|
||||
- name: delete a instance that does not exist
|
||||
gcp_redis_instance:
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
- name: verify that command succeeded
|
||||
assert:
|
||||
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
|
||||
gcp_resourcemanager_project:
|
||||
|
@ -94,7 +94,7 @@
|
|||
- name: verify that command succeeded
|
||||
assert:
|
||||
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
|
||||
gcp_resourcemanager_project:
|
||||
|
|
Loading…
Reference in a new issue