Support Murano Images
Change-Id: I12e5833c91de9d7a757b4e0005fcfcabf0f4d42d
This commit is contained in:
parent
1015f6d98b
commit
a393a33171
|
@ -15,6 +15,11 @@
|
|||
import logging
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from horizon.forms import SelfHandlingForm
|
||||
from horizon import messages, exceptions
|
||||
from openstack_dashboard.api import glance
|
||||
import json
|
||||
|
||||
from muranodashboard.panel.services import iterate_over_service_forms, \
|
||||
get_service_choices
|
||||
|
||||
|
@ -28,3 +33,40 @@ class WizardFormServiceType(forms.Form):
|
|||
|
||||
FORMS = [('service_choice', WizardFormServiceType)]
|
||||
FORMS.extend(iterate_over_service_forms())
|
||||
|
||||
|
||||
class AddImageForm(SelfHandlingForm):
|
||||
title = forms.CharField(max_length="255",
|
||||
label=_("Image Title"))
|
||||
|
||||
image_choices = forms.ChoiceField(label='Images')
|
||||
|
||||
windows_image = ('ws-2012-std', ' Windows Server 2012 Desktop')
|
||||
demo_image = ('murano_demo', 'Murano Demo Image')
|
||||
|
||||
image_type = forms.ChoiceField(label="Murano Type",
|
||||
choices=[windows_image, demo_image])
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
super(AddImageForm, self).__init__(request, *args, **kwargs)
|
||||
try:
|
||||
images, _more = glance.image_list_detailed(request)
|
||||
except Exception:
|
||||
log.error("Failed to request image list from glance ")
|
||||
images = []
|
||||
exceptions.handle(request, _("Unable to retrieve public images."))
|
||||
self.fields['image_choices'].choices = [(image.id, image.name)
|
||||
for image in images]
|
||||
|
||||
def handle(self, request, data):
|
||||
log.debug('Adding new murano using data {0}'.format(data))
|
||||
murano_properties = {'murano_image_info': json.dumps(
|
||||
{'title': data['title'], 'type': data['image_type']})}
|
||||
try:
|
||||
image = glance.image_update(request, data['image_choices'],
|
||||
properties=murano_properties)
|
||||
|
||||
messages.success(request, _('Image added to Murano'))
|
||||
return image
|
||||
except Exception:
|
||||
exceptions.handle(request, _('Unable to update image.'))
|
||||
|
|
|
@ -19,6 +19,7 @@ from django import shortcuts
|
|||
from horizon import exceptions
|
||||
from horizon import tables
|
||||
from horizon import messages
|
||||
from openstack_dashboard.api import glance
|
||||
|
||||
from muranodashboard.panel import api
|
||||
from muranodashboard.openstack.common import timeutils
|
||||
|
@ -56,6 +57,15 @@ class CreateEnvironment(tables.LinkAction):
|
|||
api.environment_create(request, environment)
|
||||
|
||||
|
||||
class MuranoImages(tables.LinkAction):
|
||||
name = 'show_images'
|
||||
verbose_name = _('Murano Images')
|
||||
url = 'horizon:project:murano:murano_images'
|
||||
|
||||
def allowed(self, request, environment):
|
||||
return True
|
||||
|
||||
|
||||
class DeleteEnvironment(tables.DeleteAction):
|
||||
data_type_singular = _('Environment')
|
||||
data_type_plural = _('Environments')
|
||||
|
@ -217,7 +227,7 @@ class EnvironmentsTable(tables.DataTable):
|
|||
verbose_name = _('Environments')
|
||||
row_class = UpdateEnvironmentRow
|
||||
status_columns = ['status']
|
||||
table_actions = (CreateEnvironment,)
|
||||
table_actions = (CreateEnvironment, MuranoImages)
|
||||
row_actions = (ShowEnvironmentServices, DeployEnvironment,
|
||||
EditEnvironment, DeleteEnvironment, ShowDeployments)
|
||||
|
||||
|
@ -302,3 +312,39 @@ class EnvConfigTable(tables.DataTable):
|
|||
class Meta:
|
||||
name = 'environment_configuration'
|
||||
verbose_name = _('Deployed Services')
|
||||
|
||||
|
||||
class AddMuranoImage(tables.LinkAction):
|
||||
name = "add_image"
|
||||
verbose_name = _("Add Image")
|
||||
url = "horizon:project:murano:add_image"
|
||||
classes = ("ajax-modal", "btn-create")
|
||||
|
||||
def allowed(self, request, image):
|
||||
return True
|
||||
|
||||
|
||||
class RemoveImageMetadata(tables.DeleteAction):
|
||||
data_type_singular = _('Murano Metadata')
|
||||
data_type_plural = _('Murano Metadatum')
|
||||
|
||||
def delete(self, request, obj_id):
|
||||
try:
|
||||
glance.image_update(request, obj_id, properties={})
|
||||
messages.success(request, _('Image removed from Murano.'))
|
||||
except Exception:
|
||||
exceptions.handle(request, _('Unable to update image.'))
|
||||
|
||||
|
||||
class ImagesTable(tables.DataTable):
|
||||
image_title = tables.Column('title', verbose_name=_('Murano title'))
|
||||
image_id = tables.Column('id', verbose_name=_('Image id'))
|
||||
|
||||
image_name = tables.Column('name', verbose_name=_('Name in Glance'))
|
||||
image_type = tables.Column('name', verbose_name=_('Murano Type'))
|
||||
|
||||
class Meta:
|
||||
name = 'images'
|
||||
verbose_name = _('Murano Images')
|
||||
table_actions = (AddMuranoImage, RemoveImageMetadata)
|
||||
row_actions = (RemoveImageMetadata,)
|
||||
|
|
|
@ -19,6 +19,7 @@ from views import Services
|
|||
from views import CreateEnvironmentView
|
||||
from views import DetailServiceView
|
||||
from views import DeploymentsView
|
||||
from views import MuranoImageView, AddMuranoImageView
|
||||
from views import Wizard, EditEnvironmentView
|
||||
from forms import FORMS
|
||||
from muranodashboard.panel.services import get_service_checkers
|
||||
|
@ -36,9 +37,18 @@ urlpatterns = patterns(
|
|||
condition_dict=dict(get_service_checkers())),
|
||||
name='create'),
|
||||
|
||||
url(r'^create_environment/$', CreateEnvironmentView.as_view(),
|
||||
url(r'^create_environment$', CreateEnvironmentView.as_view(),
|
||||
name='create_environment'),
|
||||
|
||||
url(r'^murano_images$', MuranoImageView.as_view(),
|
||||
name='murano_images'),
|
||||
|
||||
url(r'^add_image$', AddMuranoImageView.as_view(),
|
||||
name='add_image'),
|
||||
|
||||
url(r'^remove_image$', MuranoImageView.as_view(),
|
||||
name='remove_image'),
|
||||
|
||||
url(ENVIRONMENT_ID + r'/update_environment$',
|
||||
EditEnvironmentView.as_view(),
|
||||
name='update_environment'),
|
||||
|
@ -56,5 +66,6 @@ urlpatterns = patterns(
|
|||
DeploymentsView.as_view(), name='deployments'),
|
||||
|
||||
url(ENVIRONMENT_ID + r'/deployments/(?P<deployment_id>[^/]+)$',
|
||||
DeploymentDetailsView.as_view(), name='deployment_details')
|
||||
DeploymentDetailsView.as_view(), name='deployment_details'),
|
||||
|
||||
)
|
||||
|
|
|
@ -18,21 +18,28 @@ import json
|
|||
|
||||
from django.core.urlresolvers import reverse, reverse_lazy
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.encoding import smart_text
|
||||
from django.contrib.formtools.wizard.views import SessionWizardView
|
||||
from django.http import HttpResponseRedirect
|
||||
|
||||
|
||||
from openstack_dashboard.api import glance
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import tabs
|
||||
from horizon import tables
|
||||
from horizon import workflows
|
||||
from horizon import messages
|
||||
from horizon.forms.views import ModalFormMixin
|
||||
from horizon.forms.views import ModalFormMixin, ModalFormView
|
||||
from tables import EnvironmentsTable
|
||||
from tables import ServicesTable
|
||||
from tables import DeploymentsTable
|
||||
from tables import EnvConfigTable
|
||||
from tables import ImagesTable
|
||||
|
||||
from workflows import CreateEnvironment, UpdateEnvironment
|
||||
from tabs import ServicesTabs, DeploymentTabs
|
||||
from forms import AddImageForm
|
||||
|
||||
from muranodashboard.panel import api
|
||||
from muranoclient.common.exceptions import HTTPUnauthorized, \
|
||||
|
@ -325,3 +332,42 @@ class DeploymentDetailsView(tabs.TabbedTableView):
|
|||
|
||||
return self.tab_group_class(request, deployment=deployment, logs=logs,
|
||||
**kwargs)
|
||||
|
||||
|
||||
class MuranoImageView(tables.DataTableView):
|
||||
table_class = ImagesTable
|
||||
template_name = 'images/index.html'
|
||||
|
||||
def get_data(self):
|
||||
images = []
|
||||
try:
|
||||
images, _more = glance.image_list_detailed(self.request)
|
||||
|
||||
except HTTPForbidden:
|
||||
msg = _('Unable to retrieve list of images')
|
||||
exceptions.handle(self.request, msg,
|
||||
redirect=reverse("horizon:project:murano:index"))
|
||||
murano_images = []
|
||||
for image in images:
|
||||
murano_property = image.properties.get('murano_image_info')
|
||||
if murano_property:
|
||||
try:
|
||||
murano_json = json.loads(murano_property)
|
||||
except ValueError:
|
||||
LOG.warning("JSON in image metadata is not valid. "
|
||||
"Check it in glance.")
|
||||
messages.error(self.request,
|
||||
_("Invalid murano image metadata"))
|
||||
else:
|
||||
image.title = murano_json.get('title', 'No title')
|
||||
image.type = murano_json.get('type', 'No title')
|
||||
|
||||
murano_images.append(image)
|
||||
return murano_images
|
||||
|
||||
|
||||
class AddMuranoImageView(ModalFormView):
|
||||
form_class = AddImageForm
|
||||
template_name = 'images/add.html'
|
||||
context_object_name = 'image'
|
||||
success_url = reverse_lazy("horizon:project:murano:murano_images")
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block form_id %}add_murano_image_form{% endblock %}
|
||||
{% block form_attrs %}enctype="multipart/form-data"{% endblock %}
|
||||
{% block form_action %}add_image{% endblock %}
|
||||
{% block modal-header %}{% trans "Add An Image" %}{% endblock %}
|
||||
|
||||
{% block modal-body %}
|
||||
<div class="left">
|
||||
<fieldset>
|
||||
{% include "horizon/common/_form_fields.html" %}
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="right">
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans "Add image to Murano. Valid image metadata will be added so this image can be picked during service creation." %}</p>
|
||||
<p><strong>{% trans "Image Title" %}</strong>
|
||||
{% blocktrans %}Enter an image desciption which will help you to recognize the service during service creation {% endblocktrans %}
|
||||
</p>
|
||||
<p><strong>{% trans "Images" %}</strong>
|
||||
{% blocktrans %}Select image from Glance{% endblocktrans %}
|
||||
</p>
|
||||
<p><strong>{% trans "Murano Type" %}</strong>
|
||||
{% blocktrans %}Pick image type from supported by Murano{% endblocktrans %}
|
||||
</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block modal-footer %}
|
||||
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Update Image" %}" />
|
||||
{% endblock %}
|
|
@ -0,0 +1,11 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Add An Image" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Add Image To Murano") %}
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'horizon/project/murano/images/_add.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,11 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Murano Images" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Murano Images") %}
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
{{ table.render }}
|
||||
{% endblock %}
|
Loading…
Reference in New Issue