--- a/components/openstack/horizon/files/overrides.py Tue Nov 22 15:31:31 2016 -0800
+++ b/components/openstack/horizon/files/overrides.py Thu Nov 24 00:59:36 2016 +0000
@@ -17,6 +17,9 @@
"""
from django.conf import settings
+from django.conf.urls import patterns
+from django.conf.urls import url
+from django.core.urlresolvers import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
@@ -24,6 +27,9 @@
from horizon import workflows
from openstack_dashboard import api
+from openstack_dashboard.dashboards.admin.flavors import \
+ urls as flavor_urls, views as flavor_views, workflows as flavor_workflows
+from openstack_dashboard.dashboards.admin.flavors.views import INDEX_URL
from openstack_dashboard.dashboards.admin.instances.forms import \
LiveMigrateForm
from openstack_dashboard.dashboards.admin.instances.tables import \
@@ -37,6 +43,10 @@
from openstack_dashboard.dashboards.project.instances.workflows import \
create_instance, update_instance
+SOLARIS_ZONE_TYPE_CHOICES = (('solaris-kz', 'Solaris Kernel Zone'),
+ ('solaris', 'Solaris Non-Global Zone'))
+SOLARIS_ZONE_TYPE_DEFAULT = SOLARIS_ZONE_TYPE_CHOICES[0][0]
+
# Bootargs feature:
# Add bootargs feature to 'SetAdvanced' workflow action.
@@ -178,3 +188,178 @@
temp = list(ImagesTable._meta.row_actions)
temp.remove(CreateVolumeFromImage)
ImagesTable._meta.row_actions = tuple(temp)
+
+
+# Solaris brand type feature.
+# Override CreateFlavorInfoAction adding Solaris Zone Brand drop down
+# if SOLARIS_BRANDTYPE is set to True
+class SolarisCreateFlavorInfoAction(flavor_workflows.CreateFlavorInfoAction):
+ if getattr(settings, 'SOLARIS_BRANDTYPE', True):
+ zone_brand = forms.ChoiceField(label=_("Solaris Zone Brand"),
+ required=True,
+ choices=SOLARIS_ZONE_TYPE_CHOICES)
+
+ class Meta(object):
+ name = _("Flavor Information")
+ help_text = _("Flavors define the sizes for RAM, disk, number of "
+ "cores, and other resources and can be selected when "
+ "users deploy instances.")
+
+
+# Solaris brand type feature.
+# Override UpdateFlavorInfoAction adding Solaris Zone Brand drop down
+# if SOLARIS_BRANDTYPE is set to True
+class SolarisUpdateFlavorInfoAction(flavor_workflows.UpdateFlavorInfoAction):
+ if getattr(settings, 'SOLARIS_BRANDTYPE', True):
+ zone_brand = forms.ChoiceField(label=_("Solaris Zone Brand"),
+ required=True,
+ choices=SOLARIS_ZONE_TYPE_CHOICES)
+
+ class Meta(object):
+ name = _("Flavor Information")
+ slug = 'update_info'
+ help_text = _("Edit the flavor details. Flavors define the sizes for "
+ "RAM, disk, number of cores, and other resources. "
+ "Flavors are selected when users deploy instances.")
+
+
+# Solaris brand type feature.
+# Override CreateFlavor ensuring brand type metadata is saved to flavor
+class SolarisCreateFlavor(flavor_workflows.CreateFlavor):
+ def handle(self, request, data):
+ flavor_id = data.get('flavor_id') or 'auto'
+ swap = data.get('swap_mb') or 0
+ ephemeral = data.get('eph_gb') or 0
+ flavor_access = data['flavor_access']
+ is_public = not flavor_access
+ rxtx_factor = data.get('rxtx_factor') or 1
+ zone_brand = data.get('zone_brand')
+ metadata = {'zonecfg:brand': zone_brand}
+
+ # Create the flavor
+ try:
+ self.object = api.nova.flavor_create(request,
+ name=data['name'],
+ memory=data['memory_mb'],
+ vcpu=data['vcpus'],
+ disk=data['disk_gb'],
+ ephemeral=ephemeral,
+ swap=swap,
+ flavorid=flavor_id,
+ is_public=is_public,
+ rxtx_factor=rxtx_factor,
+ metadata=metadata)
+ except Exception:
+ exceptions.handle(request, _('Unable to create flavor.'))
+ return False
+
+ # Update flavor access if the new flavor is not public
+ flavor_id = self.object.id
+ for project in flavor_access:
+ try:
+ api.nova.add_tenant_to_flavor(
+ request, flavor_id, project)
+ except Exception:
+ exceptions.handle(
+ request,
+ _('Unable to set flavor access for project %s.') % project)
+ return True
+
+
+# Solaris brand type feature.
+# Override UpdateFlavor ensuring brand type metadata is saved to flavor
+class SolarisUpdateFlavor(flavor_workflows.UpdateFlavor):
+ def handle(self, request, data):
+ flavor_projects = data["flavor_access"]
+ is_public = not flavor_projects
+
+ # Update flavor information
+ try:
+ flavor_id = data['flavor_id']
+ # Grab any existing extra specs, because flavor edit is currently
+ # implemented as a delete followed by a create.
+ extras_dict = api.nova.flavor_get_extras(self.request,
+ flavor_id,
+ raw=True)
+ extras_dict['zonecfg:brand'] = data['zone_brand']
+ # Mark the existing flavor as deleted.
+ api.nova.flavor_delete(request, flavor_id)
+ # Then create a new flavor with the same name but a new ID.
+ # This is in the same try/except block as the delete call
+ # because if the delete fails the API will error out because
+ # active flavors can't have the same name.
+ flavor = api.nova.flavor_create(request,
+ data['name'],
+ data['memory_mb'],
+ data['vcpus'],
+ data['disk_gb'],
+ ephemeral=data['eph_gb'],
+ swap=data['swap_mb'],
+ is_public=is_public,
+ rxtx_factor=data['rxtx_factor'])
+ if (extras_dict):
+ api.nova.flavor_extra_set(request, flavor.id, extras_dict)
+ except Exception:
+ exceptions.handle(request, ignore=True)
+ return False
+
+ # Add flavor access if the flavor is not public.
+ for project in flavor_projects:
+ try:
+ api.nova.add_tenant_to_flavor(request, flavor.id, project)
+ except Exception:
+ exceptions.handle(request, _('Modified flavor information, '
+ 'but unable to modify flavor '
+ 'access.'))
+ return True
+
+
+# Solaris brand type feature.
+# Override UpdateView ensuring brand type metadata is retrieved from flavor
+class SolarisUpdateView(flavor_views.UpdateView):
+ def get_initial(self):
+ flavor_id = self.kwargs['id']
+
+ try:
+ # Get initial flavor information
+ flavor = api.nova.flavor_get(self.request, flavor_id,
+ get_extras=True)
+ except Exception:
+ exceptions.handle(self.request,
+ _('Unable to retrieve flavor details.'),
+ redirect=reverse_lazy(INDEX_URL))
+
+ if "zonecfg:brand" not in flavor.extras:
+ zone_brand = SOLARIS_ZONE_TYPE_DEFAULT
+ else:
+ zone_brand = flavor.extras['zonecfg:brand']
+
+ return {'flavor_id': flavor.id,
+ 'name': flavor.name,
+ 'vcpus': flavor.vcpus,
+ 'memory_mb': flavor.ram,
+ 'disk_gb': flavor.disk,
+ 'swap_mb': flavor.swap or 0,
+ 'rxtx_factor': flavor.rxtx_factor or 1,
+ 'eph_gb': getattr(flavor, 'OS-FLV-EXT-DATA:ephemeral', None),
+ 'zone_brand': zone_brand}
+
+
+# Solaris brand type feature.
+# Various overrides only peformed if SOLARIS_BRANDTYPE is set to True
+if getattr(settings, 'SOLARIS_BRANDTYPE', True):
+ flavor_workflows.CreateFlavorInfo.action_class = \
+ SolarisCreateFlavorInfoAction
+ flavor_workflows.CreateFlavorInfo.contributes += ('zone_brand',)
+ flavor_workflows.UpdateFlavorInfo.action_class = \
+ SolarisUpdateFlavorInfoAction
+ flavor_workflows.UpdateFlavorInfo.contributes += ('zone_brand',)
+ flavor_views.CreateView.workflow_class = SolarisCreateFlavor
+ flavor_views.UpdateView.workflow_class = SolarisUpdateFlavor
+ flavor_urls.urlpatterns = patterns(
+ 'openstack_dashboard.dashboards.admin.flavors.views',
+ url(r'^$', flavor_views.IndexView.as_view(), name='index'),
+ url(r'^create/$', flavor_views.CreateView.as_view(), name='create'),
+ url(r'^(?P<id>[^/]+)/update/$', SolarisUpdateView.as_view(),
+ name='update'),
+ )