Downloadable Kubernetes configuration file
Kubernetes can use OpenStack application credentials for authentication. Generate a kubeconfig file and make it available to download along with the openrc and clouds.yaml files. blueprint kubernetes-config-gen Change-Id: I298370e7abf4f0d480bd5199060f24bab6d6daaa
This commit is contained in:
parent
a7a04da657
commit
f381f4dd3c
@ -7,7 +7,7 @@ Settings Reference
|
||||
Introduction
|
||||
============
|
||||
|
||||
Horizon's settings broadly fall into three categories:
|
||||
Horizon's settings broadly fall into four categories:
|
||||
|
||||
* `General Settings`_: this includes visual settings like the modal backdrop
|
||||
style, bug url and theme configuration, as well as settings that affect every
|
||||
@ -21,6 +21,8 @@ Horizon's settings broadly fall into three categories:
|
||||
should read the `Django settings documentation
|
||||
<https://docs.djangoproject.com/en/dev/topics/settings/>`_ to see the other
|
||||
options available to you.
|
||||
* `Other Settings`_: settings which do not fall into any of the above
|
||||
categories.
|
||||
|
||||
To modify your settings, you have two options:
|
||||
|
||||
@ -2521,3 +2523,51 @@ Default: Absolute paths for `horizon/locale`, `openstack_auth/locale` and
|
||||
Django uses relative paths by default so it causes localization issues
|
||||
depending on your runtime settings. To avoid this we recommend to use absolute
|
||||
paths for directories with locales.
|
||||
|
||||
Other Settings
|
||||
==============
|
||||
|
||||
KUBECONFIG_ENABLED
|
||||
------------------
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
Default: ``False``
|
||||
|
||||
Kubernetes clusters can use Keystone as an external identity provider.
|
||||
Horizon can generate a ``kubeconfig`` file from the application credentials
|
||||
control panel which can be used for authenticating with a Kubernetes cluster.
|
||||
This setting enables this behavior.
|
||||
|
||||
.. seealso::
|
||||
|
||||
`KUBECONFIG_KUBERNETES_URL`_ and `KUBECONFIG_CERTIFICATE_AUTHORITY_DATA`_
|
||||
to provide parameters for the ``kubeconfig`` file.
|
||||
|
||||
KUBECONFIG_KUBERNETES_URL
|
||||
-------------------------
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
Default: ``""``
|
||||
|
||||
A Kubernetes API endpoint URL to be included in the generated ``kubeconfig``
|
||||
file.
|
||||
|
||||
.. seealso::
|
||||
|
||||
`KUBECONFIG_ENABLED`_ to enable the ``kubeconfig`` file generation.
|
||||
|
||||
KUBECONFIG_CERTIFICATE_AUTHORITY_DATA
|
||||
-------------------------------------
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
Default: ``""``
|
||||
|
||||
Kubernetes API endpoint certificate authority data to be included in the
|
||||
generated ``kubeconfig`` file.
|
||||
|
||||
.. seealso::
|
||||
|
||||
`KUBECONFIG_ENABLED`_ to enable the ``kubeconfig`` file generation.
|
||||
|
@ -15,6 +15,8 @@
|
||||
import datetime
|
||||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
from django.forms import widgets
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.views.decorators.debug import sensitive_variables
|
||||
|
||||
@ -49,6 +51,10 @@ class CreateApplicationCredentialForm(forms.SelfHandlingForm):
|
||||
required=False)
|
||||
unrestricted = forms.BooleanField(label=_("Unrestricted (dangerous)"),
|
||||
required=False)
|
||||
kubernetes_namespace = forms.CharField(max_length=255,
|
||||
label=_("Kubernetes Namespace"),
|
||||
initial="default",
|
||||
required=False)
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
self.next_view = kwargs.pop('next_view', None)
|
||||
@ -58,6 +64,8 @@ class CreateApplicationCredentialForm(forms.SelfHandlingForm):
|
||||
role_names = [role['name'] for role in role_list]
|
||||
role_choices = ((name, name) for name in role_names)
|
||||
self.fields['roles'].choices = role_choices
|
||||
if not settings.KUBECONFIG_ENABLED:
|
||||
self.fields['kubernetes_namespace'].widget = widgets.HiddenInput()
|
||||
|
||||
# We have to protect the entire "data" dict because it contains the
|
||||
# secret string.
|
||||
@ -98,6 +106,8 @@ class CreateApplicationCredentialForm(forms.SelfHandlingForm):
|
||||
)
|
||||
self.request.session['application_credential'] = \
|
||||
new_app_cred.to_dict()
|
||||
(self.request.session['application_credential']
|
||||
['kubernetes_namespace']) = data['kubernetes_namespace']
|
||||
request.method = 'GET'
|
||||
return self.next_view.as_view()(request)
|
||||
except exceptions.Conflict:
|
||||
|
@ -40,4 +40,12 @@
|
||||
actions, check "unrestricted".
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<p>
|
||||
{% if kubeconfig_enabled %}
|
||||
{% blocktrans trimmed %}
|
||||
You can optionally provide a Kubernetes Namespace. It will be included in the
|
||||
kubeconfig file which can be downloaded from the next screen.
|
||||
{% endblocktrans %}
|
||||
{% endif %}
|
||||
</p>
|
||||
{% endblock %}
|
||||
|
@ -31,5 +31,11 @@
|
||||
<span class="fa fa-download"></span>
|
||||
{{ download_clouds_yaml_label }}
|
||||
</a>
|
||||
{% if download_kubeconfig_url %}
|
||||
<a href="{{ download_kubeconfig_url }}" class="btn btn-default">
|
||||
<span class="fa fa-download"></span>
|
||||
{{ download_kubeconfig_label }}
|
||||
</a>
|
||||
{% endif %}
|
||||
<a onClick="location.href='{{cancel_url}}'" href="{{ cancel_url }}" class="btn btn-default">{{ cancel_label }}</a>
|
||||
{% endblock %}
|
||||
|
@ -0,0 +1,26 @@
|
||||
apiVersion: v1
|
||||
kind: Config
|
||||
clusters:
|
||||
- name: kubernetes
|
||||
cluster:
|
||||
server: {{ kubernetes_url }}
|
||||
certificate-authority-data: {{ kubernetes_certificate_authority_data }}
|
||||
contexts:
|
||||
- name: kubernetes
|
||||
context:
|
||||
cluster: kubernetes
|
||||
user: {{ user }}
|
||||
namespace: {{ kubernetes_namespace }}
|
||||
current-context: kubernetes
|
||||
users:
|
||||
- name: {{ user }}
|
||||
user:
|
||||
exec:
|
||||
apiVersion: client.authentication.k8s.io/v1beta1
|
||||
command: bin/kubectl-keystone-auth
|
||||
args:
|
||||
- "--keystone-url={{ auth_url }}
|
||||
- "--domain-name=none"
|
||||
- "--user-name={{ user }}"
|
||||
- "--application-credential-id={{ application_credential_id }}"
|
||||
- "--application-credential-secret={{ application_credential_secret }}"
|
@ -28,6 +28,8 @@ urlpatterns = [
|
||||
views.CreateSuccessfulView.as_view(), name='success'),
|
||||
url(r'^download_openrc/$',
|
||||
views.download_rc_file, name='download_openrc'),
|
||||
url(r'^download_kubeconfig/$',
|
||||
views.download_kubeconfig_file, name='download_kubeconfig'),
|
||||
url(r'^download_clouds_yaml/$',
|
||||
views.download_clouds_yaml_file, name='download_clouds_yaml'),
|
||||
]
|
||||
|
@ -86,6 +86,11 @@ class CreateView(forms.ModalFormView):
|
||||
kwargs['next_view'] = CreateSuccessfulView
|
||||
return kwargs
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(CreateView, self).get_context_data(**kwargs)
|
||||
context['kubeconfig_enabled'] = settings.KUBECONFIG_ENABLED
|
||||
return context
|
||||
|
||||
|
||||
class CreateSuccessfulView(forms.ModalFormView):
|
||||
template_name = 'identity/application_credentials/success.html'
|
||||
@ -97,15 +102,20 @@ class CreateSuccessfulView(forms.ModalFormView):
|
||||
cancel_label = _("Close")
|
||||
download_openrc_label = _("Download openrc file")
|
||||
download_clouds_yaml_label = _("Download clouds.yaml")
|
||||
download_kubeconfig_label = _("Download kubeconfig file")
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(CreateSuccessfulView, self).get_context_data(**kwargs)
|
||||
context['download_openrc_label'] = self.download_openrc_label
|
||||
context['download_clouds_yaml_label'] = self.download_clouds_yaml_label
|
||||
context['download_kubeconfig_label'] = self.download_kubeconfig_label
|
||||
context['download_openrc_url'] = reverse(
|
||||
'horizon:identity:application_credentials:download_openrc')
|
||||
context['download_clouds_yaml_url'] = reverse(
|
||||
'horizon:identity:application_credentials:download_clouds_yaml')
|
||||
if settings.KUBECONFIG_ENABLED:
|
||||
context['download_kubeconfig_url'] = reverse(
|
||||
'horizon:identity:application_credentials:download_kubeconfig')
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
@ -125,12 +135,18 @@ def _get_context(request):
|
||||
interface = 'public'
|
||||
region = getattr(request.user, 'services_region', '')
|
||||
app_cred = request.session['application_credential']
|
||||
context = dict(auth_url=auth_url,
|
||||
interface=interface,
|
||||
region=region,
|
||||
application_credential_id=app_cred['id'],
|
||||
application_credential_name=app_cred['name'],
|
||||
application_credential_secret=app_cred['secret'])
|
||||
context = {
|
||||
'auth_url': auth_url,
|
||||
'interface': interface,
|
||||
'region': region,
|
||||
'user': request.user,
|
||||
'application_credential_id': app_cred['id'],
|
||||
'application_credential_name': app_cred['name'],
|
||||
'application_credential_secret': app_cred['secret'],
|
||||
'kubernetes_namespace': app_cred['kubernetes_namespace'],
|
||||
'kubernetes_url': settings.KUBECONFIG_KUBERNETES_URL,
|
||||
'kubernetes_certificate_authority_data':
|
||||
settings.KUBECONFIG_CERTIFICATE_AUTHORITY_DATA}
|
||||
return context
|
||||
|
||||
|
||||
@ -166,6 +182,14 @@ def download_clouds_yaml_file(request):
|
||||
return _render_attachment(filename, template, context, request)
|
||||
|
||||
|
||||
def download_kubeconfig_file(request):
|
||||
context = _get_context(request)
|
||||
template = 'identity/application_credentials/kubeconfig.template'
|
||||
filename = 'app-cred-%s-kubeconfig' % context['application_credential_name']
|
||||
response = _render_attachment(filename, template, context, request)
|
||||
return response
|
||||
|
||||
|
||||
class DetailView(views.HorizonTemplateView):
|
||||
template_name = 'identity/application_credentials/detail.html'
|
||||
page_title = "{{ application_credential.name }}"
|
||||
|
@ -374,3 +374,11 @@ REST_API_REQUIRED_SETTINGS = [
|
||||
# and are not encrypted on the browser. This is an experimental API and
|
||||
# may be deprecated in the future without notice.
|
||||
REST_API_ADDITIONAL_SETTINGS = []
|
||||
|
||||
# Kubernetes clusters can use Keystone as an external identity provider.
|
||||
# Horizon can generate a 'kubeconfig' file from the application credentials
|
||||
# control panel which can be used for authenticating with a Kubernetes cluster.
|
||||
# These settings control the kubeconfig parameters.
|
||||
KUBECONFIG_ENABLED = False
|
||||
KUBECONFIG_KUBERNETES_URL = ""
|
||||
KUBECONFIG_CERTIFICATE_AUTHORITY_DATA = ""
|
||||
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
[`blueprint kubernetes-config-gen <https://blueprints.launchpad.net/horizon/+spec/kubernetes-config-gen>`_]
|
||||
Horizon now supports the optional automatic generation of a Kubernetes
|
||||
configuration file (kubeconfig) based on application credentials. Adds
|
||||
a new download button for this purpose in the application credentials
|
||||
creation dialog.
|
Loading…
Reference in New Issue
Block a user