Add Horizon UIs for managing Kubernetes VIMs

- This patch implements the Horizon UIs for Kubernetes VIM type
- It also add the cert_verify option which is required by
tackerclient when registering OpenStack VIM
- Installation:
    - Go to tacker-horizon dir: `cd /opt/stack/tacker-horizon`
    - Checkout this patch: `git fetch https://git.openstack.org/openstack/tacker-horizon refs/changes/79/545279/20 && git checkout FETCH_HEAD`
    - Collectstatic and compress: `./manage.py collectstatic --noinput && echo yes | ./manage.py compress`
    - Restart apache2: `sudo systemctl restart apache2`
- Screenshot:
    - https://pasteboard.co/HbbCoZp.png
    - https://pasteboard.co/HbbGiYs.png

Change-Id: I3c4cf6e6a245a13e140740209d190c33446074c4
Implements: blueprint k8s-vim-horizon-ui
This commit is contained in:
Trinh Nguyen 2018-02-16 21:28:34 +09:00
parent b237df0434
commit 3e2604aa6f
7 changed files with 124 additions and 9 deletions

View File

@ -14,6 +14,7 @@
DASHBOARD = 'nfv'
DISABLED = False
AUTO_DISCOVER_STATIC_FILES = True
ADD_INSTALLED_APPS = [
'tacker_horizon.openstack_dashboard.dashboards.nfv',
]

View File

@ -15,6 +15,7 @@
from __future__ import absolute_import
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from oslo_log import log as logging
from oslo_utils import strutils
from tackerclient.v1_0 import client as tacker_client
@ -25,6 +26,23 @@ from openstack_dashboard.api import base
LOG = logging.getLogger(__name__)
SUPPORTED_VIM_TYPES = (
('openstack', 'OpenStack'),
('kubernetes', 'Kubernetes')
)
AUTH_METHODS = (
('basic', _('Basic')),
('bearer_token', _('Bearer Token'))
)
CERT_TRUE_TYPE = 'True'
CERT_FALSE_TYPE = 'False'
CERT_VERIFY_TYPES = (
(CERT_TRUE_TYPE, _("True")),
(CERT_FALSE_TYPE, _("False"))
)
@memoized
def tackerclient(request):

View File

@ -0,0 +1,50 @@
$( document ).ready(function() {
var vim_type = $("#id_vim_type").find(":selected").first().text();
toggle_vim_fields(vim_type);
$("#id_vim_type").change(function(){
vim_type = $("#id_vim_type").find(":selected").first().text();
toggle_vim_fields(vim_type);
});
});
function toggle_vim_fields(vim_type) {
if (vim_type === 'OpenStack') {
$("#id_username").closest(".form-group").show();
$("#id_password").closest(".form-group").show();
$("#id_password").val("");
$("#id_domain_name").closest(".form-group").show();
$("#id_ssl_ca_cert").closest(".form-group").hide();
$("#id_bearer_token").val("None");
$("#id_bearer_token").closest(".form-group").hide();
$("input[name='auth_method']").closest(".form-group").hide();
$("input[name='cert_verify']").closest(".form-group").show();
} else if (vim_type === 'Kubernetes') {
$("#id_domain_name").closest(".form-group").hide();
$("input[name='cert_verify']").closest(".form-group").hide();
$("#id_ssl_ca_cert").closest(".form-group").show();
$("#id_bearer_token").closest(".form-group").show();
$("#id_bearer_token").val("");
$("input[name='auth_method']").closest(".form-group").show();
var auth_method = $("input[name='auth_method']:checked").val();
toggle_auth_fields(auth_method);
$("input[name='auth_method']").change(function() {
toggle_auth_fields(this.value);
});
}
}
function toggle_auth_fields(auth_method) {
if (auth_method === 'basic') {
$("#id_username").closest(".form-group").show();
$("#id_password").closest(".form-group").show();
$("#id_password").val("");
$("#id_bearer_token").val("None");
$("#id_bearer_token").closest(".form-group").hide();
} else if (auth_method === 'bearer_token') {
$("#id_bearer_token").closest(".form-group").show();
$("#id_bearer_token").val("");
$("#id_username").closest(".form-group").hide();
$("#id_password").val("None");
$("#id_password").closest(".form-group").hide();
}
}

View File

@ -23,15 +23,30 @@ from tacker_horizon.openstack_dashboard import api
class RegisterVim(forms.SelfHandlingForm):
vim_type = forms.ChoiceField(choices=api.tacker.SUPPORTED_VIM_TYPES,
label=_("VIM Type"))
vim_name = forms.CharField(max_length=255, label=_("Name"))
vim_description = forms.CharField(widget=forms.widgets.Textarea(
attrs={'rows': 4}),
label=_("Description"),
required=False)
auth_url = forms.URLField(label=_("Auth URL"))
username = forms.CharField(max_length=80, label=_("Username"))
auth_method = forms.ChoiceField(widget=forms.widgets.RadioSelect,
choices=api.tacker.AUTH_METHODS,
initial="basic",
label=_("Auth Method"))
username = forms.CharField(max_length=80,
initial="admin",
label=_("Username"))
password = forms.CharField(label=_("Password"),
widget=forms.PasswordInput(render_value=False))
cert_verify = forms.ChoiceField(widget=forms.widgets.RadioSelect,
choices=api.tacker.CERT_VERIFY_TYPES,
initial="True",
label=_("Cert Verify"))
bearer_token = forms.CharField(widget=forms.widgets.Textarea(
attrs={'rows': 4}),
label=_("Bearer Token"))
project_name = forms.CharField(max_length=80, label=_("Project Name"))
domain_name = forms.CharField(max_length=80, label=_("Domain Name"),
help_text=_('Applicable for OpenStack site '
@ -39,6 +54,10 @@ class RegisterVim(forms.SelfHandlingForm):
'openstack domain list from '
'CLI to find domain name'),
required=False)
ssl_ca_cert = forms.CharField(widget=forms.widgets.Textarea(
attrs={'rows': 4}),
label=_("SSL CA Certificate"),
required=False)
is_default = forms.BooleanField(
label=_("Default"),
initial=False,
@ -67,13 +86,30 @@ class RegisterVim(forms.SelfHandlingForm):
project_name = data['project_name']
is_default = data['is_default']
auth_url = data['auth_url']
vim_type = 'openstack'
domain_name = data['domain_name']
cert_verify = data.get('cert_verify', api.tacker.CERT_TRUE_TYPE)
if cert_verify not in [api.tacker.CERT_TRUE_TYPE,
api.tacker.CERT_FALSE_TYPE]:
raise forms.ValidationError("cert_verify type not supported.")
auth_cred = {'username': username,
'password': password,
'user_domain_name': domain_name,
'cert_verify': cert_verify}
bearer_token = data['bearer_token'].replace('None', '')
ssl_ca_cert = data['ssl_ca_cert'].replace('\r\n', ' ')
vim_type = data['vim_type']
if vim_type == 'kubernetes':
auth_cred = {'username': username,
'password': password}
# if bearer_token is provided, use it instead
if bearer_token:
auth_cred = {'bearer_token': bearer_token}
# only k8s vim needs ssl_ca_cert and it's optional
if ssl_ca_cert:
auth_cred['ssl_ca_cert'] = ssl_ca_cert
vim_arg = {'vim': {'name': vim_name, 'description': description,
'type': vim_type, 'auth_url': auth_url,
'auth_cred': {'username': username,
'password': password,
'user_domain_name': domain_name},
'auth_cred': auth_cred,
'vim_project': {'name': project_name,
'project_domain_name':
domain_name},

View File

@ -66,6 +66,7 @@ class VIMTable(tables.DataTable):
user = tables.Column('user', verbose_name=_("User"))
project = tables.Column('project', verbose_name=_("Project"))
status = tables.Column('status', verbose_name=_("Status"))
type = tables.Column('type', verbose_name=_("VIM Type"))
class Meta(object):
name = "vim"

View File

@ -25,7 +25,7 @@ from tacker_horizon.openstack_dashboard.dashboards.nfv.vim import tables
class VIMItem(object):
def __init__(self, name, description, is_default, regions, vim_id,
auth_url, user, project, status):
auth_url, user, project, status, vim_type):
self.id = vim_id
self.name = name
self.description = description
@ -35,6 +35,7 @@ class VIMItem(object):
self.user = user
self.project = project
self.status = status
self.type = vim_type
class VIMTab(tabs.TableTab):
@ -56,20 +57,24 @@ class VIMTab(tabs.TableTab):
auth_cred = vim['auth_cred']
placement_attr = vim['placement_attr']
vim_regions = ','.join(placement_attr['regions'])
user = auth_cred['username'] if auth_cred[
'username'] else auth_cred['user_id']
user = "<Bearer token>"
if 'bearer_token' not in auth_cred.keys():
user = auth_cred['username'] if auth_cred[
'username'] else auth_cred['user_id']
project_info = vim['vim_project']
project = project_info['name'] if project_info[
'name'] else project_info['id']
status = vim["status"]
is_default = vim['is_default']
vim_type = vim["type"]
item = VIMItem(name=vim.get('name', ''),
description=vim.get('description', ''),
is_default=is_default,
regions=vim_regions,
vim_id=vim.get('id', ''),
auth_url=vim.get('auth_url', ''),
user=user, project=project, status=status)
user=user, project=project, status=status,
vim_type=vim_type)
instances.append(item)
return instances
except Exception:

View File

@ -7,3 +7,7 @@
<h3>{% trans "Description:" %}</h3>
<p>{% trans "Registers a VIM." %}</p>
{% endblock %}
{% block modal-js %}
<script src='{{ STATIC_URL }}nfv/js/nfv.vim.reg.js' type='text/javascript' charset='utf-8'></script>
{% endblock %}