Merge "Add import of node group templates"

This commit is contained in:
Zuul 2017-11-15 10:48:33 +00:00 committed by Gerrit Code Review
commit bd9df45a36
8 changed files with 257 additions and 6 deletions

View File

@ -166,7 +166,8 @@ def nodegroup_template_create(request, name, plugin_name, hadoop_version,
use_autoconfig=None,
shares=None,
is_public=None,
is_protected=None):
is_protected=None,
volume_mount_prefix=None):
return client(request).node_group_templates.create(
name=name,
plugin_name=plugin_name,
@ -189,7 +190,8 @@ def nodegroup_template_create(request, name, plugin_name, hadoop_version,
use_autoconfig=use_autoconfig,
shares=shares,
is_public=is_public,
is_protected=is_protected)
is_protected=is_protected,
volume_mount_prefix=volume_mount_prefix)
def nodegroup_template_list(request, search_opts=None,

View File

@ -0,0 +1,163 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import forms
from openstack_dashboard.api import neutron
from openstack_dashboard.dashboards.project.instances \
import utils as nova_utils
from oslo_serialization import jsonutils as json
from saharaclient.api import base as api_base
from sahara_dashboard.api import sahara as saharaclient
BASE_IMAGE_URL = "horizon:project:data_processing.clusters:register"
class ImportNodegroupTemplateFileForm(forms.SelfHandlingForm):
class Meta(object):
name = _("Import Node Group Template")
def __init__(self, *args, **kwargs):
self.next_view = kwargs.pop('next_view')
super(ImportNodegroupTemplateFileForm, self).__init__(
*args, **kwargs)
template_upload = forms.FileField(
label=_('Template File'),
required=True)
def handle(self, request, data):
kwargs = {'template_upload': data['template_upload']}
request.method = 'GET'
return self.next_view.as_view()(request, **kwargs)
class ImportNodegroupTemplateDetailsForm(forms.SelfHandlingForm):
class Meta(object):
name = _("Import Node Group Template")
template = forms.CharField(
widget=forms.widgets.HiddenInput)
name = forms.CharField(label=_("Name"),
required=False,
help_text=_("Name must be provided "
"either here or in the template. If "
"provided in both places, this one "
"will be used."))
security_groups = forms.MultipleChoiceField(
label=_("Security Groups"),
widget=forms.CheckboxSelectMultiple(),
help_text=_("Launch instances in these security groups. "
"Auto security group will be determined by the "
"value present in the imported template."),
required=False)
floating_ip_pool = forms.ChoiceField(
label=_("Floating IP Pool"),
required=False)
flavor = forms.ChoiceField(label=_("Openstack Flavor"))
image_id = forms.DynamicChoiceField(label=_("Base Image"),
add_item_link=BASE_IMAGE_URL)
def _populate_image_choices(self, request, plugin, hadoop_version):
all_images = saharaclient.image_list(request)
details = saharaclient.plugin_get_version_details(request,
plugin,
hadoop_version)
return [(image.id, image.name) for image in all_images
if (set(details.required_image_tags).
issubset(set(image.tags)))]
def __init__(self, *args, **kwargs):
try:
request = args[0]
template_string = ""
if "template_upload" in kwargs:
template_upload = kwargs.pop('template_upload')
super(ImportNodegroupTemplateDetailsForm, self).__init__(
*args, **kwargs)
template_string = template_upload.read()
self.fields["template"].initial = template_string
else:
super(ImportNodegroupTemplateDetailsForm, self).__init__(
*args, **kwargs)
template_string = self.data["template"]
template_json = json.loads(template_string)
template_json = template_json["node_group_template"]
security_group_list = neutron.security_group_list(request)
security_group_choices = \
[(sg.id, sg.name) for sg in security_group_list]
self.fields["security_groups"].choices = security_group_choices
pools = neutron.floating_ip_pools_list(request)
pool_choices = [(pool.id, pool.name) for pool in pools]
pool_choices.insert(0, (None, "Do not assign floating IPs"))
self.fields["floating_ip_pool"].choices = pool_choices
flavors = nova_utils.flavor_list(request)
if flavors:
self.fields["flavor"].choices = nova_utils.sort_flavor_list(
request, flavors)
else:
self.fields["flavor"].choices = []
self.fields["image_id"].choices = \
self._populate_image_choices(request,
template_json["plugin_name"],
template_json["hadoop_version"])
except (ValueError, KeyError):
raise exceptions.BadRequest(_("Could not parse template"))
except Exception:
exceptions.handle(request)
def handle(self, request, data):
try:
template = data["template"]
template = json.loads(template)
template = template["node_group_template"]
if not data["name"] and "name" not in template.keys():
return False
if data["name"]:
template["name"] = data["name"]
template["security_groups"] = data["security_groups"]
template["floating_ip_pool"] = data["floating_ip_pool"]
template["flavor_id"] = data["flavor"]
template["image_id"] = data["image_id"]
saharaclient.nodegroup_template_create(request, **template)
return True
except api_base.APIException as e:
self.error_description = str(e)
return False
except Exception as e:
if isinstance(e, TypeError):
raise exceptions.BadRequest(
_("Template JSON contained invalid key"))
else:
raise exceptions.BadRequest(_("Could not parse template"))

View File

@ -43,6 +43,15 @@ class CreateNodegroupTemplate(tables.LinkAction):
icon = "plus"
class ImportNodegroupTemplate(tables.LinkAction):
name = "import"
verbose_name = _("Import Template")
url = ("horizon:project:data_processing.clusters:"
"import-nodegroup-template-file")
classes = ("ajax-modal",)
icon = "plus"
class ConfigureNodegroupTemplate(tables.LinkAction):
name = "configure"
verbose_name = _("Configure Template")
@ -149,6 +158,7 @@ class NodegroupTemplatesTable(sahara_table.SaharaPaginateTabbedTable):
name = "nodegroup_templates"
verbose_name = _("Node Group Templates")
table_actions = (CreateNodegroupTemplate,
ImportNodegroupTemplate,
ConfigureNodegroupTemplate,
DeleteTemplate,
NodeGroupTemplatesFilterAction,)

View File

@ -12,9 +12,11 @@
# limitations under the License.
from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import forms
from horizon import tabs
from horizon.utils import memoized
from horizon import workflows
@ -30,6 +32,8 @@ import sahara_dashboard.content.data_processing.clusters. \
nodegroup_templates.workflows.create as create_flow
import sahara_dashboard.content.data_processing.clusters. \
nodegroup_templates.workflows.edit as edit_flow
import sahara_dashboard.content.data_processing.clusters. \
nodegroup_templates.forms.import_forms as import_forms
class NodegroupTemplateDetailsView(tabs.TabView):
@ -49,8 +53,8 @@ class NodegroupTemplateDetailsView(tabs.TabView):
exceptions.handle(self.request, msg, redirect=redirect)
def get_context_data(self, **kwargs):
context = super(NodegroupTemplateDetailsView, self)\
.get_context_data(**kwargs)
context = super(
NodegroupTemplateDetailsView, self).get_context_data(**kwargs)
node_group_template = self.get_object()
context['template'] = node_group_template
context['url'] = self.get_redirect_url()
@ -97,8 +101,8 @@ class CopyNodegroupTemplateView(workflows.WorkflowView):
template_name = "nodegroup_templates/configure.html"
def get_context_data(self, **kwargs):
context = super(CopyNodegroupTemplateView, self)\
.get_context_data(**kwargs)
context = super(
CopyNodegroupTemplateView, self).get_context_data(**kwargs)
context["template_id"] = kwargs["template_id"]
return context
@ -127,3 +131,38 @@ class EditNodegroupTemplateView(CopyNodegroupTemplateView):
success_url = ("horizon:project:"
"data_processing.clusters:index")
template_name = "nodegroup_templates/configure.html"
class ImportNodegroupTemplateFileView(forms.ModalFormView):
template_name = "nodegroup_templates/import.html"
form_class = import_forms.ImportNodegroupTemplateFileForm
submit_label = _("Next")
submit_url = reverse_lazy("horizon:project:data_processing."
"clusters:import-nodegroup-template-file")
success_url = reverse_lazy("horizon:project:data_processing."
"clusters:import-nodegroup-template-details")
page_title = _("Import Node Group Template")
def get_form_kwargs(self):
kwargs = super(
ImportNodegroupTemplateFileView, self).get_form_kwargs()
kwargs['next_view'] = ImportNodegroupTemplateDetailsView
return kwargs
class ImportNodegroupTemplateDetailsView(forms.ModalFormView):
template_name = "nodegroup_templates/import.html"
form_class = import_forms.ImportNodegroupTemplateDetailsForm
submit_label = _("Import")
submit_url = reverse_lazy("horizon:project:data_processing."
"clusters:import-nodegroup-template-details")
success_url = reverse_lazy("horizon:project:data_processing."
"clusters:index")
page_title = _("Import Node Group Template")
def get_form_kwargs(self):
kwargs = super(
ImportNodegroupTemplateDetailsView, self).get_form_kwargs()
if 'template_upload' in self.kwargs:
kwargs['template_upload'] = self.kwargs['template_upload']
return kwargs

View File

@ -0,0 +1,24 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% block form_id %}import-nodegroup-template{% endblock %}
{% block form_action %}{{ submit_url }}{% endblock %}
{% block form_attrs %}enctype="multipart/form-data"{% endblock %}
{% block modal-header %}{{ page_title }}{% endblock %}
{% block modal-body %}
<div class="left">
<fieldset>
{% include "horizon/common/_form_fields.html" %}
</fieldset>
</div>
{% endblock %}
{% block modal-footer %}
<input class="btn btn-primary pull-right" id="upload_file_btn" type="submit" value="{{ submit_label }}"/>
<a href="{% url 'horizon:project:data_processing.clusters:index' %}"
class="btn btn-default cancel">{% trans "Cancel" %}</a>
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Import Node Group Template" %}{% endblock %}
{% block main %}
{% include 'nodegroup_templates/_import.html' %}
{% endblock %}

View File

@ -48,6 +48,12 @@ urlpatterns = [url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^configure-nodegroup-template$',
ngt_views.ConfigureNodegroupTemplateView.as_view(),
name='configure-nodegroup-template'),
url(r'^import-nodegroup-template-file$',
ngt_views.ImportNodegroupTemplateFileView.as_view(),
name='import-nodegroup-template-file'),
url(r'^import-nodegroup-template-details$',
ngt_views.ImportNodegroupTemplateDetailsView.as_view(),
name='import-nodegroup-template-details'),
url(r'^cluster-template/(?P<template_id>[^/]+)$',
ct_views.ClusterTemplateDetailsView.as_view(),
name='ct-details'),