diff --git a/dashboard/ReadMe.txt b/dashboard/ReadMe.txt index 39e951eec..6678e44f1 100644 --- a/dashboard/ReadMe.txt +++ b/dashboard/ReadMe.txt @@ -1,7 +1,5 @@ # TO DO: -# 1. Fix issue with Create button -# 2. Create simple form for Windows Data Center deploy -# 3. Remove extra code +# 1. Remove extra code # This file is described how to install new tab on horizon dashboard. diff --git a/dashboard/windc/forms.py b/dashboard/windc/forms.py index 518a9a04c..5eb53dfe0 100644 --- a/dashboard/windc/forms.py +++ b/dashboard/windc/forms.py @@ -46,7 +46,7 @@ class UpdateInstance(forms.SelfHandlingForm): _('Instance "%s" updated.') % data['name']) return server except: - redirect = reverse("horizon:project:instances:index") + redirect = reverse("horizon:project:windc:index") exceptions.handle(request, _('Unable to update instance.'), redirect=redirect) diff --git a/dashboard/windc/panel.py b/dashboard/windc/panel.py index cc464af88..92bad578a 100644 --- a/dashboard/windc/panel.py +++ b/dashboard/windc/panel.py @@ -22,7 +22,7 @@ from openstack_dashboard.dashboards.project import dashboard class WinDC(horizon.Panel): - name = _("WinDC") + name = _("Windows Services") slug = 'windc' diff --git a/dashboard/windc/tables.py b/dashboard/windc/tables.py index 753026a87..3875f06fc 100644 --- a/dashboard/windc/tables.py +++ b/dashboard/windc/tables.py @@ -33,7 +33,6 @@ from horizon.utils.filters import replace_underscores from openstack_dashboard import api from openstack_dashboard.dashboards.project.access_and_security \ .floating_ips.workflows import IPAssociationWorkflow -from .tabs import InstanceDetailTabs, LogTab, ConsoleTab LOG = logging.getLogger(__name__) @@ -61,12 +60,12 @@ def is_deleting(instance): return task_state.lower() == "deleting" -class RebootWinDC(tables.BatchAction): +class RebootService(tables.BatchAction): name = "reboot" action_present = _("Reboot") action_past = _("Rebooted") - data_type_singular = _("Instance") - data_type_plural = _("Instances") + data_type_singular = _("Service") + data_type_plural = _("Services") classes = ('btn-danger', 'btn-reboot') def allowed(self, request, instance=None): @@ -78,9 +77,9 @@ class RebootWinDC(tables.BatchAction): api.nova.server_reboot(request, obj_id) -class CreateWinDC(tables.LinkAction): - name = "CreateWinDC" - verbose_name = _("Create WinDC") +class CreateService(tables.LinkAction): + name = "CreateService" + verbose_name = _("Create Windows Service") url = "horizon:project:windc:create" classes = ("btn-launch", "ajax-modal") @@ -101,7 +100,7 @@ class CreateWinDC(tables.LinkAction): self.verbose_name = string_concat(self.verbose_name, ' ', _("(Quota exceeded)")) else: - self.verbose_name = _("Create WinDC") + self.verbose_name = _("Create Windows Service") classes = [c for c in self.classes if c != "disabled"] self.classes = classes except: @@ -112,12 +111,12 @@ class CreateWinDC(tables.LinkAction): return True # The action should always be displayed -class DeleteWinDC(tables.BatchAction): - name = "DeleteWinDC" - action_present = _("DeleteWinDC") +class DeleteService(tables.BatchAction): + name = "DeleteService" + action_present = _("DeleteService") action_past = _("Scheduled termination of") - data_type_singular = _("Instance") - data_type_plural = _("Instances") + data_type_singular = _("Service") + data_type_plural = _("Services") classes = ('btn-danger', 'btn-terminate') def allowed(self, request, instance=None): @@ -132,46 +131,15 @@ class DeleteWinDC(tables.BatchAction): api.nova.server_delete(request, obj_id) -class EditWinDC(tables.LinkAction): +class EditService(tables.LinkAction): name = "edit" - verbose_name = _("Edit Instance") - url = "horizon:project:instances:update" + verbose_name = _("Edit Service") + url = "horizon:project:windc:update" classes = ("ajax-modal", "btn-edit") def allowed(self, request, instance): return not is_deleting(instance) - -class ConsoleLink(tables.LinkAction): - name = "console" - verbose_name = _("Console") - url = "horizon:project:instances:detail" - classes = ("btn-console",) - - def allowed(self, request, instance=None): - return instance.status in ACTIVE_STATES and not is_deleting(instance) - - def get_link_url(self, datum): - base_url = super(ConsoleLink, self).get_link_url(datum) - tab_query_string = ConsoleTab(InstanceDetailTabs).get_query_string() - return "?".join([base_url, tab_query_string]) - - -class LogLink(tables.LinkAction): - name = "log" - verbose_name = _("View Log") - url = "horizon:project:instances:detail" - classes = ("btn-log",) - - def allowed(self, request, instance=None): - return instance.status in ACTIVE_STATES and not is_deleting(instance) - - def get_link_url(self, datum): - base_url = super(LogLink, self).get_link_url(datum) - tab_query_string = LogTab(InstanceDetailTabs).get_query_string() - return "?".join([base_url, tab_query_string]) - - class UpdateRow(tables.Row): ajax = True @@ -183,7 +151,7 @@ class UpdateRow(tables.Row): def get_ips(instance): - template_name = 'project/instances/_instance_ips.html' + template_name = 'project/windc/_instance_ips.html' context = {"instance": instance} return template.loader.render_to_string(template_name, context) @@ -223,7 +191,7 @@ TASK_DISPLAY_CHOICES = ( ) -class WinDCTable(tables.DataTable): +class WinServicesTable(tables.DataTable): TASK_STATUS_CHOICES = ( (None, True), ("none", True) @@ -234,8 +202,8 @@ class WinDCTable(tables.DataTable): ("error", False), ) name = tables.Column("name", - link=("horizon:project:instances:detail"), - verbose_name=_("WinDC Instance Name")) + link=("horizon:project:windc:detail"), + verbose_name=_("Name")) ip = tables.Column(get_ips, verbose_name=_("IP Address")) size = tables.Column(get_size, verbose_name=_("Type"), @@ -252,14 +220,11 @@ class WinDCTable(tables.DataTable): status=True, status_choices=TASK_STATUS_CHOICES, display_choices=TASK_DISPLAY_CHOICES) - state = tables.Column(get_power_state, - filters=(title, replace_underscores), - verbose_name=_("Power State")) class Meta: name = "windc" - verbose_name = _("WinDC") + verbose_name = _("Windows Services") status_columns = ["status", "task"] row_class = UpdateRow - table_actions = (CreateWinDC, DeleteWinDC) - row_actions = (EditWinDC, ConsoleLink, LogLink, RebootWinDC) + table_actions = (CreateService, DeleteService) + row_actions = (EditService, RebootService) diff --git a/dashboard/windc/tabs.py b/dashboard/windc/tabs.py deleted file mode 100644 index 029c877f0..000000000 --- a/dashboard/windc/tabs.py +++ /dev/null @@ -1,85 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 Nebula, 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 tabs - -from openstack_dashboard import api - - -class OverviewTab(tabs.Tab): - name = _("Overview") - slug = "overview" - template_name = ("project/instances/" - "_detail_overview.html") - - def get_context_data(self, request): - return {"instance": self.tab_group.kwargs['instance']} - - -class LogTab(tabs.Tab): - name = _("Log") - slug = "log" - template_name = "project/instances/_detail_log.html" - preload = False - - def get_context_data(self, request): - instance = self.tab_group.kwargs['instance'] - try: - data = api.nova.server_console_output(request, - instance.id, - tail_length=35) - except: - data = _('Unable to get log for instance "%s".') % instance.id - exceptions.handle(request, ignore=True) - return {"instance": instance, - "console_log": data} - - -class ConsoleTab(tabs.Tab): - name = _("Console") - slug = "console" - template_name = "project/instances/_detail_console.html" - preload = False - - def get_context_data(self, request): - instance = self.tab_group.kwargs['instance'] - # Currently prefer VNC over SPICE, since noVNC has had much more - # testing than spice-html5 - try: - console = api.nova.server_vnc_console(request, instance.id) - console_url = "%s&title=%s(%s)" % ( - console.url, - getattr(instance, "name", ""), - instance.id) - except: - try: - console = api.nova.server_spice_console(request, instance.id) - console_url = "%s&title=%s(%s)" % ( - console.url, - getattr(instance, "name", ""), - instance.id) - except: - console_url = None - return {'console_url': console_url, 'instance_id': instance.id} - - -class InstanceDetailTabs(tabs.TabGroup): - slug = "instance_details" - tabs = (OverviewTab, LogTab, ConsoleTab) - sticky = True diff --git a/dashboard/windc/templates/windc/create.html b/dashboard/windc/templates/windc/create.html index 09c996ac3..0508b68ea 100644 --- a/dashboard/windc/templates/windc/create.html +++ b/dashboard/windc/templates/windc/create.html @@ -1,9 +1,9 @@ {% extends 'base.html' %} {% load i18n %} -{% block title %}{% trans "Create Windows Instance" %}{% endblock %} +{% block title %}{% trans "Create Windows Service" %}{% endblock %} {% block page_header %} - {% include "horizon/common/_page_header.html" with title=_("Create Windows Instance") %} + {% include "horizon/common/_page_header.html" with title=_("Create Windows Service") %} {% endblock page_header %} {% block main %} diff --git a/dashboard/windc/urls.py b/dashboard/windc/urls.py index 19bd6c0b8..8f52b6fb6 100644 --- a/dashboard/windc/urls.py +++ b/dashboard/windc/urls.py @@ -20,12 +20,12 @@ from django.conf.urls.defaults import patterns, url -from .views import IndexView, CreateWinDCView +from .views import IndexView, CreateWinServiceView VIEW_MOD = 'openstack_dashboard.dashboards.project.windc.views' urlpatterns = patterns(VIEW_MOD, url(r'^$', IndexView.as_view(), name='index'), - url(r'^create$', CreateWinDCView.as_view(), name='create') + url(r'^create$', CreateWinServiceView.as_view(), name='create') ) diff --git a/dashboard/windc/views.py b/dashboard/windc/views.py index a61fb2b31..c5854e034 100644 --- a/dashboard/windc/views.py +++ b/dashboard/windc/views.py @@ -36,15 +36,15 @@ from horizon import tables from horizon import workflows from openstack_dashboard import api -from .tables import WinDCTable -from .workflows import CreateWinDC +from .tables import WinServicesTable +from .workflows import CreateWinService LOG = logging.getLogger(__name__) class IndexView(tables.DataTableView): - table_class = WinDCTable + table_class = WinServicesTable template_name = 'project/windc/index.html' def get_data(self): @@ -82,12 +82,12 @@ class IndexView(tables.DataTableView): return instances -class CreateWinDCView(workflows.WorkflowView): - workflow_class = CreateWinDC +class CreateWinServiceView(workflows.WorkflowView): + workflow_class = CreateWinService template_name = "project/windc/create.html" def get_initial(self): - initial = super(CreateWinDCView, self).get_initial() + initial = super(CreateWinServiceView, self).get_initial() initial['project_id'] = self.request.user.tenant_id initial['user_id'] = self.request.user.id return initial diff --git a/dashboard/windc/workflows.py b/dashboard/windc/workflows.py index ce25b4440..292a6434b 100644 --- a/dashboard/windc/workflows.py +++ b/dashboard/windc/workflows.py @@ -64,451 +64,72 @@ class SelectProjectUser(workflows.Step): contributes = ("project_id", "user_id") -class VolumeOptionsAction(workflows.Action): - VOLUME_CHOICES = ( - ('', _("Don't boot from a volume.")), - ("volume_id", _("Boot from volume.")), - ("volume_snapshot_id", _("Boot from volume snapshot " - "(creates a new volume).")), - ) - # Boot from volume options - volume_type = forms.ChoiceField(label=_("Volume Options"), - choices=VOLUME_CHOICES, - required=False) - volume_id = forms.ChoiceField(label=_("Volume"), required=False) - volume_snapshot_id = forms.ChoiceField(label=_("Volume Snapshot"), - required=False) - device_name = forms.CharField(label=_("Device Name"), - required=False, - initial="vda", - help_text=_("Volume mount point (e.g. 'vda' " - "mounts at '/dev/vda').")) - delete_on_terminate = forms.BooleanField(label=_("Delete on Terminate"), - initial=False, - required=False, - help_text=_("Delete volume on " - "instance terminate")) +class ConfigureWinDCAction(workflows.Action): + dc_name = forms.CharField(label=_("Domain Name"), + required=False, + help_text=_("A name of new domain.")) + + dc_count = forms.IntegerField(label=_("Domain Controllers Count"), + required=True, + min_value=1, + max_value=100, + initial=1, + help_text=_("Domain Controllers count.")) class Meta: - name = _("Volume Options") - permissions = ('openstack.services.volume',) - help_text_template = ("project/instances/" - "_launch_volumes_help.html") - - def clean(self): - cleaned_data = super(VolumeOptionsAction, self).clean() - volume_opt = cleaned_data.get('volume_type', None) - - if volume_opt and not cleaned_data[volume_opt]: - raise forms.ValidationError(_('Please choose a volume, or select ' - '%s.') % self.VOLUME_CHOICES[0][1]) - return cleaned_data - - def _get_volume_display_name(self, volume): - if hasattr(volume, "volume_id"): - vol_type = "snap" - visible_label = _("Snapshot") - else: - vol_type = "vol" - visible_label = _("Volume") - return (("%s:%s" % (volume.id, vol_type)), - ("%s - %s GB (%s)" % (volume.display_name, - volume.size, - visible_label))) - - def populate_volume_id_choices(self, request, context): - volume_options = [("", _("Select Volume"))] - try: - volumes = [v for v in cinder.volume_list(self.request) - if v.status == api.cinder.VOLUME_STATE_AVAILABLE] - volume_options.extend([self._get_volume_display_name(vol) - for vol in volumes]) - except: - exceptions.handle(self.request, - _('Unable to retrieve list of volumes.')) - return volume_options - - def populate_volume_snapshot_id_choices(self, request, context): - volume_options = [("", _("Select Volume Snapshot"))] - try: - snapshots = cinder.volume_snapshot_list(self.request) - snapshots = [s for s in snapshots - if s.status == api.cinder.VOLUME_STATE_AVAILABLE] - volume_options.extend([self._get_volume_display_name(snap) - for snap in snapshots]) - except: - exceptions.handle(self.request, - _('Unable to retrieve list of volume ' - 'snapshots.')) - - return volume_options + name = _("Domain Controllers") + help_text_template = ("project/windc/_dc_help.html") -class VolumeOptions(workflows.Step): - action_class = VolumeOptionsAction - depends_on = ("project_id", "user_id") - contributes = ("volume_type", - "volume_id", - "device_name", # Can be None for an image. - "delete_on_terminate") - - def contribute(self, data, context): - context = super(VolumeOptions, self).contribute(data, context) - # Translate form input to context for volume values. - if "volume_type" in data and data["volume_type"]: - context['volume_id'] = data.get(data['volume_type'], None) - - if not context.get("volume_type", ""): - context['volume_type'] = self.action.VOLUME_CHOICES[0][0] - context['volume_id'] = None - context['device_name'] = None - context['delete_on_terminate'] = None - return context +class ConfigureWinDC(workflows.Step): + action_class = ConfigureWinDCAction + #contributes = ("windows_domain_controller",) -class SetInstanceDetailsAction(workflows.Action): - SOURCE_TYPE_CHOICES = ( - ("image_id", _("Image")), - ("instance_snapshot_id", _("Snapshot")), - ) - source_type = forms.ChoiceField(label=_("Instance Source"), - choices=SOURCE_TYPE_CHOICES) - image_id = forms.ChoiceField(label=_("Image"), required=False) - instance_snapshot_id = forms.ChoiceField(label=_("Instance Snapshot"), - required=False) - name = forms.CharField(max_length=80, label=_("Instance Name")) - flavor = forms.ChoiceField(label=_("Flavor"), - help_text=_("Size of image to launch.")) - count = forms.IntegerField(label=_("Instance Count"), - min_value=1, - initial=1, - help_text=_("Number of instances to launch.")) +class ConfigureWinIISAction(workflows.Action): + iis_name = forms.CharField(label=_("IIS Server Name"), + required=False, + help_text=_("A name of IIS Server.")) + + iis_count = forms.IntegerField(label=_("IIS Servers Count"), + required=True, + min_value=1, + max_value=100, + initial=1, + help_text=_("IIS Servers count.")) + + iis_domain = forms.CharField(label=_("Member of the Domain"), + required=False, + help_text=_("A name of domain for" + " IIS Server.")) class Meta: - name = _("Details") - help_text_template = ("project/instances/" - "_launch_details_help.html") - - def clean(self): - cleaned_data = super(SetInstanceDetailsAction, self).clean() - - # Validate our instance source. - source = cleaned_data['source_type'] - # There should always be at least one image_id choice, telling the user - # that there are "No Images Available" so we check for 2 here... - if source == 'image_id' and not \ - filter(lambda x: x[0] != '', self.fields['image_id'].choices): - raise forms.ValidationError(_("There are no image sources " - "available; you must first create " - "an image before attempting to " - "launch an instance.")) - if not cleaned_data[source]: - raise forms.ValidationError(_("Please select an option for the " - "instance source.")) - - # Prevent launching multiple instances with the same volume. - # TODO(gabriel): is it safe to launch multiple instances with - # a snapshot since it should be cloned to new volumes? - count = cleaned_data.get('count', 1) - volume_type = self.data.get('volume_type', None) - if volume_type and count > 1: - msg = _('Launching multiple instances is only supported for ' - 'images and instance snapshots.') - raise forms.ValidationError(msg) - - return cleaned_data - - def _get_available_images(self, request, context): - project_id = context.get('project_id', None) - if not hasattr(self, "_public_images"): - public = {"is_public": True, - "status": "active"} - try: - public_images, _more = glance.image_list_detailed( - request, filters=public) - except: - public_images = [] - exceptions.handle(request, - _("Unable to retrieve public images.")) - self._public_images = public_images - - # Preempt if we don't have a project_id yet. - if project_id is None: - setattr(self, "_images_for_%s" % project_id, []) - - if not hasattr(self, "_images_for_%s" % project_id): - owner = {"property-owner_id": project_id, - "status": "active"} - try: - owned_images, _more = glance.image_list_detailed( - request, filters=owner) - except: - exceptions.handle(request, - _("Unable to retrieve images for " - "the current project.")) - setattr(self, "_images_for_%s" % project_id, owned_images) - - owned_images = getattr(self, "_images_for_%s" % project_id) - images = owned_images + self._public_images - - # Remove duplicate images - image_ids = [] - final_images = [] - for image in images: - if image.id not in image_ids: - image_ids.append(image.id) - final_images.append(image) - return [image for image in final_images - if image.container_format not in ('aki', 'ari')] - - def populate_image_id_choices(self, request, context): - images = self._get_available_images(request, context) - choices = [(image.id, image.name) - for image in images - if image.properties.get("image_type", '') != "snapshot"] - if choices: - choices.insert(0, ("", _("Select Image"))) - else: - choices.insert(0, ("", _("No images available."))) - return choices - - def populate_instance_snapshot_id_choices(self, request, context): - images = self._get_available_images(request, context) - choices = [(image.id, image.name) - for image in images - if image.properties.get("image_type", '') == "snapshot"] - if choices: - choices.insert(0, ("", _("Select Instance Snapshot"))) - else: - choices.insert(0, ("", _("No snapshots available."))) - return choices - - def populate_flavor_choices(self, request, context): - try: - flavors = api.nova.flavor_list(request) - flavor_list = [(flavor.id, "%s" % flavor.name) - for flavor in flavors] - except: - flavor_list = [] - exceptions.handle(request, - _('Unable to retrieve instance flavors.')) - return sorted(flavor_list) - - def get_help_text(self): - extra = {} - try: - extra['usages'] = quotas.tenant_quota_usages(self.request) - extra['usages_json'] = json.dumps(extra['usages']) - flavors = json.dumps([f._info for f in - api.nova.flavor_list(self.request)]) - extra['flavors'] = flavors - except: - exceptions.handle(self.request, - _("Unable to retrieve quota information.")) - return super(SetInstanceDetailsAction, self).get_help_text(extra) + name = _("Internet Information Services") + help_text_template = ("project/windc/_iis_help.html") -class SetInstanceDetails(workflows.Step): - action_class = SetInstanceDetailsAction - contributes = ("source_type", "source_id", "name", "count", "flavor") +class ConfigureWinIIS(workflows.Step): + action_class = ConfigureWinIISAction + #contributes = ("windows_iis",) - def prepare_action_context(self, request, context): - if 'source_type' in context and 'source_id' in context: - context[context['source_type']] = context['source_id'] - return context - - def contribute(self, data, context): - context = super(SetInstanceDetails, self).contribute(data, context) - # Allow setting the source dynamically. - if ("source_type" in context and "source_id" in context - and context["source_type"] not in context): - context[context["source_type"]] = context["source_id"] - - # Translate form input to context for source values. - if "source_type" in data: - context["source_id"] = data.get(data['source_type'], None) - - return context - - -KEYPAIR_IMPORT_URL = "horizon:project:access_and_security:keypairs:import" - - -class SetAccessControlsAction(workflows.Action): - keypair = forms.DynamicChoiceField(label=_("Keypair"), - required=False, - help_text=_("Which keypair to use for " - "authentication."), - add_item_link=KEYPAIR_IMPORT_URL) - groups = forms.MultipleChoiceField(label=_("Security Groups"), - required=True, - initial=["default"], - widget=forms.CheckboxSelectMultiple(), - help_text=_("Launch instance in these " - "security groups.")) - - class Meta: - name = _("Access & Security") - help_text = _("Control access to your instance via keypairs, " - "security groups, and other mechanisms.") - - def populate_keypair_choices(self, request, context): - try: - keypairs = api.nova.keypair_list(request) - keypair_list = [(kp.name, kp.name) for kp in keypairs] - except: - keypair_list = [] - exceptions.handle(request, - _('Unable to retrieve keypairs.')) - if keypair_list: - keypair_list.insert(0, ("", _("Select a keypair"))) - else: - keypair_list = (("", _("No keypairs available.")),) - return keypair_list - - def populate_groups_choices(self, request, context): - try: - groups = api.nova.security_group_list(request) - security_group_list = [(sg.name, sg.name) for sg in groups] - except: - exceptions.handle(request, - _('Unable to retrieve list of security groups')) - security_group_list = [] - return security_group_list - - -class SetAccessControls(workflows.Step): - action_class = SetAccessControlsAction - depends_on = ("project_id", "user_id") - contributes = ("keypair_id", "security_group_ids") - - def contribute(self, data, context): - if data: - post = self.workflow.request.POST - context['security_group_ids'] = post.getlist("groups") - context['keypair_id'] = data.get("keypair", "") - return context - - -class CustomizeAction(workflows.Action): - customization_script = forms.CharField(widget=forms.Textarea, - label=_("Customization Script"), - required=False, - help_text=_("A script or set of " - "commands to be " - "executed after the " - "instance has been " - "built (max 16kb).")) - - class Meta: - name = _("Post-Creation") - help_text_template = ("project/instances/" - "_launch_customize_help.html") - - -class PostCreationStep(workflows.Step): - action_class = CustomizeAction - contributes = ("customization_script",) - - -class SetNetworkAction(workflows.Action): - network = forms.MultipleChoiceField(label=_("Networks"), - required=True, - widget=forms.CheckboxSelectMultiple(), - help_text=_("Launch instance with" - "these networks")) - - class Meta: - name = _("Networking") - permissions = ('openstack.services.network',) - help_text = _("Select networks for your instance.") - - def populate_network_choices(self, request, context): - try: - tenant_id = self.request.user.tenant_id - networks = api.quantum.network_list_for_tenant(request, tenant_id) - for n in networks: - n.set_id_as_name_if_empty() - network_list = [(network.id, network.name) for network in networks] - except: - network_list = [] - exceptions.handle(request, - _('Unable to retrieve networks.')) - return network_list - - -class SetNetwork(workflows.Step): - action_class = SetNetworkAction - contributes = ("network_id",) - - def contribute(self, data, context): - if data: - networks = self.workflow.request.POST.getlist("network") - # If no networks are explicitly specified, network list - # contains an empty string, so remove it. - networks = [n for n in networks if n != ''] - if networks: - context['network_id'] = networks - return context - - -class CreateWinDC(workflows.Workflow): - slug = "create_windc" +class CreateWinService(workflows.Workflow): + slug = "create" name = _("Create Windows Service") finalize_button_name = _("Deploy") success_message = _('Deployed %(count)s named "%(name)s".') failure_message = _('Unable to deploy %(count)s named "%(name)s".') success_url = "horizon:project:windc:index" default_steps = (SelectProjectUser, - SetInstanceDetails, - SetAccessControls, - SetNetwork, - VolumeOptions, - PostCreationStep) + ConfigureWinDC, + ConfigureWinIIS) - def format_status_message(self, message): - name = self.context.get('name', 'unknown instance') - count = self.context.get('count', 1) - if int(count) > 1: - return message % {"count": _("%s instances") % count, - "name": name} - else: - return message % {"count": _("instance"), "name": name} + ## TO DO: + ## Need to rewrite the following code: - def handle(self, request, context): - custom_script = context.get('customization_script', '') - - # Determine volume mapping options - if context.get('volume_type', None): - if(context['delete_on_terminate']): - del_on_terminate = 1 - else: - del_on_terminate = 0 - mapping_opts = ("%s::%s" - % (context['volume_id'], del_on_terminate)) - dev_mapping = {context['device_name']: mapping_opts} - else: - dev_mapping = None - - netids = context.get('network_id', None) - if netids: - nics = [{"net-id": netid, "v4-fixed-ip": ""} - for netid in netids] - else: - nics = None - - try: - api.nova.server_create(request, - context['name'], - context['source_id'], - context['flavor'], - context['keypair_id'], - normalize_newlines(custom_script), - context['security_group_ids'], - dev_mapping, - nics=nics, - instance_count=int(context['count'])) - return True - except: - exceptions.handle(request) - return False + #def handle(self, request, context): + # try: + # api.windc.create(request,...) + # return True + # except: + # exceptions.handle(request) + # return False