Move 'Images' handling table to a separate panel 'Images'.

Change-Id: I626f93d1eaacb4249a342ddf9669d30cf1aede47
This commit is contained in:
Timur Sufiev 2013-10-23 14:51:34 +04:00
parent 56cee3d972
commit baed5a613c
11 changed files with 276 additions and 149 deletions

View File

@ -16,15 +16,21 @@ from django.utils.translation import ugettext_lazy as _
class DeployPanels(horizon.PanelGroup):
slug = "deployment_group"
name = _("Deployment")
slug = 'deployment_group'
name = _('Deployment')
panels = ('environments',)
class ManagePanels(horizon.PanelGroup):
slug = 'manage_metadata'
name = _('Manage')
panels = ('images',)
class Murano(horizon.Dashboard):
name = _("Murano")
slug = "murano"
panels = (DeployPanels,)
name = _('Murano')
slug = 'murano'
panels = (DeployPanels, ManagePanels)
default_panel = 'environments'
supports_tenants = True

View File

@ -15,10 +15,6 @@
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.environments.services import get_service_choices
@ -30,40 +26,3 @@ def ChoiceServiceFormFactory(request):
service = forms.ChoiceField(label=_('Service Type'),
choices=get_service_choices(request))
return _Class
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.'))

View File

@ -19,7 +19,6 @@ from django import shortcuts
from horizon import exceptions
from horizon import tables
from horizon import messages
from openstack_dashboard.api import glance
from muranodashboard.environments import api
from muranodashboard.openstack.common import timeutils
@ -57,15 +56,6 @@ class CreateEnvironment(tables.LinkAction):
api.environment_create(request, environment)
class MuranoImages(tables.LinkAction):
name = 'show_images'
verbose_name = _('Murano Images')
url = 'horizon:murano:environments:murano_images'
def allowed(self, request, environment):
return True
class DeleteEnvironment(tables.DeleteAction):
data_type_singular = _('Environment')
data_type_plural = _('Environments')
@ -229,7 +219,7 @@ class EnvironmentsTable(tables.DataTable):
verbose_name = _('Environments')
row_class = UpdateEnvironmentRow
status_columns = ['status']
table_actions = (CreateEnvironment, MuranoImages)
table_actions = (CreateEnvironment,)
row_actions = (ShowEnvironmentServices, DeployEnvironment,
EditEnvironment, DeleteEnvironment, ShowDeployments)
@ -314,39 +304,3 @@ 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:murano:environments: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 Metadata')
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,)

View File

@ -19,7 +19,6 @@ 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 ChoiceServiceFormFactory
from services import get_service_checkers
@ -47,15 +46,6 @@ urlpatterns = patterns(
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'),

View File

@ -14,7 +14,6 @@
import logging
import re
import json
import copy
from django.core.urlresolvers import reverse, reverse_lazy
@ -22,23 +21,19 @@ from django.utils.translation import ugettext_lazy as _
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, ModalFormView
from horizon.forms.views import ModalFormMixin
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
import api
from muranoclient.common.exceptions import HTTPUnauthorized, \
@ -378,43 +373,3 @@ 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:murano:environments: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:murano:environments:murano_images")

View File

@ -0,0 +1,13 @@
# Copyright (c) 2013 Mirantis, Inc.
#
# 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.

View File

@ -0,0 +1,60 @@
# Copyright (c) 2013 Mirantis, Inc.
#
# 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.
import logging
import json
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
log = logging.getLogger(__name__)
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.'))

View File

@ -0,0 +1,25 @@
# Copyright (c) 2013 Mirantis, Inc.
#
# 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.
import horizon
from django.utils.translation import ugettext_lazy as _
from muranodashboard import dashboard
class Images(horizon.Panel):
name = _("Images")
slug = 'images'
dashboard.Murano.register(Images)

View File

@ -0,0 +1,64 @@
# Copyright (c) 2013 Mirantis, Inc.
#
# 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 tables
from horizon import messages
from openstack_dashboard.api import glance
class MuranoImages(tables.LinkAction):
name = 'show_images'
verbose_name = _('Murano Images')
url = 'horizon:murano:images:murano_images'
def allowed(self, request, environment):
return True
class AddMuranoImage(tables.LinkAction):
name = "add_image"
verbose_name = _("Add Image")
url = "horizon:murano:images: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 Metadata')
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,)

View File

@ -0,0 +1,30 @@
# Copyright (c) 2013 Mirantis, Inc.
#
# 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.conf.urls.defaults import patterns, url
from .views import MuranoImageView, AddMuranoImageView
urlpatterns = patterns(
'',
url(r'^$', MuranoImageView.as_view(),
name='index'),
url(r'^add_image$', AddMuranoImageView.as_view(),
name='add_image'),
url(r'^remove_image$', MuranoImageView.as_view(),
name='remove_image'),
)

View File

@ -0,0 +1,71 @@
# Copyright (c) 2013 Mirantis, Inc.
#
# 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.
import logging
import json
from django.core.urlresolvers import reverse, reverse_lazy
from django.utils.translation import ugettext_lazy as _
from openstack_dashboard.api import glance
from horizon import exceptions
from horizon import tables
from horizon import messages
from horizon.forms.views import ModalFormView
from tables import ImagesTable
from forms import AddImageForm
from muranoclient.common.exceptions import HTTPForbidden
LOG = logging.getLogger(__name__)
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:murano:images: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:murano:images:index")