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

This commit is contained in:
Timur Nurlygayanov 2013-04-05 15:32:17 +04:00
parent bd7a24e3c1
commit f5a08a6a22
11 changed files with 1168 additions and 0 deletions

View File

@ -0,0 +1,189 @@
!ENTRY com.aptana.shared_core 4 4 2013-04-05 14:34:01.030
!MESSAGE Error when analyzing module forms
!STACK 0
java.lang.RuntimeException: java.io.IOException: No such file or directory
at org.python.pydev.core.DeltaSaver.addCommand(DeltaSaver.java:254)
at org.python.pydev.core.DeltaSaver.addInsertCommand(DeltaSaver.java:293)
at org.python.pydev.editor.codecompletion.revisited.ModulesManagerWithBuild.doAddSingleModule(ModulesManagerWithBuild.java:112)
at org.python.pydev.editor.codecompletion.revisited.ModulesManager.getModule(ModulesManager.java:895)
at org.python.pydev.editor.codecompletion.revisited.ModulesManager.getModule(ModulesManager.java:718)
at org.python.pydev.editor.codecompletion.revisited.SystemModulesManager.getModule(SystemModulesManager.java:342)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.getModule(AbstractASTManager.java:448)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.findModuleFromPath(AbstractASTManager.java:1430)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.findOnImportedMods(AbstractASTManager.java:1321)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.findOnImportedMods(AbstractASTManager.java:1200)
at com.python.pydev.analysis.visitors.ImportChecker.visitImportToken(ImportChecker.java:186)
at com.python.pydev.analysis.visitors.ImportChecker.visitImportToken(ImportChecker.java:167)
at com.python.pydev.analysis.visitors.Scope.addImportTokens(Scope.java:173)
at com.python.pydev.analysis.scopeanalysis.AbstractScopeAnalyzerVisitor.visitImportFrom(AbstractScopeAnalyzerVisitor.java:562)
at com.python.pydev.analysis.scopeanalysis.ScopeAnalyzerVisitor.visitImportFrom(ScopeAnalyzerVisitor.java:106)
at org.python.pydev.parser.jython.ast.ImportFrom.accept(ImportFrom.java:99)
at org.python.pydev.parser.jython.ast.Module.traverse(Module.java:86)
at com.python.pydev.analysis.scopeanalysis.AbstractScopeAnalyzerVisitor.traverse(AbstractScopeAnalyzerVisitor.java:189)
at org.python.pydev.parser.jython.ast.VisitorBase.visitModule(VisitorBase.java:10)
at org.python.pydev.parser.jython.ast.Module.accept(Module.java:79)
at com.python.pydev.refactoring.wizards.rename.AbstractRenameRefactorProcess.getOccurrencesWithScopeAnalyzer(AbstractRenameRefactorProcess.java:257)
at com.python.pydev.refactoring.wizards.rename.PyRenameAnyLocalProcess.findReferencesToRenameOnLocalScope(PyRenameAnyLocalProcess.java:38)
at com.python.pydev.refactoring.wizards.rename.AbstractRenameRefactorProcess.findReferencesToRename(AbstractRenameRefactorProcess.java:181)
at com.python.pydev.refactoring.wizards.rename.PyRenameEntryPoint.checkFinalConditions(PyRenameEntryPoint.java:258)
at com.python.pydev.refactoring.wizards.rename.PyRenameEntryPoint.checkFinalConditions(PyRenameEntryPoint.java:227)
at com.python.pydev.refactoring.markoccurrences.MarkOccurrencesJob.checkAnnotations(MarkOccurrencesJob.java:226)
at com.python.pydev.refactoring.markoccurrences.MarkOccurrencesJob.run(MarkOccurrencesJob.java:126)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Caused by: java.io.IOException: No such file or directory
at java.io.UnixFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:947)
at org.python.pydev.core.DeltaSaver.addCommand(DeltaSaver.java:252)
... 27 more
!ENTRY com.aptana.shared_core 4 4 2013-04-05 15:21:20.739
!MESSAGE Error when analyzing module urls
!STACK 0
java.lang.RuntimeException: java.io.IOException: No such file or directory
at org.python.pydev.core.DeltaSaver.addCommand(DeltaSaver.java:254)
at org.python.pydev.core.DeltaSaver.addInsertCommand(DeltaSaver.java:293)
at org.python.pydev.editor.codecompletion.revisited.ModulesManagerWithBuild.doAddSingleModule(ModulesManagerWithBuild.java:112)
at org.python.pydev.editor.codecompletion.revisited.ModulesManager.getModule(ModulesManager.java:895)
at org.python.pydev.editor.codecompletion.revisited.ModulesManager.getModule(ModulesManager.java:718)
at org.python.pydev.editor.codecompletion.revisited.SystemModulesManager.getRelativeModule(SystemModulesManager.java:139)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.getModule(AbstractASTManager.java:446)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.findModuleFromPath(AbstractASTManager.java:1437)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.findOnImportedMods(AbstractASTManager.java:1289)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.findOnImportedMods(AbstractASTManager.java:1200)
at com.python.pydev.analysis.visitors.ImportChecker.visitImportToken(ImportChecker.java:186)
at com.python.pydev.analysis.visitors.ImportChecker.visitImportToken(ImportChecker.java:167)
at com.python.pydev.analysis.visitors.Scope.addImportTokens(Scope.java:173)
at com.python.pydev.analysis.scopeanalysis.AbstractScopeAnalyzerVisitor.visitImportFrom(AbstractScopeAnalyzerVisitor.java:562)
at com.python.pydev.analysis.scopeanalysis.ScopeAnalyzerVisitor.visitImportFrom(ScopeAnalyzerVisitor.java:106)
at org.python.pydev.parser.jython.ast.ImportFrom.accept(ImportFrom.java:99)
at org.python.pydev.parser.jython.ast.Module.traverse(Module.java:86)
at com.python.pydev.analysis.scopeanalysis.AbstractScopeAnalyzerVisitor.traverse(AbstractScopeAnalyzerVisitor.java:189)
at org.python.pydev.parser.jython.ast.VisitorBase.visitModule(VisitorBase.java:10)
at org.python.pydev.parser.jython.ast.Module.accept(Module.java:79)
at com.python.pydev.refactoring.wizards.rename.AbstractRenameRefactorProcess.getOccurrencesWithScopeAnalyzer(AbstractRenameRefactorProcess.java:257)
at com.python.pydev.refactoring.wizards.rename.PyRenameImportProcess.findReferencesToRenameOnLocalScope(PyRenameImportProcess.java:66)
at com.python.pydev.refactoring.wizards.rename.AbstractRenameRefactorProcess.findReferencesToRename(AbstractRenameRefactorProcess.java:181)
at com.python.pydev.refactoring.wizards.rename.PyRenameEntryPoint.checkFinalConditions(PyRenameEntryPoint.java:258)
at com.python.pydev.refactoring.wizards.rename.PyRenameEntryPoint.checkFinalConditions(PyRenameEntryPoint.java:227)
at com.python.pydev.refactoring.markoccurrences.MarkOccurrencesJob.checkAnnotations(MarkOccurrencesJob.java:226)
at com.python.pydev.refactoring.markoccurrences.MarkOccurrencesJob.run(MarkOccurrencesJob.java:126)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Caused by: java.io.IOException: No such file or directory
at java.io.UnixFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:947)
at org.python.pydev.core.DeltaSaver.addCommand(DeltaSaver.java:252)
... 27 more
!ENTRY com.aptana.shared_core 4 4 2013-04-05 15:22:51.347
!MESSAGE Error when analyzing module views
!STACK 0
java.lang.RuntimeException: java.io.IOException: No such file or directory
at org.python.pydev.core.DeltaSaver.addCommand(DeltaSaver.java:254)
at org.python.pydev.core.DeltaSaver.addInsertCommand(DeltaSaver.java:293)
at org.python.pydev.editor.codecompletion.revisited.ModulesManagerWithBuild.doAddSingleModule(ModulesManagerWithBuild.java:112)
at org.python.pydev.editor.codecompletion.revisited.ModulesManager.getModule(ModulesManager.java:895)
at org.python.pydev.editor.codecompletion.revisited.ModulesManager.getModule(ModulesManager.java:718)
at org.python.pydev.editor.codecompletion.revisited.SystemModulesManager.getModule(SystemModulesManager.java:342)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.getModule(AbstractASTManager.java:448)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.findModuleFromPath(AbstractASTManager.java:1430)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.findOnImportedMods(AbstractASTManager.java:1304)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.findOnImportedMods(AbstractASTManager.java:1200)
at com.python.pydev.analysis.visitors.ImportChecker.visitImportToken(ImportChecker.java:186)
at com.python.pydev.analysis.visitors.ImportChecker.visitImportToken(ImportChecker.java:167)
at com.python.pydev.analysis.visitors.Scope.addImportTokens(Scope.java:173)
at com.python.pydev.analysis.scopeanalysis.AbstractScopeAnalyzerVisitor.visitImportFrom(AbstractScopeAnalyzerVisitor.java:562)
at com.python.pydev.analysis.scopeanalysis.ScopeAnalyzerVisitor.visitImportFrom(ScopeAnalyzerVisitor.java:106)
at org.python.pydev.parser.jython.ast.ImportFrom.accept(ImportFrom.java:99)
at org.python.pydev.parser.jython.ast.Module.traverse(Module.java:86)
at com.python.pydev.analysis.scopeanalysis.AbstractScopeAnalyzerVisitor.traverse(AbstractScopeAnalyzerVisitor.java:189)
at org.python.pydev.parser.jython.ast.VisitorBase.visitModule(VisitorBase.java:10)
at org.python.pydev.parser.jython.ast.Module.accept(Module.java:79)
at com.python.pydev.refactoring.wizards.rename.AbstractRenameRefactorProcess.getOccurrencesWithScopeAnalyzer(AbstractRenameRefactorProcess.java:257)
at com.python.pydev.refactoring.wizards.rename.PyRenameImportProcess.findReferencesToRenameOnLocalScope(PyRenameImportProcess.java:66)
at com.python.pydev.refactoring.wizards.rename.AbstractRenameRefactorProcess.findReferencesToRename(AbstractRenameRefactorProcess.java:181)
at com.python.pydev.refactoring.wizards.rename.PyRenameEntryPoint.checkFinalConditions(PyRenameEntryPoint.java:258)
at com.python.pydev.refactoring.wizards.rename.PyRenameEntryPoint.checkFinalConditions(PyRenameEntryPoint.java:227)
at com.python.pydev.refactoring.markoccurrences.MarkOccurrencesJob.checkAnnotations(MarkOccurrencesJob.java:226)
at com.python.pydev.refactoring.markoccurrences.MarkOccurrencesJob.run(MarkOccurrencesJob.java:126)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Caused by: java.io.IOException: No such file or directory
at java.io.UnixFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:947)
at org.python.pydev.core.DeltaSaver.addCommand(DeltaSaver.java:252)
... 27 more
!ENTRY com.aptana.shared_core 4 4 2013-04-05 15:25:25.732
!MESSAGE java.io.IOException: No such file or directory
!STACK 0
java.lang.RuntimeException: java.io.IOException: No such file or directory
at org.python.pydev.core.DeltaSaver.addCommand(DeltaSaver.java:254)
at org.python.pydev.core.DeltaSaver.addInsertCommand(DeltaSaver.java:293)
at org.python.pydev.editor.codecompletion.revisited.ModulesManagerWithBuild.doAddSingleModule(ModulesManagerWithBuild.java:112)
at org.python.pydev.editor.codecompletion.revisited.ModulesManager.getModule(ModulesManager.java:895)
at org.python.pydev.editor.codecompletion.revisited.ModulesManager.getModule(ModulesManager.java:718)
at org.python.pydev.editor.codecompletion.revisited.SystemModulesManager.getModule(SystemModulesManager.java:342)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.getModule(AbstractASTManager.java:448)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.findModuleFromPath(AbstractASTManager.java:1430)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.findOnImportedMods(AbstractASTManager.java:1321)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.findOnImportedMods(AbstractASTManager.java:1200)
at com.python.pydev.analysis.visitors.ImportChecker.visitImportToken(ImportChecker.java:186)
at com.python.pydev.analysis.visitors.ImportChecker.visitImportToken(ImportChecker.java:167)
at com.python.pydev.analysis.visitors.Scope.addImportTokens(Scope.java:173)
at com.python.pydev.analysis.scopeanalysis.AbstractScopeAnalyzerVisitor.visitImport(AbstractScopeAnalyzerVisitor.java:538)
at org.python.pydev.parser.jython.ast.Import.accept(Import.java:79)
at org.python.pydev.parser.jython.ast.Module.traverse(Module.java:86)
at com.python.pydev.analysis.scopeanalysis.AbstractScopeAnalyzerVisitor.traverse(AbstractScopeAnalyzerVisitor.java:189)
at org.python.pydev.parser.jython.ast.VisitorBase.visitModule(VisitorBase.java:10)
at org.python.pydev.parser.jython.ast.Module.accept(Module.java:79)
at com.python.pydev.refactoring.wizards.rename.AbstractRenameRefactorProcess.getOccurrencesWithScopeAnalyzer(AbstractRenameRefactorProcess.java:257)
at com.python.pydev.refactoring.wizards.rename.PyRenameAnyLocalProcess.findReferencesToRenameOnLocalScope(PyRenameAnyLocalProcess.java:38)
at com.python.pydev.refactoring.wizards.rename.AbstractRenameRefactorProcess.findReferencesToRename(AbstractRenameRefactorProcess.java:181)
at com.python.pydev.refactoring.wizards.rename.PyRenameEntryPoint.checkFinalConditions(PyRenameEntryPoint.java:258)
at com.python.pydev.refactoring.wizards.rename.PyRenameEntryPoint.checkFinalConditions(PyRenameEntryPoint.java:227)
at com.python.pydev.refactoring.markoccurrences.MarkOccurrencesJob.checkAnnotations(MarkOccurrencesJob.java:226)
at com.python.pydev.refactoring.markoccurrences.MarkOccurrencesJob.run(MarkOccurrencesJob.java:126)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Caused by: java.io.IOException: No such file or directory
at java.io.UnixFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:947)
at org.python.pydev.core.DeltaSaver.addCommand(DeltaSaver.java:252)
... 26 more
!ENTRY com.aptana.shared_core 4 4 2013-04-05 15:26:00.341
!MESSAGE Error when analyzing module workflows
!STACK 0
java.lang.RuntimeException: java.io.IOException: No such file or directory
at org.python.pydev.core.DeltaSaver.addCommand(DeltaSaver.java:254)
at org.python.pydev.core.DeltaSaver.addInsertCommand(DeltaSaver.java:293)
at org.python.pydev.editor.codecompletion.revisited.ModulesManagerWithBuild.doAddSingleModule(ModulesManagerWithBuild.java:112)
at org.python.pydev.editor.codecompletion.revisited.ModulesManager.getModule(ModulesManager.java:895)
at org.python.pydev.editor.codecompletion.revisited.ModulesManager.getModule(ModulesManager.java:718)
at org.python.pydev.editor.codecompletion.revisited.SystemModulesManager.getRelativeModule(SystemModulesManager.java:139)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.getModule(AbstractASTManager.java:446)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.findModuleFromPath(AbstractASTManager.java:1437)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.findOnImportedMods(AbstractASTManager.java:1289)
at org.python.pydev.editor.codecompletion.revisited.AbstractASTManager.findOnImportedMods(AbstractASTManager.java:1200)
at com.python.pydev.analysis.visitors.ImportChecker.visitImportToken(ImportChecker.java:186)
at com.python.pydev.analysis.visitors.ImportChecker.visitImportToken(ImportChecker.java:167)
at com.python.pydev.analysis.visitors.Scope.addImportTokens(Scope.java:173)
at com.python.pydev.analysis.scopeanalysis.AbstractScopeAnalyzerVisitor.visitImportFrom(AbstractScopeAnalyzerVisitor.java:562)
at com.python.pydev.analysis.scopeanalysis.ScopeAnalyzerVisitor.visitImportFrom(ScopeAnalyzerVisitor.java:106)
at org.python.pydev.parser.jython.ast.ImportFrom.accept(ImportFrom.java:99)
at org.python.pydev.parser.jython.ast.Module.traverse(Module.java:86)
at com.python.pydev.analysis.scopeanalysis.AbstractScopeAnalyzerVisitor.traverse(AbstractScopeAnalyzerVisitor.java:189)
at org.python.pydev.parser.jython.ast.VisitorBase.visitModule(VisitorBase.java:10)
at org.python.pydev.parser.jython.ast.Module.accept(Module.java:79)
at com.python.pydev.refactoring.wizards.rename.AbstractRenameRefactorProcess.getOccurrencesWithScopeAnalyzer(AbstractRenameRefactorProcess.java:257)
at com.python.pydev.refactoring.wizards.rename.PyRenameAnyLocalProcess.findReferencesToRenameOnLocalScope(PyRenameAnyLocalProcess.java:38)
at com.python.pydev.refactoring.wizards.rename.AbstractRenameRefactorProcess.findReferencesToRename(AbstractRenameRefactorProcess.java:181)
at com.python.pydev.refactoring.wizards.rename.PyRenameEntryPoint.checkFinalConditions(PyRenameEntryPoint.java:258)
at com.python.pydev.refactoring.wizards.rename.PyRenameEntryPoint.checkFinalConditions(PyRenameEntryPoint.java:227)
at com.python.pydev.refactoring.markoccurrences.MarkOccurrencesJob.checkAnnotations(MarkOccurrencesJob.java:226)
at com.python.pydev.refactoring.markoccurrences.MarkOccurrencesJob.run(MarkOccurrencesJob.java:126)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Caused by: java.io.IOException: No such file or directory
at java.io.UnixFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:947)
at org.python.pydev.core.DeltaSaver.addCommand(DeltaSaver.java:252)
... 27 more

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.

210
tabula/tabula/tabula/api.py Normal file
View File

@ -0,0 +1,210 @@
# 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
from portasclient.v1.client import Client as glazier_client
log = logging.getLogger(__name__)
def glazierclient(request):
url = "http://127.0.0.1:8082"
log.debug('glazierclient connection created using token "%s" and url "%s"'
% (request.user.token, url))
return glazier_client(endpoint=url, token=request.user.token.token['id'])
def datacenters_create(request, parameters):
env = glazierclient(request).environments.create(parameters.get('name', ''))
log.debug('Environment::Create {0}'.format(env))
return env
def datacenters_delete(request, datacenter_id):
result = glazierclient(request).environments.delete(datacenter_id)
log.debug('Environment::Delete Id:{0}'.format(datacenter_id))
return result
def datacenters_get(request, datacenter_id):
env = glazierclient(request).environments.get(datacenter_id)
log.debug('Environment::Get {0}'.format(env))
return env
def datacenters_list(request):
log.debug('Environment::List')
return glazierclient(request).environments.list()
def datacenters_deploy(request, datacenter_id):
sessions = glazierclient(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 = glazierclient(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 = glazierclient(request).sessions.list(environment_id)
for s in sessions:
if s.state == 'open':
session_id = s.id
else:
glazierclient(request).sessions.delete(environment_id, s.id)
if session_id is None:
session_id = glazierclient(request).sessions.configure(environment_id).id
if parameters['service_type'] == 'Active Directory':
service = glazierclient(request)\
.activeDirectories\
.create(environment_id, session_id, parameters)
else:
service = glazierclient(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 = glazierclient(request).sessions.list(datacenter_id)
for s in sessions:
session_id = s.id
if session_id:
services = glazierclient(request).activeDirectories.list(datacenter_id,
session_id)
services += glazierclient(request).webServers.list(datacenter_id,
session_id)
for i in range(len(services)):
reports = glazierclient(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 = glazierclient(request).sessions.list(datacenter_id)
for s in sessions:
session_id = s.id
if session_id:
services = glazierclient(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 = glazierclient(request).sessions.list(environment_id)
for s in sessions:
session_id = s.id
if session_id:
reports = glazierclient(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 = glazierclient(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':
glazierclient(request).activeDirectories.delete(datacenter_id,
session_id,
service_id)
elif service.type is 'IIS':
glazierclient(request).webServers.delete(datacenter_id,
session_id,
service_id)

View File

@ -0,0 +1,120 @@
# 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 string
from django import forms
from django.utils.translation import ugettext_lazy as _
import re
from tabula.tabula 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('tabula/(\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

@ -0,0 +1,21 @@
# 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 panel import tabula
project = horizon.get_dashboard('project')
project.register(tabula)

View File

@ -0,0 +1,26 @@
# 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 openstack_dashboard.dashboards.project import dashboard
class tabula(horizon.Panel):
name = _("Environments")
slug = 'tabula'
dashboard.Project.register(tabula)

View File

@ -0,0 +1,193 @@
# 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 re
from django.utils.translation import ugettext_lazy as _
from horizon import messages
from horizon import tables
from tabula.tabula import api
LOG = logging.getLogger(__name__)
class CreateService(tables.LinkAction):
name = 'CreateService'
verbose_name = _('Create Service')
url = 'horizon:project:tabula:create'
classes = ('btn-launch', 'ajax-modal')
def allowed(self, request, datum):
return True
def action(self, request, service):
api.services_create(request, service)
class CreateEnvironment(tables.LinkAction):
name = 'CreateEnvironment'
verbose_name = _('Create Environment')
url = 'horizon:project:tabula:create_dc'
classes = ('btn-launch', 'ajax-modal')
def allowed(self, request, datum):
return True
def action(self, request, environment):
api.datacenters_create(request, environment)
class DeleteEnvironment(tables.BatchAction):
name = 'delete'
action_present = _('Delete')
action_past = _('Delete')
data_type_singular = _('Environment')
data_type_plural = _('Environment')
classes = ('btn-danger', 'btn-terminate')
def allowed(self, request, datum):
return True
def action(self, request, environment_id):
api.datacenters_delete(request, environment_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('tabula/(\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 DeployEnvironment(tables.BatchAction):
name = 'deploy'
action_present = _('Deploy')
action_past = _('Deploy')
data_type_singular = _('Environment')
data_type_plural = _('Environment')
classes = 'btn-launch'
def allowed(self, request, datum):
return True
def action(self, request, environment_id):
return api.datacenters_deploy(request, environment_id)
class ShowDataCenterServices(tables.LinkAction):
name = 'edit'
verbose_name = _('Services')
url = 'horizon:project:tabula: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('tabula/(\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 DCTable(tables.DataTable):
STATUS_CHOICES = (
(None, True),
('Ready to deploy', True),
('Active', True)
)
name = tables.Column('name',
link=('horizon:project:tabula: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 = 'tabula'
verbose_name = _('Environment')
row_class = UpdateDCRow
status_columns = ['status']
table_actions = (CreateDataCenter,)
row_actions = (ShowDataCenterServices, DeleteDataCenter,
DeployDataCenter)
class ServicesTable(tables.DataTable):
STATUS_CHOICES = (
(None, True),
('Ready to deploy', True),
('Active', True)
)
name = tables.Column('name', verbose_name=_('Name'),
link=('horizon:project:tabula: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

@ -0,0 +1,58 @@
# 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 tabs
import logging
from tabula.tabula 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 ServicesTabs(tabs.TabGroup):
slug = "services_details"
tabs = (OverviewTab, LogsTab)
sticky = True

View File

@ -0,0 +1,36 @@
# 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 IndexView, Services, CreateDCView, DetailServiceView
from .views import Wizard
from .forms import WizardFormServiceType, WizardFormConfiguration
VIEW_MOD = 'openstack_dashboard.dashboards.project.tabula.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$', CreateDCView.as_view(),
name='create_dc'),
url(r'^(?P<data_center_id>[^/]+)/$',
Services.as_view(), name='services'),
url(r'^(?P<service_id>[^/]+)/details$',
DetailServiceView.as_view(),
name='service_details'))

View File

@ -0,0 +1,205 @@
# 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 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.tabula import api
from .tables import DCTable, ServicesTable
from .workflows import CreateDC
from .tabs import ServicesTabs
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('tabula/(\S+)', link).group(0)[6:-1]
url = "/project/tabula/%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)
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 Services(tables.DataTableView):
table_class = ServicesTable
template_name = 'services.html'
def get_context_data(self, **kwargs):
context = super(Services, 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 = ServicesTabs
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:tabula: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 CreateDCView(workflows.WorkflowView):
workflow_class = CreateDC
template_name = 'create_dc.html'
def get_initial(self):
initial = super(CreateDCView, self).get_initial()
initial['project_id'] = self.request.user.tenant_id
initial['user_id'] = self.request.user.id
return initial

View File

@ -0,0 +1,96 @@
# 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 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.tabula 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=_("Environment Name"), required=True)
class Meta:
name = _("Environment")
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 CreateDC(workflows.Workflow):
slug = "create"
name = _("Create Environment")
finalize_button_name = _("Create")
success_message = _('Created environment "%s".')
failure_message = _('Unable to create environment "%s".')
success_url = "horizon:project:tabula: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