Fixed licenses for tabula and tests. Fixed name of tabula project.

This commit is contained in:
Timur Nurlygayanov 2013-04-05 15:32:00 +04:00
parent fd39e49cba
commit bd7a24e3c1
23 changed files with 179 additions and 993 deletions

View File

@ -0,0 +1,14 @@
# 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,14 @@
# 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

@ -1,3 +1,18 @@
# 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 unittest import unittest
from conductor.app import ConductorWorkflowService from conductor.app import ConductorWorkflowService
import conductor.rabbitmq as rabbitmq import conductor.rabbitmq as rabbitmq
@ -10,4 +25,4 @@ class TestMethodsAndClasses(unittest.TestCase):
con = ConductorWorkflowService() con = ConductorWorkflowService()
con.start() con.start()
con.stop() con.stop()

View File

@ -1,3 +1,18 @@
# 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 unittest import unittest
from conductor.app import ConductorWorkflowService from conductor.app import ConductorWorkflowService
from conductor.openstack.common import service from conductor.openstack.common import service
@ -8,4 +23,4 @@ class TestMethodsAndClasses(unittest.TestCase):
launcher = service.ServiceLauncher() launcher = service.ServiceLauncher()
con = ConductorWorkflowService() con = ConductorWorkflowService()
launcher.launch_service(con) launcher.launch_service(con)

View File

@ -0,0 +1,14 @@
# 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

@ -1 +1,15 @@
__author__ = 'sad' # 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.
__author__ = 'Mirantis'

View File

@ -1,3 +1,18 @@
# 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 unittest import unittest
import portas.api.v1 as api import portas.api.v1 as api

View File

@ -1,3 +1,18 @@
# 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 unittest2 import unittest2
from mock import MagicMock from mock import MagicMock

View File

@ -0,0 +1,14 @@
# 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,14 @@
# 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

@ -1,3 +1,18 @@
# 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 unittest import unittest
import logging import logging
from httpretty import HTTPretty, httprettified from httpretty import HTTPretty, httprettified
@ -191,4 +206,4 @@ class UnitTestsForClassesAndFunctions(unittest.TestCase):
test_client = Client('1', endpoint=endpoint, token='1', timeout=10) test_client = Client('1', endpoint=endpoint, token='1', timeout=10)
result = test_client.webServers.list('1', 'test') result = test_client.webServers.list('1', 'test')
assert result == [] assert result == []

View File

@ -1,3 +1,18 @@
# 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 unittest import unittest
import logging import logging
from mock import MagicMock from mock import MagicMock

View File

@ -39,7 +39,7 @@ HORIZON_CONFIG = {
'exceptions': {'recoverable': exceptions.RECOVERABLE, 'exceptions': {'recoverable': exceptions.RECOVERABLE,
'not_found': exceptions.NOT_FOUND, 'not_found': exceptions.NOT_FOUND,
'unauthorized': exceptions.UNAUTHORIZED}, 'unauthorized': exceptions.UNAUTHORIZED},
'customization_module': 'windc.overrides' 'customization_module': 'tabula.overrides'
} }

View File

@ -1,215 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# 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.
import logging
from portasclient.v1.client import Client as windc_client
log = logging.getLogger(__name__)
def windcclient(request):
url = "http://127.0.0.1:8082"
log.debug('windcclient connection created using token "%s" and url "%s"'
% (request.user.token, url))
return windc_client(endpoint=url, token=request.user.token.token['id'])
def datacenters_create(request, parameters):
env = windcclient(request).environments.create(parameters.get('name', ''))
log.debug('Environment::Create {0}'.format(env))
return env
def datacenters_delete(request, datacenter_id):
result = windcclient(request).environments.delete(datacenter_id)
log.debug('Environment::Delete Id:{0}'.format(datacenter_id))
return result
def datacenters_get(request, datacenter_id):
env = windcclient(request).environments.get(datacenter_id)
log.debug('Environment::Get {0}'.format(env))
return env
def datacenters_list(request):
log.debug('Environment::List')
return windcclient(request).environments.list()
def datacenters_deploy(request, datacenter_id):
sessions = windcclient(request).sessions.list(datacenter_id)
for session in sessions:
if session.state == 'open':
session_id = session.id
if not session_id:
return "Sorry, nothing to deploy."
log.debug('Obtained session with Id: {0}'.format(session_id))
result = windcclient(request).sessions.deploy(datacenter_id, session_id)
log.debug('Environment with Id: {0} deployed in session '
'with Id: {1}'.format(datacenter_id, session_id))
return result
def services_create(request, environment_id, parameters):
session_id = None
sessions = windcclient(request).sessions.list(environment_id)
for s in sessions:
if s.state == 'open':
session_id = s.id
else:
windcclient(request).sessions.delete(environment_id, s.id)
if session_id is None:
session_id = windcclient(request).sessions.configure(environment_id).id
if parameters['service_type'] == 'Active Directory':
service = windcclient(request)\
.activeDirectories\
.create(environment_id, session_id, parameters)
else:
service = windcclient(request)\
.webServers.create(environment_id, session_id, parameters)
log.debug('Service::Create {0}'.format(service))
return service
def get_time(obj):
return obj.updated
def services_list(request, datacenter_id):
services = []
session_id = None
sessions = windcclient(request).sessions.list(datacenter_id)
for s in sessions:
session_id = s.id
if session_id:
services = windcclient(request).activeDirectories.list(datacenter_id,
session_id)
services += windcclient(request).webServers.list(datacenter_id,
session_id)
for i in range(len(services)):
reports = windcclient(request).sessions. \
reports(datacenter_id, session_id,
services[i].id)
for report in reports:
services[i].operation = report.text
log.debug('Service::List')
return services
def get_active_directories(request, datacenter_id):
services = []
session_id = None
sessions = windcclient(request).sessions.list(datacenter_id)
for s in sessions:
session_id = s.id
if session_id:
services = windcclient(request)\
.activeDirectories\
.list(datacenter_id, session_id)
log.debug('Service::Active Directories::List')
return services
def services_get(request, datacenter_id, service_id):
services = services_list(request, datacenter_id)
for service in services:
if service.id == service_id:
log.debug('Service::Get {0}'.format(service))
return service
def get_data_center_id_for_service(request, service_id):
datacenters = datacenters_list(request)
for dc in datacenters:
services = services_list(request, dc.id)
for service in services:
if service.id == service_id:
return dc.id
def get_service_datails(request, service_id):
datacenters = datacenters_list(request)
services = []
for dc in datacenters:
services += services_list(request, dc.id)
for service in services:
if service.id == service_id:
return service
def get_status_message_for_service(request, service_id):
environment_id = get_data_center_id_for_service(request, service_id)
session_id = None
sessions = windcclient(request).sessions.list(environment_id)
for s in sessions:
session_id = s.id
if session_id:
reports = windcclient(request).sessions.\
reports(environment_id, session_id, service_id)
result = 'Initialization.... \n'
for report in reports:
result += ' ' + str(report.text) + '\n'
return result
def services_delete(request, datacenter_id, service_id):
log.debug('Service::Remove EnvId: {0} '
'SrvId: {1}'.format(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)

View File

@ -1,125 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# 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.
import logging
import string
from django import forms
from django.utils.translation import ugettext_lazy as _
import re
from tabula.windc import api
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'),
choices=[
('Active Directory', 'Active Directory'),
('IIS', 'Internet Information Services')
])
class WizardFormConfiguration(forms.Form):
'The functions for this class will dynamically create in views.py'
pass
class WizardFormADConfiguration(forms.Form):
dc_name = forms.CharField(label=_('Domain Name'),
required=True)
dc_count = forms.IntegerField(label=_('Instances Count'),
required=True,
min_value=1,
max_value=100,
initial=1)
adm_password = PasswordField(_('Administrator password'))
recovery_password = PasswordField(_('Recovery password'))
def __init__(self, request, *args, **kwargs):
super(WizardFormADConfiguration, self).__init__(*args, **kwargs)
class WizardFormIISConfiguration(forms.Form):
iis_name = forms.CharField(label=_('IIS Server Name'),
required=True)
adm_password = PasswordField(_('Administrator password'))
iis_domain = forms.ChoiceField(label=_('Member of the Domain'),
required=False)
def __init__(self, request, *args, **kwargs):
super(WizardFormIISConfiguration, self).__init__(*args, **kwargs)
link = request.__dict__['META']['HTTP_REFERER']
datacenter_id = re.search('windc/(\S+)', link).group(0)[6:-1]
domains = api.get_active_directories(request, datacenter_id)
self.fields['iis_domain'].choices = [("", "")] + \
[(domain.name, domain.name)
for domain in domains]

View File

@ -1,6 +0,0 @@
import horizon
from panel import WinDC
project = horizon.get_dashboard('project')
project.register(WinDC)

View File

@ -1,29 +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 _
import horizon
from openstack_dashboard.dashboards.project import dashboard
class WinDC(horizon.Panel):
name = _("Windows Data Centers")
slug = 'windc'
dashboard.Project.register(WinDC)

View File

@ -1,197 +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.
# TO DO: clear extra modules
import logging
import re
from django.utils.translation import ugettext_lazy as _
from horizon import messages
from horizon import tables
from tabula.windc import api
LOG = logging.getLogger(__name__)
class CreateService(tables.LinkAction):
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):
api.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')
def allowed(self, request, datum):
return True
def action(self, request, datacenter):
api.datacenters_create(request, datacenter)
class DeleteDataCenter(tables.BatchAction):
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):
return True
def action(self, request, datacenter_id):
api.datacenters_delete(request, datacenter_id)
class DeleteService(tables.BatchAction):
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):
link = request.__dict__['META']['HTTP_REFERER']
datacenter_id = re.search('windc/(\S+)', link).group(0)[6:-1]
try:
api.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'
def allowed(self, request, datum):
return True
def action(self, request, datacenter_id):
return api.datacenters_deploy(request, datacenter_id)
class ShowDataCenterServices(tables.LinkAction):
name = 'edit'
verbose_name = _('Services')
url = 'horizon:project:windc:services'
def allowed(self, request, instance):
return True
class UpdateDCRow(tables.Row):
ajax = True
def get_data(self, request, datacenter_id):
return api.datacenters_get(request, datacenter_id)
class UpdateServiceRow(tables.Row):
ajax = True
def get_data(self, request, service_id):
link = request.__dict__['META']['HTTP_REFERER']
datacenter_id = re.search('windc/(\S+)', link).group(0)[6:-1]
service = api.services_get(request, datacenter_id, service_id)
return service
STATUS_DISPLAY_CHOICES = (
('draft', 'Ready to deploy'),
('pending', 'Wait for configuration'),
('inprogress', 'Deploy in progress'),
('finished', 'Active')
)
class WinDCTable(tables.DataTable):
STATUS_CHOICES = (
(None, True),
('Ready to deploy', True),
('Active', True)
)
name = tables.Column('name',
link=('horizon:project:windc:services'),
verbose_name=_('Name'))
status = tables.Column('status', verbose_name=_('Status'),
status=True,
status_choices=STATUS_CHOICES,
display_choices=STATUS_DISPLAY_CHOICES)
class Meta:
name = 'windc'
verbose_name = _('Windows Data Centers')
row_class = UpdateDCRow
status_columns = ['status']
table_actions = (CreateDataCenter,)
row_actions = (ShowDataCenterServices, DeleteDataCenter,
DeployDataCenter)
class WinServicesTable(tables.DataTable):
STATUS_CHOICES = (
(None, True),
('Ready to deploy', True),
('Active', True)
)
name = tables.Column('name', verbose_name=_('Name'),
link=('horizon:project:windc:service_details'))
_type = tables.Column('service_type', verbose_name=_('Type'))
status = tables.Column('status', verbose_name=_('Status'),
status=True,
status_choices=STATUS_CHOICES,
display_choices=STATUS_DISPLAY_CHOICES)
operation = tables.Column('operation', verbose_name=_('Operation'))
class Meta:
name = 'services'
verbose_name = _('Services')
row_class = UpdateServiceRow
status_columns = ['status']
table_actions = (CreateService,)

View File

@ -1,59 +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
import logging
from tabula.windc import api
LOG = logging.getLogger(__name__)
class OverviewTab(tabs.Tab):
name = _("Service")
slug = "_service"
template_name = '_services.html'
def get_context_data(self, request):
data = self.tab_group.kwargs['service']
return {"service_name": data.name,
"service_status": data.status,
"service_type": data.service_type,
"service_domain": data.domain}
class LogsTab(tabs.Tab):
name = _("Logs")
slug = "_logs"
template_name = '_service_logs.html'
def get_context_data(self, request):
data = self.tab_group.kwargs['service']
reports = api.get_status_message_for_service(request, data.id)
return {"reports": reports}
class WinServicesTabs(tabs.TabGroup):
slug = "services_details"
tabs = (OverviewTab, LogsTab)
sticky = True

View File

@ -1,41 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# 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.conf.urls.defaults import patterns, url
from .views import IndexView, WinServices, CreateWinDCView, DetailServiceView
from .views import Wizard
from .forms import WizardFormServiceType, WizardFormConfiguration
VIEW_MOD = 'openstack_dashboard.dashboards.project.windc.views'
urlpatterns = patterns(VIEW_MOD,
url(r'^$', IndexView.as_view(), name='index'),
url(r'^create$',
Wizard.as_view([WizardFormServiceType,
WizardFormConfiguration]),
name='create'),
url(r'^create_dc$', CreateWinDCView.as_view(),
name='create_dc'),
url(r'^(?P<data_center_id>[^/]+)/$',
WinServices.as_view(), name='services'),
url(r'^(?P<service_id>[^/]+)/details$',
DetailServiceView.as_view(),
name='service_details'))

View File

@ -1,215 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# 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.
"""
Views for managing instances.
"""
import logging
import re
from django.views import generic
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from django.contrib.formtools.wizard.views import SessionWizardView
from horizon import exceptions
from horizon import tabs
from horizon import tables
from horizon import workflows
from horizon.forms.views import ModalFormMixin
from tabula.windc import api
from .tables import WinDCTable, WinServicesTable
from .workflows import CreateWinDC
from .tabs import WinServicesTabs
from .forms import (WizardFormADConfiguration, WizardFormIISConfiguration)
from horizon import messages
from django.http import HttpResponseRedirect
LOG = logging.getLogger(__name__)
class Wizard(ModalFormMixin, SessionWizardView, generic.FormView):
template_name = 'services_tabs.html'
def done(self, form_list, **kwargs):
link = self.request.__dict__['META']['HTTP_REFERER']
datacenter_id = re.search('windc/(\S+)', link).group(0)[6:-1]
url = "/project/windc/%s/" % datacenter_id
service_type = form_list[0].data.get('0-service', '')
parameters = {'service_type': service_type}
data = form_list[1].data
if service_type == 'Active Directory':
parameters['configuration'] = 'standalone'
parameters['name'] = str(data.get('1-dc_name', 'noname'))
parameters['domain'] = parameters['name'] # Fix Me in orchestrator
parameters['adminPassword'] = str(data.get('1-adm_password', ''))
dc_count = int(data.get('1-dc_count', 1))
recovery_password = str(data.get('1-recovery_password', ''))
parameters['units'] = []
parameters['units'].append({'isMaster': True,
'recoveryPassword': recovery_password,
'location': 'west-dc'})
for dc in range(dc_count - 1):
parameters['units'].append({
'isMaster': False,
'recoveryPassword': recovery_password,
'location': 'west-dc'
})
elif service_type == 'IIS':
password = data.get('1-adm_password', '')
parameters['name'] = str(data.get('1-iis_name', 'noname'))
parameters['credentials'] = {'username': 'Administrator',
'password': password}
parameters['domain'] = str(data.get('1-iis_domain', ''))
password = form_list[1].data.get('1-adm_password', '')
domain = form_list[1].data.get('1-iis_domain', '')
dc_user = form_list[1].data.get('1-domain_user_name', '')
dc_pass = form_list[1].data.get('1-domain_user_password', '')
parameters['name'] = str(form_list[1].data.get('1-iis_name',
'noname'))
parameters['domain'] = parameters['name']
parameters['credentials'] = {'username': 'Administrator',
'password': password}
parameters['domain'] = str(domain)
# 'username': str(dc_user),
# 'password': str(dc_pass)}
parameters['location'] = 'west-dc'
parameters['units'] = []
parameters['units'].append({'id': '1',
'endpoint': [{'host': '10.0.0.1'}],
'location': 'west-dc'})
service = api.services_create(self.request, datacenter_id, parameters)
message = "The %s service successfully created." % service_type
messages.success(self.request, message)
return HttpResponseRedirect(url)
def get_form(self, step=None, data=None, files=None):
form = super(Wizard, self).get_form(step, data, files)
if data:
self.service_type = data.get('0-service', '')
if self.service_type == 'Active Directory':
self.form_list['1'] = WizardFormADConfiguration
elif self.service_type == 'IIS':
self.form_list['1'] = WizardFormIISConfiguration
return form
def get_form_kwargs(self, step=None):
return {'request': self.request} if step == u'1' else {}
def get_form_step_data(self, form):
LOG.debug(form.data)
return form.data
def get_context_data(self, form, **kwargs):
context = super(Wizard, self).get_context_data(form=form, **kwargs)
if self.steps.index > 0:
context.update({'service_type': self.service_type})
return context
class IndexView(tables.DataTableView):
table_class = WinDCTable
template_name = 'index.html'
def get_data(self):
try:
data_centers = api.datacenters_list(self.request)
except:
data_centers = []
exceptions.handle(self.request,
_('Unable to retrieve data centers list.'))
return data_centers
class WinServices(tables.DataTableView):
table_class = WinServicesTable
template_name = 'services.html'
def get_context_data(self, **kwargs):
context = super(WinServices, self).get_context_data(**kwargs)
context['dc_name'] = self.dc_name
return context
def get_data(self):
try:
dc_id = self.kwargs['data_center_id']
self.datacenter_id = dc_id
datacenter = api.datacenters_get(self.request, dc_id)
self.dc_name = datacenter.name
services = api.services_list(self.request, dc_id)
except:
services = []
exceptions.handle(self.request,
_('Unable to retrieve list of services for '
'data center "%s".') % self.dc_name)
self._services = services
return self._services
class DetailServiceView(tabs.TabView):
tab_group_class = WinServicesTabs
template_name = 'service_details.html'
def get_context_data(self, **kwargs):
context = super(DetailServiceView, self).get_context_data(**kwargs)
context["service"] = self.get_data()
context["service_name"] = self.get_data().name
return context
def get_data(self):
if not hasattr(self, "_service"):
try:
service_id = self.kwargs['service_id']
service = api.get_service_datails(self.request, service_id)
except:
redirect = reverse('horizon:project:windc:index')
exceptions.handle(self.request,
_('Unable to retrieve details for '
'service "%s".') % service_id,
redirect=redirect)
self._service = service
return self._service
def get_tabs(self, request, *args, **kwargs):
service = self.get_data()
return self.tab_group_class(request, service=service, **kwargs)
class CreateWinDCView(workflows.WorkflowView):
workflow_class = CreateWinDC
template_name = 'create_dc.html'
def get_initial(self):
initial = super(CreateWinDCView, self).get_initial()
initial['project_id'] = self.request.user.tenant_id
initial['user_id'] = self.request.user.id
return initial

View File

@ -1,101 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# 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.
import json
import logging
import re
from django.utils.text import normalize_newlines
from django.utils.translation import ugettext as _
from horizon import exceptions
from horizon import forms
from horizon import workflows
from tabula.windc import api
LOG = logging.getLogger(__name__)
class SelectProjectUserAction(workflows.Action):
project_id = forms.ChoiceField(label=_("Project"))
user_id = forms.ChoiceField(label=_("User"))
def __init__(self, request, *args, **kwargs):
super(SelectProjectUserAction, self).__init__(request, *args, **kwargs)
# Set our project choices
projects = [(tenant.id, tenant.name)
for tenant in request.user.authorized_tenants]
self.fields['project_id'].choices = projects
# Set our user options
users = [(request.user.id, request.user.username)]
self.fields['user_id'].choices = users
class Meta:
name = _("Project & User")
# Unusable permission so this is always hidden. However, we
# keep this step in the workflow for validation/verification purposes.
permissions = ("!",)
class SelectProjectUser(workflows.Step):
action_class = SelectProjectUserAction
class ConfigureDCAction(workflows.Action):
name = forms.CharField(label=_("Data Center Name"), required=True)
class Meta:
name = _("Data Center")
help_text_template = "_data_center_help.html"
class ConfigureDC(workflows.Step):
action_class = ConfigureDCAction
contibutes = ('name',)
def contribute(self, data, context):
if data:
context['name'] = data.get('name', '')
return context
class CreateWinDC(workflows.Workflow):
slug = "create"
name = _("Create Windows Data Center")
finalize_button_name = _("Create")
success_message = _('Created data center "%s".')
failure_message = _('Unable to create data center "%s".')
success_url = "horizon:project:windc:index"
default_steps = (SelectProjectUser, ConfigureDC)
def format_status_message(self, message):
name = self.context.get('name', 'noname')
return message % name
def handle(self, request, context):
try:
datacenter = api.datacenters_create(request, context)
return True
except:
exceptions.handle(request)
return False