Different issues with image metadata forms

Fixed different small issues with forms related
to marking images with specific Murano metadata

Resolved Bug #1236262

Change-Id: I0a4f6c7034c76c6b7a591e26b0df5f9f29ad782d
This commit is contained in:
Serg Melikyan 2013-10-11 10:13:18 +04:00
parent e54bf89c41
commit 78496587b3
9 changed files with 128 additions and 123 deletions

View File

@ -20,8 +20,8 @@ from horizon import messages, exceptions
from openstack_dashboard.api import glance from openstack_dashboard.api import glance
import json import json
from muranodashboard.panel.services import iterate_over_service_forms, \ from muranodashboard.panel.services import iterate_over_service_forms
get_service_choices from muranodashboard.panel.services import get_service_choices
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -35,38 +35,43 @@ FORMS = [('service_choice', WizardFormServiceType)]
FORMS.extend(iterate_over_service_forms()) FORMS.extend(iterate_over_service_forms())
class AddImageForm(SelfHandlingForm): class MarkImageForm(SelfHandlingForm):
title = forms.CharField(max_length="255", _metadata = {
label=_("Image Title")) 'windows.2012.standart': ' Windows Server 2012 Desktop',
'linux': 'Generic Linux',
'cirros.demo': 'Murano Demo Image'
}
image_choices = forms.ChoiceField(label='Images') image = forms.ChoiceField(label='Image')
type = forms.ChoiceField(label="Metadata", choices=_metadata.items())
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): def __init__(self, request, *args, **kwargs):
super(AddImageForm, self).__init__(request, *args, **kwargs) super(MarkImageForm, self).__init__(request, *args, **kwargs)
images = []
try: try:
images, _more = glance.image_list_detailed(request) images, _more = glance.image_list_detailed(request)
except Exception: except Exception:
log.error("Failed to request image list from glance ") log.error('Failed to request image list from Glance')
images = [] exceptions.handle(request, _('Unable to retrieve list of images'))
exceptions.handle(request, _("Unable to retrieve public images."))
self.fields['image_choices'].choices = [(image.id, image.name) self.fields['image'].choices = [(i.id, i.name) for i in images]
for image in images]
def handle(self, request, data): def handle(self, request, data):
log.debug('Adding new murano using data {0}'.format(data)) log.debug('Marking image with specified metadata: {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')) image, mtype = (data['image'], data['type'])
properties = {
'murano_image_info': json.dumps({
'title': self._metadata[mtype],
'type': mtype
})
}
try:
image = glance.image_update(request, image, properties=properties)
messages.success(request, _('Image successfully marked'))
return image return image
except Exception: except Exception:
exceptions.handle(request, _('Unable to update image.')) exceptions.handle(request, _('Unable to mark image'))

View File

@ -57,10 +57,10 @@ class CreateEnvironment(tables.LinkAction):
api.environment_create(request, environment) api.environment_create(request, environment)
class MuranoImages(tables.LinkAction): class MarkedImages(tables.LinkAction):
name = 'show_images' name = 'show_images'
verbose_name = _('Murano Images') verbose_name = _('Marked Images')
url = 'horizon:project:murano:murano_images' url = 'horizon:project:murano:images'
def allowed(self, request, environment): def allowed(self, request, environment):
return True return True
@ -227,7 +227,7 @@ class EnvironmentsTable(tables.DataTable):
verbose_name = _('Environments') verbose_name = _('Environments')
row_class = UpdateEnvironmentRow row_class = UpdateEnvironmentRow
status_columns = ['status'] status_columns = ['status']
table_actions = (CreateEnvironment, MuranoImages) table_actions = (CreateEnvironment, MarkedImages)
row_actions = (ShowEnvironmentServices, DeployEnvironment, row_actions = (ShowEnvironmentServices, DeployEnvironment,
EditEnvironment, DeleteEnvironment, ShowDeployments) EditEnvironment, DeleteEnvironment, ShowDeployments)
@ -314,10 +314,10 @@ class EnvConfigTable(tables.DataTable):
verbose_name = _('Deployed Services') verbose_name = _('Deployed Services')
class AddMuranoImage(tables.LinkAction): class MarkImage(tables.LinkAction):
name = "add_image" name = "mark_image"
verbose_name = _("Add Image") verbose_name = _("Mark Image")
url = "horizon:project:murano:add_image" url = "horizon:project:murano:mark_image"
classes = ("ajax-modal", "btn-create") classes = ("ajax-modal", "btn-create")
def allowed(self, request, image): def allowed(self, request, image):
@ -325,26 +325,27 @@ class AddMuranoImage(tables.LinkAction):
class RemoveImageMetadata(tables.DeleteAction): class RemoveImageMetadata(tables.DeleteAction):
data_type_singular = _('Murano Metadata') data_type_singular = _('Metadata')
data_type_plural = _('Murano Metadata') data_type_plural = _('Metadata')
def delete(self, request, obj_id): def delete(self, request, obj_id):
try: try:
glance.image_update(request, obj_id, properties={}) glance.image_update(request, obj_id, properties={})
messages.success(request, _('Image removed from Murano.'))
except Exception: except Exception:
exceptions.handle(request, _('Unable to update image.')) exceptions.handle(request, _('Unable to remove metadata'))
class ImagesTable(tables.DataTable): class MarkedImagesTable(tables.DataTable):
image_title = tables.Column('title', verbose_name=_('Murano title')) image = tables.Column(
image_id = tables.Column('id', verbose_name=_('Image id')) 'name',
link='horizon:project:images_and_snapshots:images:detail',
image_name = tables.Column('name', verbose_name=_('Name in Glance')) verbose_name=_('Image')
image_type = tables.Column('name', verbose_name=_('Murano Type')) )
type = tables.Column('type', verbose_name=_('Type'))
title = tables.Column('title', verbose_name=_('Title'))
class Meta: class Meta:
name = 'images' name = 'marked_images'
verbose_name = _('Murano Images') verbose_name = _('Marked Images')
table_actions = (AddMuranoImage, RemoveImageMetadata) table_actions = (MarkImage, RemoveImageMetadata)
row_actions = (RemoveImageMetadata,) row_actions = (RemoveImageMetadata,)

View File

@ -19,7 +19,7 @@ from views import Services
from views import CreateEnvironmentView from views import CreateEnvironmentView
from views import DetailServiceView from views import DetailServiceView
from views import DeploymentsView from views import DeploymentsView
from views import MuranoImageView, AddMuranoImageView from views import MarkedImagesView, MarkImageView
from views import Wizard, EditEnvironmentView from views import Wizard, EditEnvironmentView
from forms import FORMS from forms import FORMS
from muranodashboard.panel.services import get_service_checkers from muranodashboard.panel.services import get_service_checkers
@ -40,14 +40,14 @@ urlpatterns = patterns(
url(r'^create_environment$', CreateEnvironmentView.as_view(), url(r'^create_environment$', CreateEnvironmentView.as_view(),
name='create_environment'), name='create_environment'),
url(r'^murano_images$', MuranoImageView.as_view(), url(r'^images$', MarkedImagesView.as_view(),
name='murano_images'), name='images'),
url(r'^add_image$', AddMuranoImageView.as_view(), url(r'^mark_image$', MarkImageView.as_view(),
name='add_image'), name='mark_image'),
url(r'^remove_image$', MuranoImageView.as_view(), url(r'^remove_metadata$', MarkedImagesView.as_view(),
name='remove_image'), name='remove_metadata'),
url(ENVIRONMENT_ID + r'/update_environment$', url(ENVIRONMENT_ID + r'/update_environment$',
EditEnvironmentView.as_view(), EditEnvironmentView.as_view(),

View File

@ -35,11 +35,11 @@ from tables import EnvironmentsTable
from tables import ServicesTable from tables import ServicesTable
from tables import DeploymentsTable from tables import DeploymentsTable
from tables import EnvConfigTable from tables import EnvConfigTable
from tables import ImagesTable from tables import MarkedImagesTable
from workflows import CreateEnvironment, UpdateEnvironment from workflows import CreateEnvironment, UpdateEnvironment
from tabs import ServicesTabs, DeploymentTabs from tabs import ServicesTabs, DeploymentTabs
from forms import AddImageForm from forms import MarkImageForm
from muranodashboard.panel import api from muranodashboard.panel import api
from muranoclient.common.exceptions import HTTPUnauthorized, \ from muranoclient.common.exceptions import HTTPUnauthorized, \
@ -334,40 +334,40 @@ class DeploymentDetailsView(tabs.TabbedTableView):
**kwargs) **kwargs)
class MuranoImageView(tables.DataTableView): class MarkedImagesView(tables.DataTableView):
table_class = ImagesTable table_class = MarkedImagesTable
template_name = 'images/index.html' template_name = 'images/index.html'
def get_data(self): def get_data(self):
images = [] images = []
try: try:
images, _more = glance.image_list_detailed(self.request) images, _more = glance.image_list_detailed(self.request)
except Exception:
except HTTPForbidden:
msg = _('Unable to retrieve list of images') msg = _('Unable to retrieve list of images')
exceptions.handle(self.request, msg, uri = reverse('horizon:project:murano:index')
redirect=reverse("horizon:project:murano:index"))
murano_images = [] exceptions.handle(self.request, msg, redirect=uri)
marked_images = []
for image in images: for image in images:
murano_property = image.properties.get('murano_image_info') metadata = image.properties.get('murano_image_info')
if murano_property: if metadata:
try: try:
murano_json = json.loads(murano_property) metadata = json.loads(metadata)
except ValueError: except ValueError:
LOG.warning("JSON in image metadata is not valid. " msg = _('Invalid metadata for image: {0}'.format(image.id))
"Check it in glance.") LOG.warn(msg)
messages.error(self.request, messages.error(self.request, msg)
_("Invalid murano image metadata"))
else: else:
image.title = murano_json.get('title', 'No title') image.title = metadata.get('title', 'No Title')
image.type = murano_json.get('type', 'No title') image.type = metadata.get('type', 'No Type')
murano_images.append(image) marked_images.append(image)
return murano_images return marked_images
class AddMuranoImageView(ModalFormView): class MarkImageView(ModalFormView):
form_class = AddImageForm form_class = MarkImageForm
template_name = 'images/add.html' template_name = 'images/mark.html'
context_object_name = 'image' context_object_name = 'image'
success_url = reverse_lazy("horizon:project:murano:murano_images") success_url = reverse_lazy('horizon:project:murano:images')

View File

@ -1,32 +0,0 @@
{% 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 %}

View File

@ -0,0 +1,31 @@
{% 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 %}mark_image{% endblock %}
{% block modal-header %}{% trans 'Mark 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 'Mark image with specific Murano metadata. Valid image metadata will be added to the selected image so image can be picked during service creation.' %}</p>
<p>
<strong>{% trans 'Image' %}:</strong>
{% blocktrans %}Select one of the images registered in the Glance{% endblocktrans %}
</p>
<p>
<strong>{% trans 'Metadata' %}:</strong>
{% blocktrans %}Pick metadata from supported by Murano{% endblocktrans %}
</p>
</div>
{% endblock %}
{% block modal-footer %}
<input class='btn btn-primary pull-right' type='submit' value='{% trans 'Mark' %}' />
{% endblock %}

View File

@ -1,11 +0,0 @@
{% 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 %}

View File

@ -1,9 +1,9 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load i18n %} {% load i18n %}
{% block title %}{% trans "Murano Images" %}{% endblock %} {% block title %}{% trans "Marked Images" %}{% endblock %}
{% block page_header %} {% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Murano Images") %} {% include "horizon/common/_page_header.html" with title=_("Marked Images") %}
{% endblock page_header %} {% endblock page_header %}
{% block main %} {% block main %}

View File

@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Mark Image" %}{% endblock %}
{% block page_header %}
{% include 'horizon/common/_page_header.html' with title=_('Mark image with Metadata') %}
{% endblock page_header %}
{% block main %}
{% include 'horizon/project/murano/images/_mark.html' %}
{% endblock %}