Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ansible] Gke kube config #1944

Merged
merged 9 commits into from
Jun 24, 2019
Merged
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
2 changes: 1 addition & 1 deletion build/ansible
12 changes: 8 additions & 4 deletions products/container/ansible.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ datasources: !ruby/object:Overrides::ResourceOverrides
properties:
location: !ruby/object:Overrides::Ansible::PropertyOverride
aliases: ["region", "zone"]
kubectlPath: !ruby/object:Overrides::Ansible::PropertyOverride
exclude: true
kubectlContext: !ruby/object:Overrides::Ansible::PropertyOverride
exclude: true
facts: !ruby/object:Provider::Ansible::FactsOverride
has_filters: false
test: !ruby/object:Provider::Ansible::AnsibleFactsTestInformation
Expand All @@ -37,8 +41,6 @@ datasources: !ruby/object:Overrides::ResourceOverrides
"'my-pool' in \"{{ results['resources'] | map(attribute='name') | list }}\""
does_not_exist: |
"'my-pool' not in \"{{ results['resources'] | map(attribute='name') | list }}\""
KubeConfig: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
overrides: !ruby/object:Overrides::ResourceOverrides
Cluster: !ruby/object:Overrides::Ansible::ResourceOverride
notes:
Expand All @@ -53,10 +55,12 @@ overrides: !ruby/object:Overrides::ResourceOverrides
aliases: ['zone']
post_create: |
delete_default_node_pool(module)
post_action: |
if module.params.get('kubectl_path'):
Kubectl(module).write_file()
provider_helpers:
- 'products/container/helpers/python/provider_cluster.py'
KubeConfig: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
- 'products/container/helpers/python/kubectl.py'
NodePool: !ruby/object:Overrides::Ansible::ResourceOverride
transport: !ruby/object:Overrides::Ansible::Transport
encoder: encode_request
Expand Down
4 changes: 4 additions & 0 deletions products/container/ansible_version_added.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
:regular:
:Cluster:
:version_added: '2.6'
:kubectlPath:
:version_added: '2.9'
:kubectlContext:
:version_added: '2.9'
:name:
:version_added: '2.6'
:description:
Expand Down
40 changes: 14 additions & 26 deletions products/container/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,20 @@ objects:
description: 'The location where the cluster is deployed'
required: true
properties:
- !ruby/object:Api::Type::String
name: '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.
required: true
- !ruby/object:Api::Type::String
name: 'kubectlContext'
description: 'The name of the context for the kubectl config file. Will default to the cluster name'
- !ruby/object:Api::Type::String
name: 'name'
description: |
Expand Down Expand Up @@ -838,29 +852,3 @@ objects:
name: 'podIpv4CidrSize'
description: The pod CIDR block size per node in this node pool.
output: true
- !ruby/object:Api::Resource
name: 'KubeConfig'
base_url: 'unused'
description: |
Generates a compatible Kuberenetes '.kube/config' file
properties:
- !ruby/object:Api::Type::String
name: 'name'
description: 'The config file kubectl settings will be written to.'
required: true
- !ruby/object:Api::Type::ResourceRef
name: 'cluster'
resource: 'Cluster'
imports: 'name'
description: 'A reference to Cluster resource'
required: true
# TODO(nelsonjr): Make 'zone' a ResourceRef once cross-module references
# are possible.
- !ruby/object:Api::Type::String
name: 'location'
description: 'The location where the container is deployed'
required: true
- !ruby/object:Api::Type::String
name: 'context'
description: 'The name of the context. Defaults to cluster name.'
required: true
81 changes: 81 additions & 0 deletions products/container/helpers/python/kubectl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
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://{}".format(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]
7 changes: 5 additions & 2 deletions products/container/inspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@ overrides: !ruby/object:Overrides::ResourceOverrides
# there exists a `container_cluster` resource in InSpec already
# that can handle zonal resources only
name: 'RegionalCluster'
properties:
kubectlPath: !ruby/object:Overrides::Inspec::PropertyOverride
exclude: true
kubectlContext: !ruby/object:Overrides::Inspec::PropertyOverride
exclude: true
NodePool: !ruby/object:Overrides::Inspec::ResourceOverride
# See note on RegionalCluster, similar for NodePool
name: 'RegionalNodePool'
base_url: projects/{{project}}/locations/{{location}}/clusters/{{cluster}}/nodePools
properties:
cluster: !ruby/object:Overrides::Inspec::PropertyOverride
resource: 'RegionalCluster'
KubeConfig: !ruby/object:Overrides::Inspec::ResourceOverride
exclude: true
files: !ruby/object:Provider::Config::Files
copy:
'Gemfile': 'provider/inspec/Gemfile'