diff --git a/dashboard/api/windc.py b/dashboard/api/windc.py index 2f13696..26033eb 100644 --- a/dashboard/api/windc.py +++ b/dashboard/api/windc.py @@ -24,7 +24,6 @@ import urlparse from django.utils.decorators import available_attrs from portasclient.v1.client import Client as windc_client - LOG = logging.getLogger(__name__) @@ -91,9 +90,6 @@ def services_create(request, datacenter, parameters): def services_list(request, datacenter_id): - session_id = request.user.token.token['id'] - services = [] - session_id = None sessions = windcclient(request).sessions.list(datacenter_id) for s in sessions: @@ -114,5 +110,25 @@ def services_get(request, datacenter, service_id): return windcclient(request).services.get(datacenter, service_id) -def services_delete(request, datacenter, service_id): - return windcclient(request).services.delete(datacenter, service_id) +def services_delete(request, datacenter_id, service_id): + services = services_list(request, datacenter_id) + + session_id = None + sessions = windcclient(request).sessions.list(datacenter_id) + for session in sessions: + if session.state == 'open': + session_id = session.id + + if session_id is None: + raise Exception("Sorry, you can not delete this service now.") + + for service in services: + if service.id is service_id: + if service.type is 'Active Directory': + windcclient(request).activeDirectories.delete(datacenter_id, + session_id, + service_id) + elif service.type is 'IIS': + windcclient(request).webServers.delete(datacenter_id, + session_id, + service_id) diff --git a/dashboard/windc/forms.py b/dashboard/windc/forms.py index f4a2f7a..b44cd16 100644 --- a/dashboard/windc/forms.py +++ b/dashboard/windc/forms.py @@ -19,6 +19,7 @@ # under the License. import logging +import string from django import forms from django.core.urlresolvers import reverse @@ -30,13 +31,54 @@ from horizon import forms from horizon import exceptions from horizon import messages -import pdb - LOG = logging.getLogger(__name__) +class PasswordField(forms.CharField): + + # Setup the Field + def __init__(self, label, *args, **kwargs): + super(PasswordField, self).__init__(min_length=7, required=True, + label=label, + widget=forms.PasswordInput(render_value=False), + *args, **kwargs) + + def clean(self, value): + + # Setup Our Lists of Characters and Numbers + characters = list(string.letters) + special_characters = '!@#$%^&*()_+|\/.,~?><:{}' + numbers = [str(i) for i in range(10)] + + # Assume False until Proven Otherwise + numCheck = False + charCheck = False + specCharCheck = False + + # Loop until we Match + for char in value: + if not charCheck: + if char in characters: + charCheck = True + if not specCharCheck: + if char in special_characters: + specCharCheck = True + if not numCheck: + if char in numbers: + numCheck = True + if numCheck and charCheck and specCharCheck: + break + + if not numCheck or not charCheck or not specCharCheck: + raise forms.ValidationError(u'Your password must include at least \ + one letter, at least one number and \ + at least one special character.') + + return super(PasswordField, self).clean(value) + + class WizardFormServiceType(forms.Form): - service = forms.ChoiceField(label=_("Service Type"), + service = forms.ChoiceField(label=_('Service Type'), choices=[ ('Active Directory', 'Active Directory'), ('IIS', 'Internet Information Services') @@ -44,62 +86,35 @@ class WizardFormServiceType(forms.Form): class WizardFormConfiguration(forms.Form): - "The functions for this class will dynamically create in views.py" + 'The functions for this class will dynamically create in views.py' pass class WizardFormADConfiguration(forms.Form): - dc_name = forms.CharField(label=_("Domain Name"), - required=False) + dc_name = forms.CharField(label=_('Domain Name'), + required=True) - dc_count = forms.IntegerField(label=_("Instances Count"), + dc_count = forms.IntegerField(label=_('Instances Count'), required=True, min_value=1, max_value=100, initial=1) - adm_password = forms.CharField(widget=forms.PasswordInput, - label=_("Administrator password"), - required=False) + adm_password = PasswordField(_('Administrator password')) - recovery_password = forms.CharField(widget=forms.PasswordInput, - label=_("Recovery password"), - required=False) + recovery_password = PasswordField(_('Recovery password')) class WizardFormIISConfiguration(forms.Form): - iis_name = forms.CharField(label=_("IIS Server Name"), - required=False) + iis_name = forms.CharField(label=_('IIS Server Name'), + required=True) - adm_password = forms.CharField(widget=forms.PasswordInput, - label=_("Administrator password"), - required=False) + adm_password = PasswordField(_('Administrator password')) - iis_domain = forms.CharField(label=_("Member of the Domain"), - required=False) + iis_domain = forms.CharField(label=_('Member of the Domain'), + required=True) - domain_user_name = forms.CharField(label=_("Domain User Name"), - required=False) + domain_user_name = forms.CharField(label=_('Domain User Name'), + required=True) - domain_user_password = forms.CharField(widget=forms.PasswordInput, - label=_("Domain User Password"), - required=False) - - -class UpdateWinDC(forms.SelfHandlingForm): - tenant_id = forms.CharField(widget=forms.HiddenInput) - data_center = forms.CharField(widget=forms.HiddenInput) - name = forms.CharField(required=True) - - def handle(self, request, data): - try: - server = api.nova.server_update(request, data['data_center'], - data['name']) - messages.success(request, - _('Data Center "%s" updated.') % data['name']) - return server - except: - redirect = reverse("horizon:project:windc:index") - exceptions.handle(request, - _('Unable to update data center.'), - redirect=redirect) + domain_user_password = PasswordField(_('Domain User Password')) diff --git a/dashboard/windc/tables.py b/dashboard/windc/tables.py index f61714c..c6f998d 100644 --- a/dashboard/windc/tables.py +++ b/dashboard/windc/tables.py @@ -43,24 +43,23 @@ LOG = logging.getLogger(__name__) class CreateService(tables.LinkAction): - name = "CreateService" - verbose_name = _("Create Service") - url = "horizon:project:windc:create" - classes = ("btn-launch", "ajax-modal") + name = 'CreateService' + verbose_name = _('Create Service') + url = 'horizon:project:windc:create' + classes = ('btn-launch', 'ajax-modal') def allowed(self, request, datum): return True def action(self, request, service): - # FIX ME api.windc.services_create(request, service) class CreateDataCenter(tables.LinkAction): - name = "CreateDataCenter" - verbose_name = _("Create Windows Data Center") - url = "horizon:project:windc:create_dc" - classes = ("btn-launch", "ajax-modal") + name = 'CreateDataCenter' + verbose_name = _('Create Windows Data Center') + url = 'horizon:project:windc:create_dc' + classes = ('btn-launch', 'ajax-modal') def allowed(self, request, datum): return True @@ -70,11 +69,11 @@ class CreateDataCenter(tables.LinkAction): class DeleteDataCenter(tables.BatchAction): - name = "delete" - action_present = _("Delete") - action_past = _("Delete") - data_type_singular = _("Data Center") - data_type_plural = _("Data Center") + name = 'delete' + action_present = _('Delete') + action_past = _('Delete') + data_type_singular = _('Data Center') + data_type_plural = _('Data Center') classes = ('btn-danger', 'btn-terminate') def allowed(self, request, datum): @@ -85,62 +84,52 @@ class DeleteDataCenter(tables.BatchAction): class DeleteService(tables.BatchAction): - name = "delete" - action_present = _("Delete") - action_past = _("Delete") - data_type_singular = _("Service") - data_type_plural = _("Service") + name = 'delete' + action_present = _('Delete') + action_past = _('Delete') + data_type_singular = _('Service') + data_type_plural = _('Service') classes = ('btn-danger', 'btn-terminate') def allowed(self, request, datum): return True def action(self, request, service_id): - ############## FIX ME: link = request.__dict__['META']['HTTP_REFERER'] datacenter_id = re.search('windc/(\S+)', link).group(0)[6:-1] - ############## - api.windc.services_delete(request, datacenter_id, service_id) + try: + api.windc.services_delete(request, datacenter_id, service_id) + except: + messages.error(request, + _('Sorry, you can not delete this service right now.')) class DeployDataCenter(tables.BatchAction): - name = "deploy" - action_present = _("Deploy") - action_past = _("Deploy") - data_type_singular = _("Data Center") - data_type_plural = _("Data Center") - classes = ("btn-launch") + name = 'deploy' + action_present = _('Deploy') + action_past = _('Deploy') + data_type_singular = _('Data Center') + data_type_plural = _('Data Center') + classes = ('btn-launch') def allowed(self, request, datum): return True def action(self, request, datacenter_id): - #link = request.__dict__['META']['HTTP_REFERER'] - #datacenter_id = re.search('windc/(\S+)', link).group(0)[6:-1] return api.windc.datacenters_deploy(request, datacenter_id) -class EditService(tables.LinkAction): - name = "edit" - verbose_name = _("Edit") - url = "horizon:project:windc:update" - classes = ("ajax-modal", "btn-edit") - - def allowed(self, request, instance): - return True - - class ShowDataCenterServices(tables.LinkAction): - name = "edit" - verbose_name = _("Services") - url = "horizon:project:windc:services" + name = 'edit' + verbose_name = _('Services') + url = 'horizon:project:windc:services' def allowed(self, request, instance): return True -class UpdateRow(tables.Row): +class UpdateDCRow(tables.Row): ajax = True def get_data(self, request, datacenter_id): @@ -164,16 +153,16 @@ class WinDCTable(tables.DataTable): STATUS_CHOICES = ( (None, True), - ("Ready to deploy", False), - ("deploying", True), - ("deployed", True), - ("ready", True), - ("error", False), + ('Ready to deploy', False), + ('deploying', True), + ('deployed', True), + ('ready', True), + ('error', False), ) - name = tables.Column("name", - link=("horizon:project:windc:services"), - verbose_name=_("Name")) + name = tables.Column('name', + link=('horizon:project:windc:services'), + verbose_name=_('Name')) status = tables.Column(get_datacenter_status, verbose_name=_('Status'), status=True, @@ -181,9 +170,9 @@ class WinDCTable(tables.DataTable): display_choices=STATUS_DISPLAY_CHOICES) class Meta: - name = "windc" - verbose_name = _("Windows Data Centers") - row_class = UpdateRow + name = 'windc' + verbose_name = _('Windows Data Centers') + row_class = UpdateDCRow table_actions = (CreateDataCenter,) status_columns = ['status'] row_actions = (ShowDataCenterServices, DeleteDataCenter, @@ -193,12 +182,11 @@ class WinDCTable(tables.DataTable): class WinServicesTable(tables.DataTable): name = tables.Column('name', verbose_name=_('Name'), - link=("horizon:project:windc:service_details"),) + link=('horizon:project:windc:service_details'),) _type = tables.Column('service_type', verbose_name=_('Type')) class Meta: - name = "services" - verbose_name = _("Services") - row_class = UpdateRow + name = 'services' + verbose_name = _('Services') table_actions = (CreateService,) - row_actions = (EditService, DeleteService) + row_actions = (DeleteService,) diff --git a/dashboard/windc/templates/windc/_services_tabs.html b/dashboard/windc/templates/windc/_services_tabs.html index 86542bb..a58eac8 100644 --- a/dashboard/windc/templates/windc/_services_tabs.html +++ b/dashboard/windc/templates/windc/_services_tabs.html @@ -50,9 +50,9 @@ {% block modal-footer %} {% if wizard.steps.prev %} - - + + {% else %} - + {% endif %} {% endblock %} diff --git a/dashboard/windc/views.py b/dashboard/windc/views.py index bf9ed7c..4ab32ab 100644 --- a/dashboard/windc/views.py +++ b/dashboard/windc/views.py @@ -109,7 +109,6 @@ class Wizard(ModalFormMixin, SessionWizardView, generic.FormView): def get_form(self, step=None, data=None, files=None): form = super(Wizard, self).get_form(step, data, files) - LOG.debug("********" + str(self.form_list)) if data: service_type = data.get('0-service', '') self.service_type = service_type @@ -139,7 +138,6 @@ class IndexView(tables.DataTableView): try: data_centers = api.windc.datacenters_list(self.request) for dc in data_centers: - # get the information about session status for each dc dc.status = api.windc.datacenters_get_status(self.request, dc.id) except: @@ -156,7 +154,7 @@ class WinServices(tables.DataTableView): def get_context_data(self, **kwargs): context = super(WinServices, self).get_context_data(**kwargs) data = self.get_data() - context["dc_name"] = self.dc_name + context['dc_name'] = self.dc_name return context def get_data(self): @@ -175,7 +173,7 @@ class WinServices(tables.DataTableView): class CreateWinDCView(workflows.WorkflowView): workflow_class = CreateWinDC - template_name = "project/windc/create_dc.html" + template_name = 'project/windc/create_dc.html' def get_initial(self): initial = super(CreateWinDCView, self).get_initial()