From e999e5acf84b20c5be34ca835e656877e00812a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez=20Garc=C3=ADa?= Date: Tue, 26 Oct 2021 16:31:54 +0200 Subject: [PATCH] Removed outdated documentation --- server/documentation/Makefile | 153 - .../_build/doctrees/api/index.doctree | Bin 2936 -> 0 bytes .../_build/doctrees/api/models.doctree | Bin 5121 -> 0 bytes .../api/models/authentication.doctree | Bin 51925 -> 0 bytes .../_build/doctrees/api/models/other.doctree | Bin 26101 -> 0 bytes .../doctrees/api/models/services.doctree | Bin 141396 -> 0 bytes .../doctrees/api/models/transport.doctree | Bin 34509 -> 0 bytes .../_build/doctrees/api/modules.doctree | Bin 4212 -> 0 bytes .../api/modules/AuthenticatorModule.doctree | Bin 6463 -> 0 bytes .../doctrees/api/modules/BaseModule.doctree | Bin 105921 -> 0 bytes .../doctrees/api/modules/FormFields.doctree | Bin 88258 -> 0 bytes .../api/modules/ServiceModules.doctree | Bin 13996 -> 0 bytes .../api/modules/auths/Authenticator.doctree | Bin 131457 -> 0 bytes .../api/modules/services/Exceptions.doctree | Bin 17026 -> 0 bytes .../api/modules/services/Provider.doctree | Bin 19780 -> 0 bytes .../api/modules/services/Publication.doctree | Bin 42511 -> 0 bytes .../api/modules/services/Service.doctree | Bin 22870 -> 0 bytes .../modules/services/UserDeployment.doctree | Bin 92613 -> 0 bytes .../doctrees/development/architecture.doctree | Bin 9732 -> 0 bytes .../doctrees/development/contributing.doctree | Bin 2547 -> 0 bytes .../doctrees/development/repository.doctree | Bin 2525 -> 0 bytes .../samples/auths/Authenticator.doctree | Bin 33487 -> 0 bytes .../development/samples/samples.doctree | Bin 18001 -> 0 bytes .../services/DeployedServiceOne.doctree | Bin 36950 -> 0 bytes .../services/DeployedServiceTwo.doctree | Bin 46710 -> 0 bytes .../samples/services/Provider.doctree | Bin 22830 -> 0 bytes .../samples/services/Publication.doctree | Bin 28313 -> 0 bytes .../samples/services/Service.doctree | Bin 23643 -> 0 bytes .../samples/services/whatisneeded.doctree | Bin 11743 -> 0 bytes .../_build/doctrees/environment.pickle | Bin 1406907 -> 0 bytes .../_build/doctrees/index.doctree | Bin 16882 -> 0 bytes .../_build/doctrees/intro/install.doctree | Bin 12746 -> 0 bytes .../_build/doctrees/intro/overview.doctree | Bin 8591 -> 0 bytes server/documentation/_build/html/.buildinfo | 4 - .../_build/html/_downloads/SampleAuth.py | 307 - .../_build/html/_downloads/SampleProvider.py | 196 - .../html/_downloads/SamplePublication.py | 272 - .../_build/html/_downloads/SampleService.py | 236 - .../_downloads/SampleUserDeploymentOne.py | 373 - .../_downloads/SampleUserDeploymentTwo.py | 469 - .../_build/html/_downloads/__init__.py | 44 - .../_build/html/_modules/index.html | 96 - .../_build/html/_modules/uds/core.html | 136 - .../_build/html/_modules/uds/core/auths.html | 146 - .../html/_modules/uds/core/services.html | 152 - .../uds/core/services/Exceptions.html | 181 - .../_modules/uds/core/ui/UserInterface.html | 940 -- .../_build/html/_modules/uds/models.html | 183 - .../_build/html/_sources/api/index.txt | 9 - .../_build/html/_sources/api/models.txt | 24 - .../_sources/api/models/authentication.txt | 25 - .../_build/html/_sources/api/models/other.txt | 41 - .../html/_sources/api/models/services.txt | 33 - .../html/_sources/api/models/transport.txt | 18 - .../_build/html/_sources/api/modules.txt | 18 - .../api/modules/AuthenticatorModule.txt | 27 - .../html/_sources/api/modules/BaseModule.txt | 53 - .../html/_sources/api/modules/FormFields.txt | 33 - .../_sources/api/modules/ServiceModules.txt | 53 - .../api/modules/auths/Authenticator.txt | 15 - .../api/modules/services/Exceptions.txt | 9 - .../api/modules/services/Provider.txt | 27 - .../api/modules/services/Publication.txt | 30 - .../_sources/api/modules/services/Service.txt | 25 - .../api/modules/services/UserDeployment.txt | 23 - .../_sources/development/architecture.txt | 36 - .../_sources/development/contributing.txt | 3 - .../html/_sources/development/repository.txt | 3 - .../samples/auths/Authenticator.txt | 15 - .../_sources/development/samples/samples.txt | 100 - .../samples/services/DeployedServiceOne.txt | 20 - .../samples/services/DeployedServiceTwo.txt | 20 - .../development/samples/services/Provider.txt | 19 - .../samples/services/Publication.txt | 23 - .../development/samples/services/Service.txt | 15 - .../samples/services/whatisneeded.txt | 32 - .../_build/html/_sources/index.txt | 71 - .../_build/html/_sources/intro/install.txt | 46 - .../_build/html/_sources/intro/overview.txt | 32 - .../_build/html/_static/ajax-loader.gif | Bin 673 -> 0 bytes .../_build/html/_static/basic.css | 537 - .../_build/html/_static/comment-bright.png | Bin 3500 -> 0 bytes .../_build/html/_static/comment-close.png | Bin 3578 -> 0 bytes .../_build/html/_static/comment.png | Bin 3445 -> 0 bytes .../_build/html/_static/contents.png | Bin 202 -> 0 bytes .../_build/html/_static/doctools.js | 238 - .../_build/html/_static/down-pressed.png | Bin 368 -> 0 bytes .../_build/html/_static/down.png | Bin 363 -> 0 bytes .../_build/html/_static/file.png | Bin 392 -> 0 bytes .../_build/html/_static/jquery.js | 9404 ----------------- .../_build/html/_static/minus.png | Bin 199 -> 0 bytes .../_build/html/_static/navigation.png | Bin 218 -> 0 bytes .../_build/html/_static/plus.png | Bin 199 -> 0 bytes .../_build/html/_static/pygments.css | 62 - .../_build/html/_static/searchtools.js | 622 -- .../_build/html/_static/sphinxdoc.css | 339 - .../_build/html/_static/underscore.js | 1226 --- .../_build/html/_static/up-pressed.png | Bin 372 -> 0 bytes .../documentation/_build/html/_static/up.png | Bin 363 -> 0 bytes .../_build/html/_static/websupport.js | 808 -- .../documentation/_build/html/api/index.html | 194 - .../documentation/_build/html/api/models.html | 150 - .../html/api/models/authentication.html | 367 - .../_build/html/api/models/other.html | 226 - .../_build/html/api/models/services.html | 808 -- .../_build/html/api/models/transport.html | 280 - .../_build/html/api/modules.html | 162 - .../html/api/modules/AuthenticatorModule.html | 147 - .../_build/html/api/modules/BaseModule.html | 595 -- .../_build/html/api/modules/FormFields.html | 559 - .../html/api/modules/ServiceModules.html | 184 - .../html/api/modules/auths/Authenticator.html | 761 -- .../html/api/modules/services/Exceptions.html | 171 - .../html/api/modules/services/Provider.html | 207 - .../api/modules/services/Publication.html | 348 - .../html/api/modules/services/Service.html | 219 - .../api/modules/services/UserDeployment.html | 638 -- .../_build/html/development/architecture.html | 164 - .../_build/html/development/contributing.html | 117 - .../_build/html/development/repository.html | 107 - .../samples/auths/Authenticator.html | 742 -- .../html/development/samples/samples.html | 216 - .../samples/services/DeployedServiceOne.html | 877 -- .../samples/services/DeployedServiceTwo.html | 1069 -- .../samples/services/Provider.html | 523 - .../samples/services/Publication.html | 678 -- .../development/samples/services/Service.html | 599 -- .../samples/services/whatisneeded.html | 236 - .../documentation/_build/html/genindex.html | 1309 --- server/documentation/_build/html/index.html | 259 - .../_build/html/intro/install.html | 168 - .../_build/html/intro/overview.html | 147 - server/documentation/_build/html/objects.inv | Bin 2556 -> 0 bytes .../_build/html/py-modindex.html | 140 - server/documentation/_build/html/search.html | 106 - .../documentation/_build/html/searchindex.js | 1 - .../_downloads/samples/auths/SampleAuth.py | 307 - .../_downloads/samples/auths/__init__.py | 40 - .../_downloads/samples/auths/auth.png | Bin 1225 -> 0 bytes .../samples/services/SampleProvider.py | 196 - .../samples/services/SamplePublication.py | 272 - .../samples/services/SampleService.py | 236 - .../services/SampleUserDeploymentOne.py | 373 - .../services/SampleUserDeploymentTwo.py | 469 - .../_downloads/samples/services/__init__.py | 44 - .../_downloads/samples/services/provider.png | Bin 491 -> 0 bytes .../_downloads/samples/services/service.png | Bin 578 -> 0 bytes server/documentation/_images/LogoUDS.png | Bin 9441 -> 0 bytes server/documentation/api/index.rst | 9 - server/documentation/api/models.rst | 24 - .../api/models/authentication.rst | 25 - server/documentation/api/models/other.rst | 41 - server/documentation/api/models/services.rst | 33 - server/documentation/api/models/transport.rst | 18 - server/documentation/api/modules.rst | 18 - .../api/modules/AuthenticatorModule.rst | 27 - .../documentation/api/modules/BaseModule.rst | 53 - .../documentation/api/modules/FormFields.rst | 33 - .../api/modules/ServiceModules.rst | 53 - .../api/modules/auths/Authenticator.rst | 15 - .../api/modules/services/Exceptions.rst | 9 - .../api/modules/services/Provider.rst | 27 - .../api/modules/services/Publication.rst | 30 - .../api/modules/services/Service.rst | 25 - .../api/modules/services/UserDeployment.rst | 23 - server/documentation/conf.py | 258 - .../development/architecture.rst | 36 - .../development/contributing.rst | 3 - .../documentation/development/repository.rst | 3 - .../samples/auths/Authenticator.rst | 15 - .../development/samples/samples.rst | 100 - .../samples/services/DeployedServiceOne.rst | 20 - .../samples/services/DeployedServiceTwo.rst | 20 - .../development/samples/services/Provider.rst | 19 - .../samples/services/Publication.rst | 23 - .../development/samples/services/Service.rst | 15 - .../samples/services/whatisneeded.rst | 32 - server/documentation/index.rst | 71 - server/documentation/intro/install.rst | 46 - server/documentation/intro/overview.rst | 31 - server/documentation/make.bat | 190 - server/samples/sample_output_REST3.txt | 2 +- server/src/uds/auths/Sample/SampleAuth.py | 3 +- server/src/uds/core/auths/auth.py | 4 +- server/src/uds/core/auths/authenticator.py | 6 +- server/src/uds/core/util/calendar/__init__.py | 23 +- server/src/uds/models/calendar_rule.py | 41 +- server/src/uds/web/views/auth.py | 4 +- 188 files changed, 37 insertions(+), 34824 deletions(-) delete mode 100644 server/documentation/Makefile delete mode 100644 server/documentation/_build/doctrees/api/index.doctree delete mode 100644 server/documentation/_build/doctrees/api/models.doctree delete mode 100644 server/documentation/_build/doctrees/api/models/authentication.doctree delete mode 100644 server/documentation/_build/doctrees/api/models/other.doctree delete mode 100644 server/documentation/_build/doctrees/api/models/services.doctree delete mode 100644 server/documentation/_build/doctrees/api/models/transport.doctree delete mode 100644 server/documentation/_build/doctrees/api/modules.doctree delete mode 100644 server/documentation/_build/doctrees/api/modules/AuthenticatorModule.doctree delete mode 100644 server/documentation/_build/doctrees/api/modules/BaseModule.doctree delete mode 100644 server/documentation/_build/doctrees/api/modules/FormFields.doctree delete mode 100644 server/documentation/_build/doctrees/api/modules/ServiceModules.doctree delete mode 100644 server/documentation/_build/doctrees/api/modules/auths/Authenticator.doctree delete mode 100644 server/documentation/_build/doctrees/api/modules/services/Exceptions.doctree delete mode 100644 server/documentation/_build/doctrees/api/modules/services/Provider.doctree delete mode 100644 server/documentation/_build/doctrees/api/modules/services/Publication.doctree delete mode 100644 server/documentation/_build/doctrees/api/modules/services/Service.doctree delete mode 100644 server/documentation/_build/doctrees/api/modules/services/UserDeployment.doctree delete mode 100644 server/documentation/_build/doctrees/development/architecture.doctree delete mode 100644 server/documentation/_build/doctrees/development/contributing.doctree delete mode 100644 server/documentation/_build/doctrees/development/repository.doctree delete mode 100644 server/documentation/_build/doctrees/development/samples/auths/Authenticator.doctree delete mode 100644 server/documentation/_build/doctrees/development/samples/samples.doctree delete mode 100644 server/documentation/_build/doctrees/development/samples/services/DeployedServiceOne.doctree delete mode 100644 server/documentation/_build/doctrees/development/samples/services/DeployedServiceTwo.doctree delete mode 100644 server/documentation/_build/doctrees/development/samples/services/Provider.doctree delete mode 100644 server/documentation/_build/doctrees/development/samples/services/Publication.doctree delete mode 100644 server/documentation/_build/doctrees/development/samples/services/Service.doctree delete mode 100644 server/documentation/_build/doctrees/development/samples/services/whatisneeded.doctree delete mode 100644 server/documentation/_build/doctrees/environment.pickle delete mode 100644 server/documentation/_build/doctrees/index.doctree delete mode 100644 server/documentation/_build/doctrees/intro/install.doctree delete mode 100644 server/documentation/_build/doctrees/intro/overview.doctree delete mode 100644 server/documentation/_build/html/.buildinfo delete mode 100644 server/documentation/_build/html/_downloads/SampleAuth.py delete mode 100644 server/documentation/_build/html/_downloads/SampleProvider.py delete mode 100644 server/documentation/_build/html/_downloads/SamplePublication.py delete mode 100644 server/documentation/_build/html/_downloads/SampleService.py delete mode 100644 server/documentation/_build/html/_downloads/SampleUserDeploymentOne.py delete mode 100644 server/documentation/_build/html/_downloads/SampleUserDeploymentTwo.py delete mode 100644 server/documentation/_build/html/_downloads/__init__.py delete mode 100644 server/documentation/_build/html/_modules/index.html delete mode 100644 server/documentation/_build/html/_modules/uds/core.html delete mode 100644 server/documentation/_build/html/_modules/uds/core/auths.html delete mode 100644 server/documentation/_build/html/_modules/uds/core/services.html delete mode 100644 server/documentation/_build/html/_modules/uds/core/services/Exceptions.html delete mode 100644 server/documentation/_build/html/_modules/uds/core/ui/UserInterface.html delete mode 100644 server/documentation/_build/html/_modules/uds/models.html delete mode 100644 server/documentation/_build/html/_sources/api/index.txt delete mode 100644 server/documentation/_build/html/_sources/api/models.txt delete mode 100644 server/documentation/_build/html/_sources/api/models/authentication.txt delete mode 100644 server/documentation/_build/html/_sources/api/models/other.txt delete mode 100644 server/documentation/_build/html/_sources/api/models/services.txt delete mode 100644 server/documentation/_build/html/_sources/api/models/transport.txt delete mode 100644 server/documentation/_build/html/_sources/api/modules.txt delete mode 100644 server/documentation/_build/html/_sources/api/modules/AuthenticatorModule.txt delete mode 100644 server/documentation/_build/html/_sources/api/modules/BaseModule.txt delete mode 100644 server/documentation/_build/html/_sources/api/modules/FormFields.txt delete mode 100644 server/documentation/_build/html/_sources/api/modules/ServiceModules.txt delete mode 100644 server/documentation/_build/html/_sources/api/modules/auths/Authenticator.txt delete mode 100644 server/documentation/_build/html/_sources/api/modules/services/Exceptions.txt delete mode 100644 server/documentation/_build/html/_sources/api/modules/services/Provider.txt delete mode 100644 server/documentation/_build/html/_sources/api/modules/services/Publication.txt delete mode 100644 server/documentation/_build/html/_sources/api/modules/services/Service.txt delete mode 100644 server/documentation/_build/html/_sources/api/modules/services/UserDeployment.txt delete mode 100644 server/documentation/_build/html/_sources/development/architecture.txt delete mode 100644 server/documentation/_build/html/_sources/development/contributing.txt delete mode 100644 server/documentation/_build/html/_sources/development/repository.txt delete mode 100644 server/documentation/_build/html/_sources/development/samples/auths/Authenticator.txt delete mode 100644 server/documentation/_build/html/_sources/development/samples/samples.txt delete mode 100644 server/documentation/_build/html/_sources/development/samples/services/DeployedServiceOne.txt delete mode 100644 server/documentation/_build/html/_sources/development/samples/services/DeployedServiceTwo.txt delete mode 100644 server/documentation/_build/html/_sources/development/samples/services/Provider.txt delete mode 100644 server/documentation/_build/html/_sources/development/samples/services/Publication.txt delete mode 100644 server/documentation/_build/html/_sources/development/samples/services/Service.txt delete mode 100644 server/documentation/_build/html/_sources/development/samples/services/whatisneeded.txt delete mode 100644 server/documentation/_build/html/_sources/index.txt delete mode 100644 server/documentation/_build/html/_sources/intro/install.txt delete mode 100644 server/documentation/_build/html/_sources/intro/overview.txt delete mode 100644 server/documentation/_build/html/_static/ajax-loader.gif delete mode 100644 server/documentation/_build/html/_static/basic.css delete mode 100644 server/documentation/_build/html/_static/comment-bright.png delete mode 100644 server/documentation/_build/html/_static/comment-close.png delete mode 100644 server/documentation/_build/html/_static/comment.png delete mode 100644 server/documentation/_build/html/_static/contents.png delete mode 100644 server/documentation/_build/html/_static/doctools.js delete mode 100644 server/documentation/_build/html/_static/down-pressed.png delete mode 100644 server/documentation/_build/html/_static/down.png delete mode 100644 server/documentation/_build/html/_static/file.png delete mode 100644 server/documentation/_build/html/_static/jquery.js delete mode 100644 server/documentation/_build/html/_static/minus.png delete mode 100644 server/documentation/_build/html/_static/navigation.png delete mode 100644 server/documentation/_build/html/_static/plus.png delete mode 100644 server/documentation/_build/html/_static/pygments.css delete mode 100644 server/documentation/_build/html/_static/searchtools.js delete mode 100644 server/documentation/_build/html/_static/sphinxdoc.css delete mode 100644 server/documentation/_build/html/_static/underscore.js delete mode 100644 server/documentation/_build/html/_static/up-pressed.png delete mode 100644 server/documentation/_build/html/_static/up.png delete mode 100644 server/documentation/_build/html/_static/websupport.js delete mode 100644 server/documentation/_build/html/api/index.html delete mode 100644 server/documentation/_build/html/api/models.html delete mode 100644 server/documentation/_build/html/api/models/authentication.html delete mode 100644 server/documentation/_build/html/api/models/other.html delete mode 100644 server/documentation/_build/html/api/models/services.html delete mode 100644 server/documentation/_build/html/api/models/transport.html delete mode 100644 server/documentation/_build/html/api/modules.html delete mode 100644 server/documentation/_build/html/api/modules/AuthenticatorModule.html delete mode 100644 server/documentation/_build/html/api/modules/BaseModule.html delete mode 100644 server/documentation/_build/html/api/modules/FormFields.html delete mode 100644 server/documentation/_build/html/api/modules/ServiceModules.html delete mode 100644 server/documentation/_build/html/api/modules/auths/Authenticator.html delete mode 100644 server/documentation/_build/html/api/modules/services/Exceptions.html delete mode 100644 server/documentation/_build/html/api/modules/services/Provider.html delete mode 100644 server/documentation/_build/html/api/modules/services/Publication.html delete mode 100644 server/documentation/_build/html/api/modules/services/Service.html delete mode 100644 server/documentation/_build/html/api/modules/services/UserDeployment.html delete mode 100644 server/documentation/_build/html/development/architecture.html delete mode 100644 server/documentation/_build/html/development/contributing.html delete mode 100644 server/documentation/_build/html/development/repository.html delete mode 100644 server/documentation/_build/html/development/samples/auths/Authenticator.html delete mode 100644 server/documentation/_build/html/development/samples/samples.html delete mode 100644 server/documentation/_build/html/development/samples/services/DeployedServiceOne.html delete mode 100644 server/documentation/_build/html/development/samples/services/DeployedServiceTwo.html delete mode 100644 server/documentation/_build/html/development/samples/services/Provider.html delete mode 100644 server/documentation/_build/html/development/samples/services/Publication.html delete mode 100644 server/documentation/_build/html/development/samples/services/Service.html delete mode 100644 server/documentation/_build/html/development/samples/services/whatisneeded.html delete mode 100644 server/documentation/_build/html/genindex.html delete mode 100644 server/documentation/_build/html/index.html delete mode 100644 server/documentation/_build/html/intro/install.html delete mode 100644 server/documentation/_build/html/intro/overview.html delete mode 100644 server/documentation/_build/html/objects.inv delete mode 100644 server/documentation/_build/html/py-modindex.html delete mode 100644 server/documentation/_build/html/search.html delete mode 100644 server/documentation/_build/html/searchindex.js delete mode 100644 server/documentation/_downloads/samples/auths/SampleAuth.py delete mode 100644 server/documentation/_downloads/samples/auths/__init__.py delete mode 100644 server/documentation/_downloads/samples/auths/auth.png delete mode 100644 server/documentation/_downloads/samples/services/SampleProvider.py delete mode 100644 server/documentation/_downloads/samples/services/SamplePublication.py delete mode 100644 server/documentation/_downloads/samples/services/SampleService.py delete mode 100644 server/documentation/_downloads/samples/services/SampleUserDeploymentOne.py delete mode 100644 server/documentation/_downloads/samples/services/SampleUserDeploymentTwo.py delete mode 100644 server/documentation/_downloads/samples/services/__init__.py delete mode 100644 server/documentation/_downloads/samples/services/provider.png delete mode 100644 server/documentation/_downloads/samples/services/service.png delete mode 100644 server/documentation/_images/LogoUDS.png delete mode 100644 server/documentation/api/index.rst delete mode 100644 server/documentation/api/models.rst delete mode 100644 server/documentation/api/models/authentication.rst delete mode 100644 server/documentation/api/models/other.rst delete mode 100644 server/documentation/api/models/services.rst delete mode 100644 server/documentation/api/models/transport.rst delete mode 100644 server/documentation/api/modules.rst delete mode 100644 server/documentation/api/modules/AuthenticatorModule.rst delete mode 100644 server/documentation/api/modules/BaseModule.rst delete mode 100644 server/documentation/api/modules/FormFields.rst delete mode 100644 server/documentation/api/modules/ServiceModules.rst delete mode 100644 server/documentation/api/modules/auths/Authenticator.rst delete mode 100644 server/documentation/api/modules/services/Exceptions.rst delete mode 100644 server/documentation/api/modules/services/Provider.rst delete mode 100644 server/documentation/api/modules/services/Publication.rst delete mode 100644 server/documentation/api/modules/services/Service.rst delete mode 100644 server/documentation/api/modules/services/UserDeployment.rst delete mode 100644 server/documentation/conf.py delete mode 100644 server/documentation/development/architecture.rst delete mode 100644 server/documentation/development/contributing.rst delete mode 100644 server/documentation/development/repository.rst delete mode 100644 server/documentation/development/samples/auths/Authenticator.rst delete mode 100644 server/documentation/development/samples/samples.rst delete mode 100644 server/documentation/development/samples/services/DeployedServiceOne.rst delete mode 100644 server/documentation/development/samples/services/DeployedServiceTwo.rst delete mode 100644 server/documentation/development/samples/services/Provider.rst delete mode 100644 server/documentation/development/samples/services/Publication.rst delete mode 100644 server/documentation/development/samples/services/Service.rst delete mode 100644 server/documentation/development/samples/services/whatisneeded.rst delete mode 100644 server/documentation/index.rst delete mode 100644 server/documentation/intro/install.rst delete mode 100644 server/documentation/intro/overview.rst delete mode 100644 server/documentation/make.bat diff --git a/server/documentation/Makefile b/server/documentation/Makefile deleted file mode 100644 index 8cbfba74..00000000 --- a/server/documentation/Makefile +++ /dev/null @@ -1,153 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = a4 -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/UDS.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/UDS.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/UDS" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/UDS" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." diff --git a/server/documentation/_build/doctrees/api/index.doctree b/server/documentation/_build/doctrees/api/index.doctree deleted file mode 100644 index 7b7d6406ca6046f1448e6da5d2921eb8602768d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2936 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 diff --git a/server/documentation/_build/doctrees/api/models/services.doctree b/server/documentation/_build/doctrees/api/models/services.doctree deleted file mode 100644 index ae1c2d680fa7890ce2a96746915d21285a44fbf2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141396 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 R%eO~+g#JCFf2581e*vc>7?S`1 diff --git a/server/documentation/_build/doctrees/api/modules/AuthenticatorModule.doctree b/server/documentation/_build/doctrees/api/modules/AuthenticatorModule.doctree deleted file mode 100644 index 7080a1a352b0958b018814d192976a54d23995c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6463 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%0Dh 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 z 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

Tx8E^( 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 diff --git a/server/documentation/_build/doctrees/api/modules/auths/Authenticator.doctree b/server/documentation/_build/doctrees/api/modules/auths/Authenticator.doctree deleted file mode 100644 index 851ee5bbbe3d521db4fd2619d50e0db168209816..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131457 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 OcKC=~1-~OJJN^$*jL)9{ diff --git a/server/documentation/_build/doctrees/api/modules/services/Exceptions.doctree b/server/documentation/_build/doctrees/api/modules/services/Exceptions.doctree deleted file mode 100644 index 248ac97e0e3df1457a7b20faf6de3bf3e7c28b5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17026 zcmd5^34A0)^h;>+b2t z<*V~fC0`5uVlY;&IBt;Q%aU6TQ)-{ByVYu~){IzvWxM2tb5%D`Yqjbc$sD(8)vB5k zjO8ojjs-65^7C#mcKU4It%iQ39E_b^-enhk=OQDj3sm=fW_-D}=T}{_*-WEZ&wOSh znngXO-Fio=cOrAlat5t(P^(re6uM5sWZ!(|=;a!o=2nZ9Irc`QU1~lvx?H;pYLi7j z@EVQQ&1X(nuF-k+Y~-%sLf6iFNwEF%nQhCpKh-Yh-D0E9f%%%XZ%~^ILO;X=SIRlZ zoeI>TR_m?7s!f5LE4e{nPh(a$WYxabV7^9#vF3tGjqgq4t}wHrlnY zGF7RBnz2#0F=GdLefUe^Zyo;n z@i*WN)U4jT=NBFHuO5(94{VOgz|HdzQtCkn%1v4wjG!cYCPF%7t+Ki?B!E}L-fF8m zs^8pfhTJOE%6=Y^o>J+I1)q+4m6AK|>@3+q=+bzVDh2cvj902|86iH-|Kc?vju^MA z{&=b4)QWB}9*r*;ulqe1qaaj=T(w(m(dy7it0%Ol**)qot0x+TI^0UxVMzXDErjzQ ztkn@CRJIv~mX6kqkpdU8kjby#8S?|cKcU0CJ&DK2h?L|GF(A?q0?kqNy?VWl#5gvQE zRwn_7$2}ffo3v|_%|`N-QngYmJ1O-D06$r)M?&9Pl|a}VtEf{Le1Hvu#ykS zbw_8&u40c-r`n64cgN6A%Li4@FVBwIj$<~(sAWo>j$Y5u>dd&;lOwlTW?(}R- zXSr6IbjfwpIXhNa1AaMQtU0ddI}Rdz$AUMU*^J;@CY024!tcDh)Z zR1*vAaJb$0e-r_O&?g@ObADD`V0B0RJZ8b_k9wZ+5w7aOth&hRE!ndUHfm2@e9nFN zkEg8*LDJUYSmVQkQpn_CyW0Uqy89`8iw ziNlRXKBbCqLP@J~!U-O_x7M;)Re0K}BOsTGnMbu?bvu=k?Uxm0R-^OkT+5tRCJTI@ zqJm5x6zZ&_LTrgJDzcgvCeW!}BQ0^os=2_&z8%&Go8%0D&T2IWpk4ucO=)rPKM9xz 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 J9BY$f{{{^>U>g7c diff --git a/server/documentation/_build/doctrees/api/modules/services/Provider.doctree b/server/documentation/_build/doctrees/api/modules/services/Provider.doctree deleted file mode 100644 index 9cf1e234d89f433503065aa24bf6cc351a9b2ab4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19780 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 bd6WX^0L{m*F^9VbTCxBSJ}ty=V=()FydtmZ diff --git a/server/documentation/_build/doctrees/api/modules/services/Service.doctree b/server/documentation/_build/doctrees/api/modules/services/Service.doctree deleted file mode 100644 index 28180d610487d64191809c3e4c11f0bbad3d652d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22870 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 diff --git a/server/documentation/_build/doctrees/api/modules/services/UserDeployment.doctree b/server/documentation/_build/doctrees/api/modules/services/UserDeployment.doctree deleted file mode 100644 index e8e38a9ff06384def6f81a011be0203c82b240a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92613 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 Bhj{=1 diff --git a/server/documentation/_build/doctrees/development/architecture.doctree b/server/documentation/_build/doctrees/development/architecture.doctree deleted file mode 100644 index 76cc7a8fd287e3b628c396df74a9fcb8028b2ee0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9732 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 RZ<=)C!kYi5;(yET(toy=w$uOs diff --git a/server/documentation/_build/doctrees/development/repository.doctree b/server/documentation/_build/doctrees/development/repository.doctree deleted file mode 100644 index c354c925da660d97b7bbe2bb36aeceb6ea1a5cef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2525 zcmb_eX?NR16it&lv7N+8+jN06bT271ae)G5-%43h1hjpnEJBQ>u}6)h(VH1%0R$~j zNZ9v%`>DK<80q;$23*(e$CxLkj@wRL$H5$j zW}%j_n48sxB~_M$KG9akTdtfZQkp`>ycsOUOdGD6sghTzmTt-Gj7%{A4o5mR!DZ%4yP-n)du$392^gxaWXQ3Ko zsXeFhkP9Pz#I&Zr54%upF@I6nfgEvR$Z~ho#baWUL8W{CxQn-oVV1%6C`>rcE)3CS zr4sOj7!<_g9sLB*s3U6qPGa$7j&rkOPoWGrd-33fO=ZlBy<$r26VqY_D#at%6omKG ztT^O~!>%~uileSL?q-6@in7>U{lzZv71HG0|5o81BIhYa!;YI2Sv>uSi;u!o z-*K<_>M<7|hngRnV$vF)aPdjo9*p&*UvT{tDSZRsrb*7a__T$UN<~t_a}HF)pmf1A z14EP=zPHObr_^g@CMWZMqV*2PSLdp3vRv0 zIuPGnpt(>Nw7-(>2J&bj2^N|1z*`Fy7%xGT#$t|WI=einkEjTyG*I`CxCe6%$-Pxv{L~Qs5I|PYF zn`E)KVg-(ZMlum(aq4YIN@GY|k(tA!Ez4t9=~!c#sl)=NyEuz+(ShBT_jVW+L-P!e z39sQ8L6yFkJ9g@HfHCagD06-);$BFyRSAnU zW@IPJ31v~SY|4(8)?u`}$UQ4wTqc-SqFYq9LM8f$$5p6gragBC--demxYhGJ^mLeP z9TC0@wc_NQCK7U(@PbgY7ExL9@}2`VGH^--!xem=_EOETmbV-RM&PvtO39mbgx8@0 zm(Ee?4`8Ghk{`nP|21Mhf(cp)hE}U}77=dn#v0T*JmHkXQsKwcXd$OffbHBeH{*zZeLzro=;bekV)Zo3cDtq)J^=Zv{%f@fW z8s&rv;cNWX#qVHGVS+HxTovy!Jh7t;@cT6wr8fmKX7}?Cb`cl+Y^>8Cova1B`val- z_VUxhKsSAV&hZy9DW)`Ob?ZA*H-di6@i#F;Q9&vBdy$fqj}+YHn+PQ-r6%Pi)Ot%< V;~y^m3By)g6z+fJ_;=Qt{|EOmyelxap>w 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 diff --git a/server/documentation/_build/doctrees/development/samples/samples.doctree b/server/documentation/_build/doctrees/development/samples/samples.doctree deleted file mode 100644 index 71dcf9f801b15b379c92630551d50d9b5c0dc3a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18001 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 E0TteK^#A|> diff --git a/server/documentation/_build/doctrees/development/samples/services/Provider.doctree b/server/documentation/_build/doctrees/development/samples/services/Provider.doctree deleted file mode 100644 index b7d536d7d525a195880fc41834dd8bf4083f77ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22830 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 bLT005^&flcKl!9SIt=%}hU&l5cKLq*x#zO~ diff --git a/server/documentation/_build/doctrees/development/samples/services/Publication.doctree b/server/documentation/_build/doctrees/development/samples/services/Publication.doctree deleted file mode 100644 index 83c7621d07c71ae6096c22bdb614f2978f11ea2a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28313 zcmeHQ`F|V7byw`@f^At=>^QCCW=tg(s8FEf#!bw`NgxuEP*I>lV0FY{pe1&|U30OE z*;$CBQ?yCjv{vu?zVD`Y)BA4I^uF)=`b+wKZ)Oibv=aZ&{Ll~l`B((7vv1zK`@MNP z`{Da~Ufdg{L8xm{>`7gruLBvS74@3=kEr{`>i(*8G;#+r-5W}+UOQF?Z=5)A;DB}q z!%&LhXfq6YZW_dqI@Hq6BYL!{(;x-NIO=+`uhrqPI^rA~x`~$Efz;aF0-U28s^T2$ zjgka&b#**SdQv^maw?we#fgFUV9Pn-j?%av$7vL&va3@!N!3G_U*jAmi~>)qV`KHO zf5WyJL}gy>q}h1gwFd zdfdOyIb?r-!!(#g4wF$7^gzCf`m7rt1aTJqcpw+O?SZRPnJf;I_(ja67vrIfMxI`z z|1(1KS{FTeTZZwFD8Fddq8GJHZU;T77q1pXt|dBEpZ(E~s3*qijhoKl)ZHRds3)Dn zb~);EoQj*KNw7IeLFhM)m8d#LywQ-xY4y~GbGR3}TI2KFhI3@o?QJK-rjr}a{Y23> zZ>YEU$6e>38UOT#I^`d7N6u@*Ad;$j`F;SiGNR`F`+QLLbak30kbn@>cq<6IFji-( z{_9z2+II_0&41i~)PIBjg#V;-kZ)6qK9D|J^`F}C=QjM48~&R&{HHfYKIZoAjOV5& z?8se+>@%-4%jbe(ZyT#;frw8tE{rza(dIM|aNFHV+@W7lp9jp}K34A_%sp_lUY2wb zXyFQ`qDZ73#*q#-p$z>v5d(KSh_-Oqa!)`9KsZmhx7{FgX;>PIO0{j12iR0Wa=YQ-%ai08hRWgbZl8)R^TybGZB8f4*Fpj`NV6y3IDQ?>V12dqaW3eMe&y7S6t4XC;Ub`-O@i35D z^pkjiJ0Uy_q$WD_*P?_2yT&mvRp72dn8K*Mj0}M8CHZ< z^3rz#aADIRow|A(YZq>%WGZ>#JTyZlqg_p%FJ#hZL0sNX5RYVnxB@|(G5`My^Bd6g z3uASWG@S(Dy@jS<8mlI0`T)l9CRCV2Ub;GfOd5q{9U-SkG76m*JEVp|D!iEVh@_K$ z$@L$@yx1y!Wyg(Dx)HAPb^sVI)M5uJE^F%ZrzP_8eiHd`CXuU<$j>~IS3tSeSgjG| z2;oZw<*ts^`-pODpxlxd??hqjdP}!f>?dpC#Jd)|*+ql`Y?MkNf$^jz8(16ez5AA0 zpQcTFKiZtgXw&KGA?(_2&Go!2{4@A;5feznK0SDG2ZsIHSY4;J&;(blyFQWOR}5A+ z$XDI0I)`yTMT|F&V3pZ8^?v?+$4w&j!X4)*jd7DLnW_)mIEQhsdc_RFiwABHIR_|A zKoIi)VZJ*=R2rl&+Zf{M4d)PkM%J~*O zCny$jr-OHCiKXTQ12!T~aUO*n-#0*GlmKZA`#OW#2H2F!36Wg)DNT*m# z3Tb2G=5EFaTj1O+L6D;$TxWy;PGAgtb%@0hpz_4*n9Ep!B8Vn~flP>W`0s99FlUJ< z!s3FZdZV6k?f)0(5L<|VS;Wu55>cH0gAHENl6aiEm84-#Toue~w_bAMPG=cT8kdcS00Gkj- z10<027v#eI9#DlumO?Te_fr@qnM2EjO%G*{qzyMybheX_kVQt^w1y-ZvF==IwncmG zLg#vYy&>@V>iXKX=1OBloWChLml_BJuijj5UcA&1m)2HS8tZLQZ>`|hR%g9=-s!C2 zhq-zicg_(CbgkaHDH=Dft~c6kv9>OnSFWx$0S^sl`rP;c;AOJ(O z);eOfd8OIGu+G{7&kJC8-znBEh%1ftN7n+?GO?LtF)y38NdZ)SU ztk&1XRcHO`TDu`=ae%neY%j0Yn^zhuHQ<1GMdMnd)e-GW_0`pVmrE;{SnT-*P_3U| zWq3Rvmb=niZ!C9cUB#zmP!U+JE{OKk#&VNBG;TCNjQaY`1q-&_c%OqoxJby=uhcI# z+M@a?r~?iyJL`=rggEHYcFwmu&5qM)h>L4$D@=1hYd6-fHJ2OhcZ$_DV#EdEv>OYU zq*LeF0R>dUWi0T#({3{TnypS_ecid*X|A>A!SL%K&pHuqxsJPuwJTz+#TG4C5pfBZLnrl7C7iyXF>DS86CC$y%1h2s^eEE=`Rj z@U?bI37Z|uUn~mvIfZe~E_wEQ#SRVQtu0DVEA#;d?RjB;sR6fD{;k^Wl8Nhf=PMOc zH@GW|sFtvsU#gISB_h&a&J)dT+K+d%z(0tH%NZOzjg4u@&(cl&Pcwq~gRvufIC%qp z*ol*EP#Yze(Y(3Ce3zQtdWl!!QfJ!Dn+*& zL_yl^@{MN1(r|ByZd|%mW7M^O%V2re<(@Bl+suJm``?d}N`Tw*i~OM;>UhEUT7!qh z(pY(#ooTpqD;JP9d#vCk3S4UCF9tG0<$p@Np(F*K-qtLT=f_b$*czES0{kVsVBe)M zfNCEQ6%>l#tPnFuk3j_}7EwZj8b^eJCL(M?*)7*I3>)CeAi(gb!AtN|wjg5iB3};R z>CzokN*JbDC~~k6b=(5$W_k)$7vKuVhI|U;7qA9gCH@$3;?e+(n3xRJ$YN#&XD1UG zMR}$LL`Nu^1Sm=J62fqSR3wyC#pFo_DEj&+pHQ+l8X%;jZx&;cpR8Pi5}2(N@p3ti zWCUe-ImBNO3SkurY>;2z4V~0xO(?Az7ErvYMiLbhjsi-Y(-~bEgVQh=eUfhc9mZV1 zJ541Su%iGacO|OhsNEnAqLLohiD@fL5O63qvE`?1#YJ*m4dHiuY-1W~7}O6)MmN2Fu{5kqd!A*`f$n zTcX;QawuR^dt4HNFs8C3J#2Lb5*C*!%roIeuGP(Hl;q|LpcJGV>%oiQf373KEy)J# z6IhB|fJ7hc2@o(+0s!GBbH+$dny7qD1}Vnpwi}L^>ACVyvCAV-BuW4Y#Nabd&Cwe~o%;fSjCCRJlM$%9{q}&4wfh1~?Lo}SmFLU`% z9l)PsKJj$Sb>yZX0>!An4mEouB%oe3sL9&Yop2=Q&d$vn8=3h61~f4NhCM4zE{S%w zG!iT_pcbM2w4)foV3GNpK!M@%KPXrOH6%%Fd8%55ed~|NPG@+~XDcD(3XA~4iUiT^ zcpH$R(g5U+!ZddU#A+^@vT7TarD6+#xaNro z5B;|0%~(ZV5N497>yzHY(w5+4#9#q7$!G3*p;M6;8lqX41ztq|8b=Rc^eKp4YJvj7 z*<6Du(oiH^Jta6(qUj@QeWRs>rfaaSrC6Yzh1A% z@u9QhQ#Gn&xM`J9Flf@^Aq*OPqhD)mrmM8};`$`GYh?TMBtU{NU))fT3t;Km3uiZS z?w0A7T|PH`*$@+#5y?~;!ZRBsy5_{S5!}5bq--8w7BkDR+s3eA(oGlq=v8mWZX(*4-OfUe9sO--IKn9$AcNJ*o@Lb-M z&q6g5qDkPgg;Eml5OBCkl}mW;M1mp4Y>-Xnl%aN^*=n{gp)`@h%s&va#^-|arFG4l z5@NB>ZekuA8*rTzOrcmIL1eGv93Tt>2Sh*(l=EnB5Tr1HAFMjL9mj*Dms;zvAzeULquD%#+K*?DDIEsHo&SgJQnN&QG{%; z!KgF?r4DnXPD8L0s)g8^WgtKV4Nc@5VIFdbmd(JKfoR{DbP@#D@Z2nhG2(0at@(!z zA=0DDFqgB9|3`4l98Z0iSHuS#|Cmtpdgk72GJ{ENsFZ`8jF+(%>9$PAn2qs+cewRAm$##MCnvVGJm3S{XmXs>$u~0u4&fA)Ur-kSH!%l~V%aXm{CgQ!+m)6BkN`az7E7ENzUXT-j8iegiQEctsjpLZ%f zu(fBp-R5NzR*P@re<)upFu7Mku!e*@GsM;*u*uG2cFJI4g#1NQgOh93OTHThs1*j#n2d9083T@+2)i5u!@`0g`GpqrVF|tgX4uu)smM!BX>bwZ*i#AYDLJ=EEk9D7|K)5 zouS}D*c1es&3M_cLX>#1gTCUzKTXV%qg_@yyHkWJJi1l#5fiF-2Gzd&3bq}ytqBg& z83pzo9EpHpWT|M8Wf=MG`3G$0LFDdcWj+8}V34ZOAIkZm9?#8-=bsnPO{N!9=Am0X zwa%*nLsCiGUOO=P&pq|jQ)21Ne5r7cgKV-v} zM^sDBM znyY(3&>bO-NXS!)w^~p&FW5rRFwX(gE|CVeZ^`Ppv$n>@c#^QdnV{yn)^AX$^`0_A zdwXRuFg++#Uqb$G3bhpbQ6R>Kj%27$(Ui24AWGURSc}-icY!#9F50aEku!c;H}N8M zDY<>*v$?B*IF!6aL2J(7_N@D`-eXcb^Rb4>jI^O4hdM=toia=cd-9E2BZyYV=u4UR zR*}mlrIM4@TGM+GmDi1>+a<@ei8@JTTtxYs>o7*n_iF@O7_XMXb8;ZSnP8fT+0?Ic8nYS~oX&smuqa?V z1gd0|%+%C4rNP1>0u)CVo)4`eyqA|1PjX1+=ge}FnJ~XF(+diLRRtPTS~Y#aC;}@S zHXqD94d|Rx zA-1tXn6HK7B@`Q_vC;6FY@1Q-h6gv5?^4x>>Jeq&0GyZEDUD~$dDX-(Q|6H#3Oz{q zV2kour_nAJmk%-FC5I^p3c#`+l5K7U;EaeUn@O$>`OOCK0vsp`7l_LX=^9|?FhDOs zIU?iG5C+gN6OIp}Z>65m%_M?4%=bZWBI+}&%Up_C94{Z{E#AutOH6yD(ZhU=kT&wc zL>-F;D2U||8ExEHcJ$;!&cVBsE5NU02{Xfo9w9QAC&eZ53+N9Z$2}RPTinKMCL&PhG~QWQ;+MimAdLf}{W1bN9G z7%4+z?8!;O-kpbgZNVeoOQTphY<0$(<0^Zx99Mg>Gzp>|TS6*~F%gLyNw?q~v7rRa za|oqdt=k0h##P$FkjV-+5@F*IEs!Jzk+bo*t%) zVyzNtQFo5+4#FipMB9+ULyOcOK!rM$+Lm_v=;4h`G=abRM+;x=V+8cjoq62uvFtg4 z5jxOko#CeA7$$4h84lHgVI#Geb%xJ6!)Kl0v(E5YXE=5$(8$A`;AzWLcy{dAK84;6>Jqk)XtyAyi`TQxa8xz1bu;S>H|j*sGNDM$JxUUtTP;a1GCQXS!XyjBUg%9 zXE@o3a`(vo4X+c8(6i3)S!X!+T9i)3n01C5hdb*G&u#0hGaMqpy@V+G%{s&BiNRTC zI3HEOkEGI5P^B)=Ty18Z;poLi)AQs3EVIsV`>@fhGaQZRv(9j@$YHn`%B9g)-x;oM zJ1(+g)F;1f>KwT`2p)n3baD1Y}2jtAH3rLp>ua|9o$&0VW6 z7^|^!T<;AwTU)nt@FFwK&;Y^wUAOsJ_iP3JUZjfmYxCGG1&XhsF8# zT75^$IYv*&4ZG%W$5gBD1Rv9wrpU1QF6ST~rbzbGcjEy8JYhJ()1w&gN%cL>eRx~Z z_c}+Zl~AWRvO;|yVaT-YhIk@7RNsFYe8DPkhGNA0Qa^wfC*fqx)DHN;%Lko@EE4ur zKR?v+7hBF7`GLbOmd=N}cg6Y^t(Vb4{Af|Owi8B>IG4(Ted_oS- zyyfiMJoU5ABXSpK(1MKVNL$+c9B6aMoY|^=-twxKc5eqdz!TN#t8TlKpw=O`2y z&!O~#UG;mgOGi_8v%3>`sjoh9`G|9DQjXN`I|rT4g){F^pL7mqFZ22X=Yy~QS(Q)s zy$t*stUq)f#uG+#_%rDmo}Nk7AHD1xwNL+mnSYF>vw#&O{}U*a#<75DSB-E=fmVNd z$9a%MDcAo$bKYe2e`jY0Z`Ht2G!g4Ra9hMky{P`2j4lp3+3osx6GBLDLr{N#7i8hw zRrQz78z-qfrDT8Qf6O^X_OM$}_^+M&0#E%7kd1Np8Qz>_1>tY+I8PWgmZo)5g9oYK zg4A2pIW0$ z=do!A0rkOK*Z%qP0rP&ae;KQP^^g0HYRGQ+U2n!E{o7dmyZ8X>)qifN|Kj&^(Cf$kd#wIvv|0OKC98ji diff --git a/server/documentation/_build/doctrees/development/samples/services/Service.doctree b/server/documentation/_build/doctrees/development/samples/services/Service.doctree deleted file mode 100644 index 73216f79315044dbd685d8b59ee90a9c4fb03fe6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23643 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 OT_*iML;1gXxAuRu#e!J? diff --git a/server/documentation/_build/doctrees/development/samples/services/whatisneeded.doctree b/server/documentation/_build/doctrees/development/samples/services/whatisneeded.doctree deleted file mode 100644 index f68c8ab38d1efc760b41744decbcc2baf2a8dbd4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11743 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 Qb=Bi|iPbCc8+8i*2W@hDy8r+H diff --git a/server/documentation/_build/doctrees/environment.pickle b/server/documentation/_build/doctrees/environment.pickle deleted file mode 100644 index fb96b8b21f48f3ba86faba34166d4dba65b3d836..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1406907 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ⅅKKvf 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
iZ0L`2N#?65a|3uP?B>3EjS-j7 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 W;r(;WBCFvzj4DFN2*d_E%Kr~`vd%03 diff --git a/server/documentation/_build/doctrees/index.doctree b/server/documentation/_build/doctrees/index.doctree deleted file mode 100644 index 753a0ba32d4d6dbf5568f1f69e6f5813864f7ed1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16882 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 Njfa#zfX}3y{~ur7zM=pC diff --git a/server/documentation/_build/doctrees/intro/overview.doctree b/server/documentation/_build/doctrees/intro/overview.doctree deleted file mode 100644 index 20d0792595ff3296077d76b6c0233e8933e50b50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8591 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 Zh}QI@@!Opj;W}R5f|pDm$M1BZ@=Ys6sILG3 diff --git a/server/documentation/_build/html/.buildinfo b/server/documentation/_build/html/.buildinfo deleted file mode 100644 index 73828566..00000000 --- a/server/documentation/_build/html/.buildinfo +++ /dev/null @@ -1,4 +0,0 @@ -# Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: ecdf0c047589d7bf803c9f99cefd9819 -tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/server/documentation/_build/html/_downloads/SampleAuth.py b/server/documentation/_build/html/_downloads/SampleAuth.py deleted file mode 100644 index 7b3699b8..00000000 --- a/server/documentation/_build/html/_downloads/SampleAuth.py +++ /dev/null @@ -1,307 +0,0 @@ -# -*- coding: utf-8 -*- - -# -# Copyright (c) 2012 Virtual Cable S.L. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of Virtual Cable S.L. nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -''' -.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com -''' -from django.utils.translation import ugettext_noop as translatable -from uds.core.ui.UserInterface import gui -from uds.core import auths - -import logging - -logger = logging.getLogger(__name__) - -class SampleAuth(auths.Authenticator): - ''' - This class represents a sample authenticator. - - As this, it will provide: - * The authenticator functionality - * 3 Groups, "Mortals", "Gods" and "Daemons", just random group names selected.. :-), - plus groups that we enter at Authenticator form, from admin interface. - * Search of groups (inside the 3 groups used in this sample plus entered) - * Search for people (will return the search string + 000...999 as usernames) - * The Required form description for administration interface, so admins can create - new authenticators of this kind. - - In this sample, we will provide a simple standard auth, with owner drawn - login form that will simply show users that has been created and allow web user - to select one of them. - - For this class to get visible at administration client as a authenticator type, - we MUST register it at package __init__ - - :note: At class level, the translations must be simply marked as so - using ugettext_noop. This is done in this way because we will translate - the string when it is sent to the administration client. - ''' - - #: Name of type, used at administration interface to identify this - #: authenticator (i.e. LDAP, SAML, ...) - #: This string will be translated when provided to admin interface - #: using ugettext, so you can mark it as "translatable" at derived classes (using ugettext_noop) - #: if you want so it can be translated. - typeName = translatable('Sample Authenticator') - - #: Name of type used by Managers to identify this type of service - #: We could have used here the Class name, but we decided that the - #: module implementator will be the one that will provide a name that - #: will relation the class (type) and that name. - typeType = 'SampleAuthenticator' - - #: Description shown at administration level for this authenticator. - #: This string will be translated when provided to admin interface - #: using ugettext, so you can mark it as "translatable" at derived classes (using ugettext_noop) - #: if you want so it can be translated. - typeDescription = translatable('Sample dummy authenticator') - - - #: Icon file, used to represent this authenticator at administration interface - #: This file should be at same folder as this class is, except if you provide - #: your own :py:meth:uds.core.BaseModule.BaseModule.icon method. - iconFile = 'auth.png' - - #: Mark this authenticator as that the users comes from outside the UDS - #: database, that are most authenticator (except Internal DB) - #: True is the default value, so we do not need it in fact - # isExternalSource = True - - #: If we need to enter the password for this user when creating a new - #: user at administration interface. Used basically by internal authenticator. - #: False is the default value, so this is not needed in fact - #: needsPassword = False - - #: Label for username field, shown at administration interface user form. - userNameLabel = translatable('Fake User') - - # Label for group field, shown at administration interface user form. - groupNameLabel = translatable('Fake Group') - - #: Definition of this type of authenticator form - #: We will define a simple form where we will use a simple - #: list editor to allow entering a few group names - - groups = gui.EditableList(label=translatable('Groups'), values = ['Gods', 'Daemons', 'Mortals']) - - def initialize(self, values): - ''' - Simply check if we have - at least one group in the list - ''' - - # To avoid problems, we only check data if values are passed - # If values are not passed in, form data will only be available after - # unserialization, and at this point all will be default values - # so self.groups.value will be [] - if values is not None and len(self.groups.value) < 2: - raise auths.Authenticator.ValidationException(translatable('We need more that two items!')) - - def searchUsers(self, pattern): - ''' - Here we will receive a pattern for searching users. - - This method is invoked from interface, so an administrator can search users. - - If we do not provide this method, the authenticator will not provide search - facility for users. In our case, we will simply return a list of users - (array of dictionaries with ids and names) with the pattern plus 1..10 - ''' - return [ { 'id' : '{0}-{1}'.format(pattern, a), 'name' : '{0} number {1}'.format(pattern, a) } for a in range(1, 10)] - - def searchGroups(self, pattern): - ''' - Here we we will receive a patter for searching groups. - - In this sample, we will try to locate elements that where entered at - sample authenticator form (when created), and return the ones that - contains the pattern indicated. - ''' - pattern = pattern.lower() - res = [] - for g in self.groups.value: - if g.lower().find(pattern) != -1: - res.append({'id' : g, 'name' : ''}) - return res - - def authenticate(self, username, credentials, groupsManager): - ''' - This method is invoked by UDS whenever it needs an user to be authenticated. - It is used from web interface, but also from administration interface to - check credentials and access of user. - - The tricky part of this method is the groupsManager, but it's easy to - understand what is used it for. - - Imagine some authenticator, for example, an LDAP. It has its users, it has - its groups, and it has it relations (which user belongs to which group). - - Now think about UDS. UDS know nothing about this, it only knows what - the administator has entered at admin interface (groups mainly, but he can - create users also). - - UDS knows about this groups, but we need to relation those with the ones - know by the authenticator. - - To do this, we have created a simple mechanism, where the authenticator - receives a groupsManager, that knows all groups known by UDS, and has - the method so the authenticator can say, for the username being validated, - to which uds groups it belongs to. - - This is done using the :py:meth:uds.core.auths.GroupsManager.GroupsManager.validate - method of the provided groups manager. - - At return, UDS will do two things: - * If there is no group inside the groupsManager mareked as valid, it will - denied access. - * If there is some groups marked as valid, it will refresh the known - UDS relations (this means that the database will be refresehd so the user - has valid groups). - - This also means that the group membership is only checked at user login (well, - in fact its also checked when an administrator tries to modify an user) - - So, authenticate must not also validate the user credentials, but also - indicate the group membership of this user inside UDS. - - :note: groupsManager is an in/out parameter - ''' - if username != credentials: # All users with same username and password are allowed - return False - - # Now the tricky part. We will make this user belong to groups that contains at leat - # two letters equals to the groups names known by UDS - # For this, we will ask the groups manager for the groups names, and will check that and, - # if the user match this criteria, will mark that group as valid - for g in groupsManager.getGroupsNames(): - if len(set(g.lower()).intersection(username.lower())) >= 2: - groupsManager.validate(g) - - return True - - def getGroups(self, username, groupsManager): - ''' - As with authenticator part related to groupsManager, this - method will fill the groups to which the specified username belongs to. - - We have to fill up groupsManager from two different places, so it's not - a bad idea to make a method that get the "real" authenticator groups and - them simply call to :py:meth:uds.core.auths.GroupsManager.GroupsManager.validate - - In our case, we simply repeat the process that we also do at authenticate - ''' - for g in groupsManager.getGroupsNames(): - if len(set(g.lower()).intersection(username.lower())) >= 2: - groupsManager.validate(g) - - def getHtml(self, request): - ''' - If we override this method from the base one, we are telling UDS - that we want to draw our own authenticator. - - This way, we can do whataver we want here (for example redirect to a site - for a single sign on) generation our ouwn html (and javascript ofc). - - ''' - # Here there is a sample, commented out - # In this sample, we will make a list of valid users, and when clicked, - # it will fill up original form with username and same password, and submit it. - #res = '' - #for u in self.dbAuthenticator().users.all(): - # res += '{0}
'.format(u.name) - # - #res += '' - #return res - - # I know, this is a bit ugly, but this is just a sample :-) - - res = '

Login name:

' - res +='

Login

' - return res - - - def authCallback(self, parameters): - ''' - We provide this as a sample of callback for an user. - We will accept all petitions that has "user" parameter - - This method will get invoked by url redirections, probably by an SSO. - - The idea behind this is that we can provide: - * Simple user/password authentications - * Own authentications (not UDS, authenticator "owned"), but with no redirections - * Own authentications via redirections (as most SSO will do) - - Here, we will receive the parameters for this - ''' - user = parameters.get('user', None) - - return user - - def createUser(self, usrData): - ''' - This method provides a "check oportunity" to authenticators for users created - manually at administration interface. - - If we do not provide this method, the administration interface will not allow - to create new users "by hand", i mean, the "new" options from menus will dissapear. - - usrData is a dictionary that contains the input parameters from user, - with at least name, realName, comments, state & password. - - We can modify this parameters, we can modify ALL, but name is not recommended to - modify it unles you know what you are doing. - - Here, we will set the state to "Inactive" and realName to the same as username, but twice :-) - ''' - from uds.core.util.State import State - usrData['realName'] = usrData['name'] + ' ' + usrData['name'] - usrData['state'] = State.INACTIVE - - def modifyUser(self, usrData): - ''' - This method provides a "check opportunity" to authenticator for users modified - at administration interface. - - If we do not provide this method, nothing will happen (default one does nothing, but - it's valid). - - usrData is a dictionary that contains the input parameters from user, - with at least name, realName, comments, state & password. - - We can modify this parameters, we can modify ALL, but name is not recommended to - modify it unless you know what you are doing. - - Here, we will simply update the realName of the user, and (we have to take care - this this kind of things) modify the userName to a new one, the original plus '-1' - ''' - usrData['realName'] = usrData['name'] + ' ' + usrData['name'] - usrData['name'] = usrData['name'] + '-1' diff --git a/server/documentation/_build/html/_downloads/SampleProvider.py b/server/documentation/_build/html/_downloads/SampleProvider.py deleted file mode 100644 index 127c5220..00000000 --- a/server/documentation/_build/html/_downloads/SampleProvider.py +++ /dev/null @@ -1,196 +0,0 @@ -# -*- coding: utf-8 -*- - -# -# Copyright (c) 2012 Virtual Cable S.L. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of Virtual Cable S.L. nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -''' -Created on Jun 22, 2012 - -.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com -''' - -from django.utils.translation import ugettext_noop as translatable, ugettext as _ -from uds.core.services import ServiceProvider -from SampleService import ServiceOne, ServiceTwo -from uds.core.ui import gui - -import logging - -logger = logging.getLogger(__name__) - - -class Provider(ServiceProvider): - ''' - This class represents the sample services provider - - In this class we provide: - * The Provider functionality - * The basic configuration parameters for the provider - * The form fields needed by administrators to configure this provider - - :note: At class level, the translation must be simply marked as so - using ugettext_noop. This is so cause we will translate the string when - sent to the administration client. - - For this class to get visible at administration client as a provider type, - we MUST register it at package __init__. - - ''' - #: What kind of services we offer, this are classes inherited from Service - offers = [ServiceOne, ServiceTwo] - #: Name to show the administrator. This string will be translated BEFORE - #: sending it to administration interface, so don't forget to - #: mark it as translatable (using ugettext_noop) - typeName = translatable('Sample Provider') - #: Type used internally to identify this provider - typeType = 'SampleProvider' - #: Description shown at administration interface for this provider - typeDescription = translatable('Sample (and dummy) service provider') - #: Icon file used as icon for this provider. This string will be translated - #: BEFORE sending it to administration interface, so don't forget to - #: mark it as translatable (using ugettext_noop) - iconFile = 'provider.png' - - # now comes the form fields - # There is always two fields that are requested to the admin, that are: - # Service Name, that is a name that the admin uses to name this provider - # Description, that is a short description that the admin gives to this provider - # Now we are going to add a few fields that we need to use this provider - # Remember that these are "dummy" fields, that in fact are not required - # but used for sample purposes - # If we don't indicate an order, the output order of fields will be - # "random" - - #: Remote host. Here core will translate label and tooltip, remember to - #: mark them as translatable using ugettext_noop. - remoteHost = gui.TextField(oder=1, - length = 64, - label = translatable('Remote host'), - tooltip = translatable('This fields contains a remote host'), - required = True, - ) - #: Name of your pet (sample, not really needed :-) ) - petName = gui.TextField(order=2, - length = 32, - label = translatable('Your pet\'s name'), - tooltip = translatable('If you like, write the name of your pet'), - requred = False, - defvalue = 'Tux' #: This will not get translated - ) - #: Age of Methuselah (matusalén in spanish) - #: in Spain there is a well-known to say that something is very old, - #: "Tiene mas años que matusalén"(is older than Methuselah) - methAge = gui.NumericField(order = 3, - length = 4, # That is, max allowed value is 9999 - label = translatable('Age of Methuselah'), - tooltip = translatable('If you know it, please, tell me!!!'), - required = True, #: Numeric fields have always a value, so this not really needed - defvalue = '4500' - ) - - #: Is Methuselah istill alive? - methAlive = gui.CheckBoxField(order = 4, - label = translatable('Is Methuselah still alive?'), - tooltip = translatable('If you fail, this will not get saved :-)'), - required = True, #: Also means nothing. Check boxes has always a value - defvalue = gui.TRUE #: By default, at new item, check this - ) - - # There is more fields type, but not here the best place to cover it - def initialize(self, values = None): - ''' - We will use the "autosave" feature for form fields, that is more than - enought for most providers. (We simply need to store data provided by user - and, maybe, initialize some kind of connection with this values). - - Normally provider values are rally used at sevice level, cause we never - instantiate nothing except a service from a provider. - ''' - - # If you say meth is alive, you are wrong!!! (i guess..) - # values are only passed from administration client. Internals - # instantiations are always empty. - if values is not None and self.methAlive.isTrue(): - raise ServiceProvider.ValidationException(_('Methuselah is not alive!!! :-)')) - - # Marshal and unmarshal are defaults ones, also enought - - # As we use "autosave" fields feature, dictValues is also provided by - # base class so we don't have to mess with all those things... - - @staticmethod - def test(env, data): - ''' - Create your test method here so the admin can push the "check" button - and this gets executed. - Args: - env: environment passed for testing (temporal environment passed) - - data: data passed for testing (data obtained from the form - definition) - - Returns: - Array of two elements, first is True of False, depending on test - (True is all right, false is error), - second is an String with error, preferably internacionalizated.. - - In this case, wi well do nothing more that use the provider params - - Note also that this is an static method, that will be invoked using - the admin user provided data via administration client, and a temporary - environment that will be erased after invoking this method - ''' - try: - # We instantiate the provider, but this may fail... - instance = Provider(env, data) - logger.debug('Methuselah has {0} years and is {1} :-)' - .format(instance.methAge.value, instance.methAlive.value)) - except ServiceProvider.ValidationException as e: - # If we say that meth is alive, instantiation will - return [False, str(e)] - except Exception as e: - logger.exception("Exception caugth!!!") - return [False, str(e)] - return [True, _('Nothing tested, but all went fine..')] - - # Congratulations!!!, the needed part of your first simple provider is done! - # Now you can go to administration panel, and check it - # - # From now onwards, we implement our own methods, that will be used by, - # for example, services derived from this provider - def host(self): - ''' - Sample method, in fact in this we just return - the value of host field, that is an string - ''' - return self.remoteHost.value - - - def methYears(self): - ''' - Another sample return, it will in fact return the Methuselah years - ''' diff --git a/server/documentation/_build/html/_downloads/SamplePublication.py b/server/documentation/_build/html/_downloads/SamplePublication.py deleted file mode 100644 index f9ccfd5b..00000000 --- a/server/documentation/_build/html/_downloads/SamplePublication.py +++ /dev/null @@ -1,272 +0,0 @@ -# -*- coding: utf-8 -*- - -# -# Copyright (c) 2012 Virtual Cable S.L. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of Virtual Cable S.L. nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -''' -.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com -''' - -from django.utils.translation import ugettext as _ -from uds.core.services import Publication -from uds.core.util.State import State -from datetime import datetime -import logging - -logger = logging.getLogger(__name__) - -class SamplePublication(Publication): - ''' - This class shows how a publication is developed. - - In order to a publication to work correctly, we must provide at least the - following methods: - * Of course, the __init__ - * :py:meth:`.publish` - * :py:meth:`.checkState` - * :py:meth:`.finish` - - Also, of course, methods from :py:class:`uds.core.Serializable.Serializable` - - - Publication do not have an configuration interface, all data contained - inside an instance of a Publication must be serialized if you want them between - method calls. - - It's not waranteed that the class will not be serialized/deserialized - between methods calls, so, first of all, implement the marshal and umnarshal - mehods needed by all serializable classes. - - Also a thing to note is that operations requested to Publications must be - *as fast as posible*. The operations executes in a separated thread, - and so it cant take a bit more time to execute, but it's recommended that - the operations executes as fast as posible, and, if it will take a long time, - split operation so we can keep track of state. - - This means that, if we have "slow" operations, we must - - We first of all declares an estimation of how long a publication will take. - This value is instance based, so if we override it in our class, the suggested - time could change. - - The class attribute that indicates this suggested time is "suggestedTime", and - it's expressed in seconds, (i.e. "suggestedTime = 10") - ''' - - suggestedTime = 5 #: Suggested recheck time if publication is unfinished in seconds - - def initialize(self): - ''' - This method will be invoked by default __init__ of base class, so it gives - us the oportunity to initialize whataver we need here. - - In our case, we setup a few attributes.. - ''' - - # We do not check anything at marshal method, so we ensure that - # default values are correctly handled by marshal. - self._name = 'test' - self._reason = '' # No error, no reason for it - self._number = 1 - - def marshal(self): - ''' - returns data from an instance of Sample Publication serialized - ''' - return '\t'.join( [self._name, self._reason, str(self._number)] ) - - def unmarshal(self, data): - ''' - deserializes the data and loads it inside instance. - ''' - logger.debug('Data: {0}'.format(data)) - vals = data.split('\t') - logger.debug('Values: {0}'.format(vals)) - self._name = vals[0] - self._reason = vals[1] - self._number = int(vals[2]) - - - def publish(self): - ''' - This method is invoked whenever the administrator requests a new publication. - - The method is not invoked directly (i mean, that the administration request - do no makes a call to this method), but a DelayedTask is saved witch will - initiate all publication stuff (and, of course, call this method). - - You MUST implement it, so the publication do really something. - All publications can be synchronous or asynchronous. - - The main difference between both is that first do whatever needed, (the - action must be fast enough to do not block core), returning State.FINISHED. - - The second (asynchronous) are publications that could block the core, so - it have to be done in more than one step. - - An example publication could be a copy of a virtual machine, where: - * First we invoke the copy operation to virtualization provider - * Second, we kept needed values inside instance so we can serialize - them whenever requested - * Returns an State.RUNNING, indicating the core that the publication - has started but has to finish sometime later. (We do no check - again the state and keep waiting here, because we will block the - core untill this operation is finished). - - In our example wi will simple assign a name, and set number to 5. We - will use this number later, to make a "delay" at check if the publication - has finished. (see method checkState) - - We also will make this publication an "stepped one", that is, it will not - finish at publish call but a later checkState call - - Take care with instantiating threads from here. Whenever a publish returns - "State.RUNNING", the core will recheck it later, but not using this instance - and maybe that even do not use this server. - - If you want to use threadings or somethin likt it, use DelayedTasks and - do not block it. You also musht provide the mechanism to allow those - DelayedTask to communicate with the publication. - - One sample could be, for example, to copy a bunch of files, but we know - that this copy can take a long time and don't want it to take make it - all here, but in a separate task. Now, do you remember that "environment" - that is unique for every instance?, well, we can create a delayed task, - and pass that environment (owned by this intance) as a mechanism for - informing when the task is finished. (We insert at delayed tasks queue - an instance, not a class itself, so we can instantiate a class and - store it at delayed task queue. - - Also note that, in that case, this class can also acomplish that by simply - using the suggestedTime attribute and the checkState method in most cases. - ''' - self._number = 5 - self._reason = '' - return State.RUNNING - - def checkState(self): - ''' - Our publish method will initiate publication, but will not finish it. - So in our sample, wi will only check if _number reaches 0, and if so - return that we have finished, else we will return that we are working - on it. - - One publish returns State.RUNNING, this task will get called untill - checkState returns State.FINISHED. - - Also, wi will make the publication fail one of every 10 calls to this - method. - - Note: Destroying an publication also makes use of this method, so you - must keep the info of that you are checking (publishing or destroying...) - In our case, destroy is 1-step action so this will no get called while - destroying... - ''' - import random - self._number -= 1 - # Serialization will take care of storing self._number - - # One of every 10 calls - if random.randint(0, 9) == 9: - self._reason = _('Random integer was 9!!! :-)') - return State.ERROR - - if self._number <= 0: - return State.FINISHED - else: - return State.RUNNING - - - def finish(self): - ''' - Invoked when Publication manager noticed that the publication has finished. - This give us the oportunity of cleaning up things (as stored vars, etc..), - or initialize variables that will be needed in a later phase (by deployed - services) - - Returned value, if any, is ignored - ''' - import string - import random - # Make simply a random string - self._name = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(10)) - - def reasonOfError(self): - ''' - If a publication produces an error, here we must notify the reason why - it happened. This will be called just after publish or checkState - if they return State.ERROR - - Returns an string, in our case, set at checkState - ''' - return self._reason - - def destroy(self): - ''' - This is called once a publication is no more needed. - - This method do whatever needed to clean up things, such as - removing created "external" data (environment gets cleaned by core), - etc.. - - The retunred value is the same as when publishing, State.RUNNING, - State.FINISHED or State.ERROR. - ''' - self._name = '' - self._reason = '' # In fact, this is not needed, but cleaning up things... :-) - - # We do not do anything else to destroy this instance of publication - return State.FINISHED - - - def cancel(self): - ''' - Invoked for canceling the current operation. - This can be invoked directly by an administration or by the clean up - of the deployed service (indirectly). - When administrator requests it, the cancel is "delayed" and not - invoked directly. - - Also, take into account that cancel is the initiation of, maybe, a - multiple-step action, so it returns, as publish and destroy does. - - In our case, cancel simply invokes "destroy", that cleans up - things and returns that the action has finished in 1 step. - ''' - return self.destroy() - - # Here ends the publication needed methods. - # Methods provided below are specific for this publication - # and will be used by user deployments that uses this kind of publication - - def getBaseName(self): - ''' - This sample method (just for this sample publication), provides - the name generater for this publication. This is just a sample, and - this will do the work - ''' - return self._name diff --git a/server/documentation/_build/html/_downloads/SampleService.py b/server/documentation/_build/html/_downloads/SampleService.py deleted file mode 100644 index e38c96f6..00000000 --- a/server/documentation/_build/html/_downloads/SampleService.py +++ /dev/null @@ -1,236 +0,0 @@ -# -*- coding: utf-8 -*- - -# -# Copyright (c) 2012 Virtual Cable S.L. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of Virtual Cable S.L. nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -''' -.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com -''' - -from django.utils.translation import ugettext_noop as translatable, ugettext as _ -from uds.core.services import Service -from SamplePublication import SamplePublication -from SampleUserDeploymentOne import SampleUserDeploymentOne -from SampleUserDeploymentTwo import SampleUserDeploymentTwo - -from uds.core.ui import gui - -import logging - -logger = logging.getLogger(__name__) - -class ServiceOne(Service): - ''' - Basic service, the first part (variables) include the description of the service. - - Remember to fill all variables needed, but at least you must define: - * typeName - * typeType - * typeDescription - * iconFile (defaults to service.png) - * publicationType, type of publication in case it needs publication. - If this is not provided, core will assume that the service do not - needs publishing. - * deployedType, type of deployed user service. Do not forget this!!! - - The rest of them can be ommited, but its recommended that you fill all - declarations shown in this sample (that in fact, are all) - - This description informs the core what this service really provides, - and how this is done. Look at description of class variables for more - information. - - ''' - #: Name to show the administrator. This string will be translated BEFORE - #: sending it to administration interface, so don't forget to - #: mark it as translatable (using ugettext_noop) - typeName = translatable('Sample Service One') - #: Type used internally to identify this provider - typeType = 'SampleService1' - #: Description shown at administration interface for this provider - typeDescription = translatable('Sample (and dummy) service ONE') - #: Icon file used as icon for this provider. This string will be translated - #: BEFORE sending it to administration interface, so don't forget to - #: mark it as translatable (using ugettext_noop) - iconFile = 'service.png' - - # Functional related data - - #: If the service provides more than 1 "deployed user" (-1 = no limit, - #: 0 = ???? (do not use it!!!), N = max number to deploy - maxDeployed = -1 - #: If we need to generate "cache" for this service, so users can access the - #: provided services faster. Is usesCache is True, you will need also - #: set publicationType, do take care about that! - usesCache = False - #: Tooltip shown to user when this item is pointed at admin interface, none - #: because we don't use it - cacheTooltip = translatable('None') - #: If we need to generate a "Level 2" cache for this service (i.e., L1 - #: could be running machines and L2 suspended machines) - usesCache_L2 = False - #: Tooltip shown to user when this item is pointed at admin interface, None - #: also because we don't use it - cacheTooltip_L2 = translatable('None') - - #: If the service needs a s.o. manager (managers are related to agents - #: provided by services itselfs, i.e. virtual machines with actors) - needsManager = False - #: If true, the system can't do an automatic assignation of a deployed user - #: service from this service - mustAssignManually = False - - #: Types of publications (preparated data for deploys) - #: In our case, we do no need a publication, so this is None - publicationType = None - #: Types of deploys (services in cache and/or assigned to users) - deployedType = SampleUserDeploymentOne - - # Now the form part, this service will have only two "dummy" fields - # If we don't indicate an order, the output order of fields will be - # "random" - - colour = gui.ChoiceField(order = 1, - label = translatable('Colour'), - tooltip = translatable('Colour of the field'), - # In this case, the choice can have none value selected by default - required = True, - values = [ gui.choiceItem('red', 'Red'), - gui.choiceItem('green', 'Green'), - gui.choiceItem('blue', 'Blue'), - gui.choiceItem('nonsense', 'Blagenta') - ], - defvalue = '1' # Default value is the ID of the choicefield - ) - - passw = gui.PasswordField(order = 2, - label = translatable('Password'), - tooltip = translatable('Password for testing purposes'), - required = True, - defvalue = '1234' #: Default password are nonsense?? :-) - ) - - baseName = gui.TextField(order = 3, - label = translatable('Services names'), - tooltip = translatable('Base name for this user services'), - # In this case, the choice can have none value selected by default - required = True, - defvalue = '' # Default value is the ID of the choicefield - ) - - def initialize(self, values): - ''' - We check here form values to see if they are valid. - - Note that we check them throught FROM variables, that already has been - initialized by __init__ method of base class, before invoking this. - ''' - - # We don't need to check anything, bat because this is a sample, we do - # As in provider, we receive values only at new Service creation, - # so we only need to validate params if values is not None - if values is not None: - if self.colour.value == 'nonsense': - raise Service.ValidationException('The selected colour is invalid!!!') - - - # Services itself are non testeable right now, so we don't even have - # to provide one!!! - - - # Congratulations!!!, the needed part of your first simple service is done! - # Now you can go to administration panel, and check it - # - # From now onwards, we implement our own methods, that will be used by, - # for example, services derived from this provider - - def getColour(self): - ''' - Simply returns colour, for deployed user services. - - Remember that choiceField.value returns the id part of the ChoiceItem - ''' - return self.colour.value - - def getPassw(self): - ''' - Simply returns passwd, for deloyed user services - ''' - return self.passw.value - - def getBaseName(self): - ''' - ''' - return self.baseName.value - - - -class ServiceTwo(Service): - ''' - Just a second service, no comments here (almost same that ServiceOne - ''' - typeName = translatable('Sample Service Two') - typeType = 'SampleService2' - typeDescription = translatable('Sample (and dummy) service ONE+ONE') - iconFile = 'provider.png' #: We reuse provider icon here :-) - - # Functional related data - maxDeployed = 5 - usesCache = True - cacheTooltip = translatable('L1 cache for dummy elements') - usesCache_L2 = True - cacheTooltip_L2 = translatable('L2 cache for dummy elements') - - needsManager = False - mustAssignManually = False - - #: Types of publications. In this case, we will include a publication - #: type for this one - #: Note that this is a MUST if you indicate that needPublication - publicationType = SamplePublication - #: Types of deploys (services in cache and/or assigned to users) - deployedType = SampleUserDeploymentTwo - - - # Gui, we will use here the EditableList field - names = gui.EditableList(label=translatable('List of names')) - - def __init__(self, environment, parent, values = None): - ''' - We here can get a HUGE list from client. - Right now, this is treated same as other fields, in a near - future we will se how to handle this better - ''' - super(ServiceTwo, self).__init__(environment, parent, values) - - # No checks here - - def getNames(self): - ''' - For using at deployed services, really nothing - ''' - return self.names.value diff --git a/server/documentation/_build/html/_downloads/SampleUserDeploymentOne.py b/server/documentation/_build/html/_downloads/SampleUserDeploymentOne.py deleted file mode 100644 index e49d4a15..00000000 --- a/server/documentation/_build/html/_downloads/SampleUserDeploymentOne.py +++ /dev/null @@ -1,373 +0,0 @@ -# -*- coding: utf-8 -*- - -# -# Copyright (c) 2012 Virtual Cable S.L. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of Virtual Cable S.L. nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -''' -.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com -''' - -from uds.core.services import UserDeployment -from uds.core.util.State import State -import logging - -logger = logging.getLogger(__name__) - -class SampleUserDeploymentOne(UserDeployment): - ''' - This class generates the user consumable elements of the service tree. - - After creating at administration interface an Deployed Service, UDS will - create consumable services for users using UserDeployment class as - provider of this elements. - - - At class instantiation, this will receive an environment with"generator", - that are classes that provides a way to generate unique items. - - The generators provided right now are 'mac' and 'name'. To get more info - about this, look at py:class:`uds.core.util.UniqueMacGenerator.UniqueNameGenerator` - and py:class:`uds.core.util.UniqueNameGenerator.UniqueNameGenerator` - - This first sample do not uses cache. To see one with cache, see - SampleUserDeploymentTwo. The main difference are the "...Cache".." methods, - that here are not needed. - - As sample also of environment storage usage, wi will use here the provider - storage to keep all our needed info, leaving marshal and unmarshal (needed - by Serializble classes, like this) empty (that is, returns '' first and does - nothing the second one) - - Also Remember, if you don't include this class as the deployedType of the - SampleServiceOne, or whenever you trie to access a service of SampleServiceOne, - you will get an excetion that says that you havent included the deployedType. - ''' - - #: Recheck every five seconds by default (for task methods) - suggestedTime = 5 - - # Serializable needed methods - def marshal(self): - ''' - Does nothing right here, we will use envoronment storage in this sample - ''' - return '' - - def unmarshal(self, str_): - ''' - Does nothing here also, all data are keeped at environment storage - ''' - pass - - - def getName(self): - ''' - We override this to return a name to display. Default inplementation - (in base class), returns getUniqueIde() value - This name will help user to identify elements, and is only used - at administration interface. - - We will use here the environment name provided generator to generate - a name for this element. - - The namaGenerator need two params, the base name and a length for a - numeric incremental part for generating unique names. This are unique for - all UDS names generations, that is, UDS will not generate this name again - until this name is freed, or object is removed, what makes its environment - to also get removed, that makes all uniques ids (names and macs right now) - to also get released. - - Every time get method of a generator gets called, the generator creates - a new unique name, so we keep the first generated name cached and don't - generate more names. (Generator are simple utility classes) - ''' - name = self.storage().readData('name') - if name is None: - name = self.nameGenerator().get( self.service().getBaseName() - + '-' + self.service().getColour(), 3 ) - # Store value for persistence - self.storage().saveData('name', name) - - return name - - def setIp(self, ip): - ''' - In our case, there is no OS manager associated with this, so this method - will never get called, but we put here as sample. - - Whenever an os manager actor notifies the broker the state of the service - (mainly machines), the implementation of that os manager can (an probably will) - need to notify the IP of the deployed service. Remember that UDS treats with - IP services, so will probable needed in every service that you will create. - :note: This IP is the IP of the "consumed service", so the transport can - access it. - ''' - self.storage().saveData('ip', str(ip)) - - def getUniqueId(self): - ''' - Return and unique identifier for this service. - In our case, we will generate a mac name, that can be also as sample - of 'mac' generator use, and probably will get used something like this - at some services. - - The get method of a mac generator takes one param, that is the mac range - to use to get an unused mac. - ''' - mac = self.storage().readData('mac') - if mac is None: - mac = self.macGenerator().get( '00:00:00:00:00:00-00:FF:FF:FF:FF:FF' ) - self.storage().saveData('mac', mac) - return mac - - def getIp(self): - ''' - We need to implement this method, so we can return the IP for transports - use. If no IP is known for this service, this must return None - - If our sample do not returns an IP, IP transport will never work with - this service. Remember in real cases to return a valid IP address if - the service is accesible and you alredy know that (for example, because - the IP has been assigend via setIp by an os manager) or because - you get it for some other method. - - Storage returns None if key is not stored. - - :note: Keeping the IP address is responsibility of the User Deployment. - Every time the core needs to provide the service to the user, or - show the IP to the administrator, this method will get called - - ''' - ip = self.storage().readData('ip') - if ip is None: - ip = '192.168.0.34' # Sample IP for testing purposses only - return ip - - def setReady(self): - ''' - This is a task method. As that, the expected return values are - State values RUNNING, FINISHED or ERROR. - - The method is invoked whenever a machine is provided to an user, right - before presenting it (via transport rendering) to the user. - - This method exist for this kind of situations (i will explain it with a - sample) - - Imagine a Service tree (Provider, Service, ...) for virtual machines. - This machines will get created by the UserDeployment implementation, but, - at some time, the machine can be put at in an state (suspend, shut down) - that will make the transport impossible to connect with it. - - This method, in this case, will check the state of the machine, and if - it is "ready", that is, powered on and accesible, it will return - "State.FINISHED". If the machine is not accesible (has ben erased, for - example), it will return "State.ERROR" and store a reason of error so UDS - can ask for it and present this information to the Administrator. - - If the machine powered off, or suspended, or any other state that is not - directly usable but can be put in an usable state, it will return - "State.RUNNING", and core will use checkState to see when the operation - has finished. - - I hope this sample is enough to explain the use of this method.. - ''' - - # In our case, the service is always ready - return State.FINISHED - - def deployForUser(self, user): - ''' - Deploys an service instance for an user. - - This is a task method. As that, the excepted return values are - State values RUNNING, FINISHED or ERROR. - - The user parameter is not realy neded, but provided. It indicates the - Database User Object (see py:mod:`uds.modules`) to which this deployed - user service will be assigned to. - - This method will get called whenever a new deployed service for an user - is needed. This will give this class the oportunity to create - a service that is assigned to an user. - - The way of using this method is as follows: - - If the service gets created in "one step", that is, before the return - of this method, the consumable service for the user gets created, it - will return "State.FINISH". - If the service needs more steps (as in this case), we will return - "State.RUNNING", and if it has an error, it wil return "State.ERROR" and - store an error string so administration interface can show it. - - We do not use user for anything, as in most cases will be. - ''' - import random - - self.storage().saveData('count', '0') - - # random fail - if random.randint(0, 9) == 9: - self.storage().saveData('error', 'Random error at deployForUser :-)') - return State.ERROR - - return State.RUNNING - - - def checkState(self): - ''' - Our deployForUser method will initiate the consumable service deployment, - but will not finish it. - - So in our sample, we will only check if a number reaches 5, and if so - return that we have finished, else we will return that we are working - on it. - - One deployForUser returns State.RUNNING, this task will get called until - checkState returns State.FINISHED. - - Also, we will make the publication fail one of every 10 calls to this - method. - - Note: Destroying, canceling and deploying for cache also makes use of - this method, so you must keep the info of that you are checking if you - need it. - In our case, destroy is 1-step action so this will no get called while - destroying, and cancel will simply invoke destroy - ''' - import random - - count = int(self.storage().readData('count')) + 1 - # Count is always a valid value, because this method will never get - # called before deployForUser, deployForCache, destroy or cancel. - # In our sample, we only use checkState in case of deployForUser, - # so at first call count will be 0. - if count >= 5: - return State.FINISHED - - # random fail - if random.randint(0, 9) == 9: - self.storage().saveData('error', 'Random error at checkState :-)') - return State.ERROR - - self.storage().saveData('count', str(count)) - return State.RUNNING - - def finish(self): - ''' - Invoked when the core notices that the deployment of a service has finished. - (No matter wether it is for cache or for an user) - - This gives the oportunity to make something at that moment. - :note: You can also make these operations at checkState, this is really - not needed, but can be provided (default implementation of base class does - nothing) - ''' - # Note that this is not really needed, is just a sample of storage use - self.storage().remove('count') - - def assignToUser(self, user): - ''' - This method is invoked whenever a cache item gets assigned to an user. - This gives the User Deployment an oportunity to do whatever actions - are required so the service puts at a correct state for using by a service. - - In our sample, the service is always ready, so this does nothing. - - This is not a task method. All level 1 cache items can be diretly - assigned to an user with no more work needed, but, if something is needed, - here you can do whatever you need - ''' - pass - - def userLoggedIn(self, user): - ''' - This method must be available so os managers can invoke it whenever - an user get logged into a service. - - Default implementation does nothing, so if you are going to do nothing, - you don't need to implement it. - - The responability of notifying it is of os manager actor, and it's - directly invoked by os managers (right now, linux os manager and windows - os manager) - - The user provided is just an string, that is provided by actor. - ''' - # We store the value at storage, but never get used, just an example - self.storage().saveData('user', user) - - def userLoggedOut(self, user): - ''' - This method must be available so os managers can invoke it whenever - an user get logged out if a service. - - Default implementation does nothing, so if you are going to do nothing, - you don't need to implement it. - - The responability of notifying it is of os manager actor, and it's - directly invoked by os managers (right now, linux os manager and windows - os manager) - - The user provided is just an string, that is provided by actor. - ''' - # We do nothing more that remove the user - self.storage().remove('user') - - def reasonOfError(self): - ''' - Returns the reason of the error. - - Remember that the class is responsible of returning this whenever asked - for it, and it will be asked everytime it's needed to be shown to the - user (when the administation asks for it). - ''' - return self.storage().readData('error') or 'No error' - - def destroy(self): - ''' - This is a task method. As that, the excepted return values are - State values RUNNING, FINISHED or ERROR. - - Invoked for destroying a deployed service - Do whatever needed here, as deleting associated data if needed (i.e. a copy of the machine, snapshots, etc...) - @return: State.FINISHED if no more checks/steps for deployment are needed, State.RUNNING if more steps are needed (steps checked using checkState) - ''' - return State.FINISHED - - def cancel(self): - ''' - This is a task method. As that, the excepted return values are - State values RUNNING, FINISHED or ERROR. - - This can be invoked directly by an administration or by the clean up - of the deployed service (indirectly). - When administrator requests it, the cancel is "delayed" and not - invoked directly. - ''' - return State.FINISHED - \ No newline at end of file diff --git a/server/documentation/_build/html/_downloads/SampleUserDeploymentTwo.py b/server/documentation/_build/html/_downloads/SampleUserDeploymentTwo.py deleted file mode 100644 index 687971e7..00000000 --- a/server/documentation/_build/html/_downloads/SampleUserDeploymentTwo.py +++ /dev/null @@ -1,469 +0,0 @@ -# -*- coding: utf-8 -*- - -# -# Copyright (c) 2012 Virtual Cable S.L. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of Virtual Cable S.L. nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -''' -.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com -''' - -from uds.core.services import UserDeployment -from uds.core.util.State import State -import logging - -logger = logging.getLogger(__name__) - -class SampleUserDeploymentTwo(UserDeployment): - ''' - This class generates the user consumable elements of the service tree. - - This is almost the same as SampleUserDeploymentOne, but differs that this one - uses the publication to get data from it, in a very basic way. - - After creating at administration interface an Deployed Service, UDS will - create consumable services for users using UserDeployment class as - provider of this elements. - - At class instantiation, this will receive an environment with"generator", - that are classes that provides a way to generate unique items. - - The generators provided right now are 'mac' and 'name'. To get more info - about this, look at py:class:`uds.core.util.UniqueMacGenerator.UniqueNameGenerator` - and py:class:`uds.core.util.UniqueNameGenerator.UniqueNameGenerator` - - As sample also of environment storage usage, wi will use here the provider - storage to keep all our needed info, leaving marshal and unmarshal (needed - by Serializable classes, like this) empty (that is, returns '' first and does - nothing the second one) - - Also Remember, if you don't include this class as the deployedType of the - SampleServiceTwo, or whenever you try to access a service of SampleServiceTwo, - you will get an exception that says that you haven't included the deployedType. - ''' - - #: Recheck every five seconds by default (for task methods) - suggestedTime = 2 - - def initialize(self): - ''' - Initialize default attributes values here. We can do whatever we like, - but for this sample this is just right... - ''' - self._name = '' - self._ip = '' - self._mac = '' - self._error = '' - self._count = 0 - - # Serializable needed methods - def marshal(self): - ''' - Marshal own data, in this sample we will marshal internal needed - attributes. - - In this case, the data will be store with the database record. To - minimize database storage usage, we will "zip" data before returning it. - Anyway, we should keep this data as low as possible, we also have an - storage for loading larger data. - - :note: It's a good idea when providing marshalers, to store a 'version' - beside the values, so we can, at a later stage, treat with old - data for current modules. - ''' - data = '\t'.join(['v1', self._name, self._ip, self._mac, self._error, - str(self._count)]) - return data.encode('zip') - - def unmarshal(self, str_): - ''' - We unmarshal the content. - ''' - data = str_.decode('zip').split('\t') - # Data Version check - # If we include some new data at some point in a future, we can - # add "default" values at v1 check, and load new values at 'v2' check. - if data[0] == 'v1': - self._name, self._ip, self._mac, self._error, count = data[1:] - self._count = int(count) - - def getName(self): - ''' - We override this to return a name to display. Default implementation - (in base class), returns getUniqueIde() value - This name will help user to identify elements, and is only used - at administration interface. - - We will use here the environment name provided generator to generate - a name for this element. - - The namaGenerator need two params, the base name and a length for a - numeric incremental part for generating unique names. This are unique for - all UDS names generations, that is, UDS will not generate this name again - until this name is freed, or object is removed, what makes its environment - to also get removed, that makes all unique ids (names and macs right now) - to also get released. - - Every time get method of a generator gets called, the generator creates - a new unique name, so we keep the first generated name cached and don't - generate more names. (Generator are simple utility classes) - ''' - if self._name == '': - self._name = self.nameGenerator().get( self.publication().getBaseName(), - 3 ) - # self._name will be stored when object is marshaled - return self._name - - def setIp(self, ip): - ''' - In our case, there is no OS manager associated with this, so this method - will never get called, but we put here as sample. - - Whenever an os manager actor notifies the broker the state of the service - (mainly machines), the implementation of that os manager can (an probably will) - need to notify the IP of the deployed service. Remember that UDS treats with - IP services, so will probable needed in every service that you will create. - :note: This IP is the IP of the "consumed service", so the transport can - access it. - ''' - self._ip = ip - - def getUniqueId(self): - ''' - Return and unique identifier for this service. - In our case, we will generate a mac name, that can be also as sample - of 'mac' generator use, and probably will get used something like this - at some services. - - The get method of a mac generator takes one param, that is the mac range - to use to get an unused mac. - - The mac generated is not used by anyone, it will not depend on - the range, the generator will take care that this mac is unique - and in the range provided, or it will return None. The ranges - are wide enough to ensure that we always will get a mac address - in this case, but if this is not your case, take into account that - None is a possible return value, and in that case, you should return an - invalid id right now. Every time a task method is invoked, the core - will try to update the value of the unique id using this method, so - that id can change with time. (In fact, it's not unique at database level, - it's unique in the sense that you must return an unique id that can, for - example, be used by os managers to identify this element). - - :note: Normally, getting out of macs in the mac pool is a bad thing... :-) - ''' - if self._mac == '': - self._mac = self.macGenerator().get( '00:00:00:00:00:00-00:FF:FF:FF:FF:FF' ) - return self._mac - - def getIp(self): - ''' - We need to implement this method, so we can return the IP for transports - use. If no IP is known for this service, this must return None - - If our sample do not returns an IP, IP transport will never work with - this service. Remember in real cases to return a valid IP address if - the service is accesible and you alredy know that (for example, because - the IP has been assigend via setIp by an os manager) or because - you get it for some other method. - - Storage returns None if key is not stored. - - :note: Keeping the IP address is responsibility of the User Deployment. - Every time the core needs to provide the service to the user, or - show the IP to the administrator, this method will get called - - ''' - if self._ip == '': - return '192.168.0.34' # Sample IP for testing purposes only - return self._ip - - def setReady(self): - ''' - This is a task method. As that, the excepted return values are - State values RUNNING, FINISHED or ERROR. - - The method is invoked whenever a machine is provided to an user, right - before presenting it (via transport rendering) to the user. - - This method exist for this kind of situations (i will explain it with a - sample) - - Imagine a Service tree (Provider, Service, ...) for virtual machines. - This machines will get created by the UserDeployment implementation, but, - at some time, the machine can be put at in an state (suspend, shut down) - that will make the transport impossible to connect with it. - - This method, in this case, will check the state of the machine, and if - it is "ready", that is, powered on and accessible, it will return - "State.FINISHED". If the machine is not accessible (has been erased, for - example), it will return "State.ERROR" and store a reason of error so UDS - can ask for it and present this information to the Administrator. - - If the machine powered off, or suspended, or any other state that is not - directly usable but can be put in an usable state, it will return - "State.RUNNING", and core will use checkState to see when the operation - has finished. - - I hope this sample is enough to explain the use of this method.. - ''' - - # In our case, the service is always ready - return State.FINISHED - - def deployForUser(self, user): - ''' - Deploys an service instance for an user. - - This is a task method. As that, the excepted return values are - State values RUNNING, FINISHED or ERROR. - - The user parameter is not realy neded, but provided. It indicates the - Database User Object (see py:mod:`uds.modules`) to which this deployed - user service will be assigned to. - - This method will get called whenever a new deployed service for an user - is needed. This will give this class the oportunity to create - a service that is assigned to an user. - - The way of using this method is as follows: - - If the service gets created in "one step", that is, before the return - of this method, the consumable service for the user gets created, it - will return "State.FINISH". - If the service needs more steps (as in this case), we will return - "State.RUNNING", and if it has an error, it wil return "State.ERROR" and - store an error string so administration interface can show it. - - We do not use user for anything, as in most cases will be. - ''' - import random - - self._count = 0 - - # random fail - if random.randint(0, 9) == 9: - # Note that we can mark this string as translatable, and return - # it translated at reasonOfError method - self._error = 'Random error at deployForUser :-)' - return State.ERROR - - return State.RUNNING - - def deployForCache(self, cacheLevel): - ''' - Deploys a user deployment as cache. - - This is a task method. As that, the expected return values are - State values RUNNING, FINISHED or ERROR. - - In our sample, this will do exactly the same as deploy for user, - except that it will never will give an error. - - See deployForUser for a description of what this method should do. - - :note: deployForCache is invoked whenever a new cache element is needed - for an specific user deployment. It will also indicate for what - cache level (L1, L2) is the deployment - ''' - self._count = 0 - return State.RUNNING - - def moveToCache(self, newLevel): - ''' - This method is invoked whenever the core needs to move from the current - cache level to a new cache level an user deployment. - - This is a task method. As that, the expected return values are - State values RUNNING, FINISHED or ERROR. - - We only provide newLevel, because there is only two cache levels, so if - newLevel is L1, the actual is L2, and if it is L2, the actual is L1. - - Actually there is no possibility to move assigned services again back to - cache. If some service needs that kind of functionallity, this must be - provided at service level (for example, when doing publishing creating - a number of services that will be used, released and reused by users). - - Also, user deployments that are at cache level 2 will never get directly - assigned to user. First, it will pass to L1 and then it will get assigned. - - A good sample of a real implementation of this is moving a virtual machine - from a "suspended" state to "running" state to assign it to an user. - - In this sample, there is L2 cache also, but moving from L1 to L2 and - from L2 to L1 is doing really nothing, so this method will do nothing. - - In a real scenario, we will, for example, suspend or resume virtual machine - and, return State.RUNNING and at checkState check if this task is completed. - ''' - pass - - def checkState(self): - ''' - Our deployForUser method will initiate the consumable service deployment, - but will not finish it. - - So in our sample, we will only check if a number reaches 5, and if so - return that we have finished, else we will return that we are working - on it. - - One deployForUser returns State.RUNNING, this task will get called until - checkState returns State.FINISHED. - - Also, we will make the user deployment fail one of every 10 calls to this - method. - - Note: Destroying, canceling and deploying for cache also makes use of - this method, so you must keep the info of that you are checking if you - need it. - - In our case, destroy is 1-step action so this will no get called while - destroying, and cancel will simply invoke destroy. Cache deployment is - exactly as user deployment, except that the core will not assign it to - anyone, and cache moving operations is - ''' - import random - - self._count += 1 - # Count is always a valid value, because this method will never get - # called before deployForUser, deployForCache, destroy or cancel. - # In our sample, we only use checkState in case of deployForUser, - # so at first call count will be 0. - if self._count >= 5: - return State.FINISHED - - # random fail - if random.randint(0, 9) == 9: - self._error = 'Random error at checkState :-)' - return State.ERROR - - return State.RUNNING - - def finish(self): - ''' - Invoked when the core notices that the deployment of a service has finished. - (No matter whether it is for cache or for an user) - - This gives the opportunity to make something at that moment. - - :note: You can also make these operations at checkState, this is really - not needed, but can be provided (default implementation of base class does - nothing) - ''' - # We set count to 0, not needed but for sample purposes - self._count = 0 - - def assignToUser(self, user): - ''' - This method is invoked whenever a cache item gets assigned to an user. - This is not a task method right now, simply a notification. This means - that L1 cache items must be directly usable (except for the readyness part) - by users in a single step operation. - - Note that there will be an setReady call before letting the user consume - this user deployment, so this is more informational (so, if you keep at - what cache level is this instance, you can update it) than anything else. - - This is not a task method. All level 1 cache items can be dircetly - assigned to an user with no more work needed, but, if something is needed, - here you can do whatever you need. - - user is a Database user object. - ''' - logger.debug('Assigned to user {0}'.format(user)) - - def userLoggedIn(self, user): - ''' - This method must be available so os managers can invoke it whenever - an user get logged into a service. - - Default implementation does nothing, so if you are going to do nothing, - you don't need to implement it. - - The responsibility of notifying it is of os manager actor, and it's - directly invoked by os managers (right now, linux os manager and windows - os manager) - - The user provided is just an string, that is provided by actors. - ''' - # We store the value at storage, but never get used, just an example - self.storage().saveData('user', user) - - def userLoggedOut(self, user): - ''' - This method must be available so os managers can invoke it whenever - an user get logged out if a service. - - Default implementation does nothing, so if you are going to do nothing, - you don't need to implement it. - - The responability of notifying it is of os manager actor, and it's - directly invoked by os managers (right now, linux os manager and windows - os manager) - - The user provided is just an string, that is provided by actor. - ''' - # We do nothing more that remove the user - self.storage().remove('user') - - def reasonOfError(self): - ''' - Returns the reason of the error. - - Remember that the class is responsible of returning this whenever asked - for it, and it will be asked everytime it's needed to be shown to the - user (when the administation asks for it). - - :note: Remember that you can use ugettext to translate this error to - user language whenever it is possible. (This one will get invoked - directly from admin interface and, as so, will have translation - environment correctly set up. - ''' - return self._error - - def destroy(self): - ''' - This is a task method. As that, the excepted return values are - State values RUNNING, FINISHED or ERROR. - - Invoked for destroying a deployed service - Do whatever needed here, as deleting associated data if needed (i.e. a copy of the machine, snapshots, etc...) - @return: State.FINISHED if no more checks/steps for deployment are needed, State.RUNNING if more steps are needed (steps checked using checkState) - ''' - return State.FINISHED - - def cancel(self): - ''' - This is a task method. As that, the excepted return values are - State values RUNNING, FINISHED or ERROR. - - This can be invoked directly by an administration or by the clean up - of the deployed service (indirectly). - When administrator requests it, the cancel is "delayed" and not - invoked directly. - ''' - return State.FINISHED diff --git a/server/documentation/_build/html/_downloads/__init__.py b/server/documentation/_build/html/_downloads/__init__.py deleted file mode 100644 index 38a9126a..00000000 --- a/server/documentation/_build/html/_downloads/__init__.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- - -# -# Copyright (c) 2012 Virtual Cable S.L. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of Virtual Cable S.L. nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -''' -Sample Service module. - -This package simply shows how a new service can be implemented. - - -The first thing to do in every package that is a module is register the -class that is responsible of providing the module with the system. - -For this, we must simply import the class at __init__, UDS will take care -of the rest -''' - -from SampleProvider import Provider - diff --git a/server/documentation/_build/html/_modules/index.html b/server/documentation/_build/html/_modules/index.html deleted file mode 100644 index 30f0dfa2..00000000 --- a/server/documentation/_build/html/_modules/index.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - Overview: module code — UDS 1.0 documentation - - - - - - - - - - - - - -
-
- - -
-
- -
-
- -
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/_modules/uds/core.html b/server/documentation/_build/html/_modules/uds/core.html deleted file mode 100644 index e93c112b..00000000 --- a/server/documentation/_build/html/_modules/uds/core.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - - - uds.core — UDS 1.0 documentation - - - - - - - - - - - - - - -
-
- - -
-
- -
-
-
-
- -

Source code for uds.core

-# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2012 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-#    * Redistributions of source code must retain the above copyright notice,
-#      this list of conditions and the following disclaimer.
-#    * Redistributions in binary form must reproduce the above copyright notice,
-#      this list of conditions and the following disclaimer in the documentation
-#      and/or other materials provided with the distribution.
-#    * Neither the name of Virtual Cable S.L. nor the names of its contributors
-#      may be used to endorse or promote products derived from this software
-#      without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''
-Core of UDS.
-This package contains all core-related code for UDS
-@author: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-from __future__ import unicode_literals
-
-# Core needs tasks manager to register scheduled jobs, so we ensure of that here
-from Environment import Environmentable
-from Serializable import Serializable
-from BaseModule import Module
-import services
-import auths
-import transports
-
- -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/_modules/uds/core/auths.html b/server/documentation/_build/html/_modules/uds/core/auths.html deleted file mode 100644 index c8a3929d..00000000 --- a/server/documentation/_build/html/_modules/uds/core/auths.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - - - uds.core.auths — UDS 1.0 documentation - - - - - - - - - - - - - - -
-
- - -
-
- -
-
-
-
- -

Source code for uds.core.auths

-# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2012 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-#    * Redistributions of source code must retain the above copyright notice,
-#      this list of conditions and the following disclaimer.
-#    * Redistributions in binary form must reproduce the above copyright notice,
-#      this list of conditions and the following disclaimer in the documentation
-#      and/or other materials provided with the distribution.
-#    * Neither the name of Virtual Cable S.L. nor the names of its contributors
-#      may be used to endorse or promote products derived from this software
-#      without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''
-UDS authentication related interfaces and classes
-
-.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-from __future__ import unicode_literals
-
-from BaseAuthenticator import Authenticator
-from User import User
-from Group import Group
-from GroupsManager import GroupsManager
-import Exceptions
-
-__updated__ = '2014-02-19'
-
-
-def factory():
-    '''
-    Returns factory for register/access to authenticators
-    '''
-    from AuthsFactory import AuthsFactory
-    return AuthsFactory.factory()
-
- -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/_modules/uds/core/services.html b/server/documentation/_build/html/_modules/uds/core/services.html deleted file mode 100644 index f2162555..00000000 --- a/server/documentation/_build/html/_modules/uds/core/services.html +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - - - uds.core.services — UDS 1.0 documentation - - - - - - - - - - - - - - -
-
- - -
-
- -
-
-
-
- -

Source code for uds.core.services

-# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2012 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-#    * Redistributions of source code must retain the above copyright notice,
-#      this list of conditions and the following disclaimer.
-#    * Redistributions in binary form must reproduce the above copyright notice,
-#      this list of conditions and the following disclaimer in the documentation
-#      and/or other materials provided with the distribution.
-#    * Neither the name of Virtual Cable S.L. nor the names of its contributors
-#      may be used to endorse or promote products derived from this software
-#      without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''
-UDS Service modules interfaces and classes.
-
-.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-from __future__ import unicode_literals
-
-from BaseServiceProvider import ServiceProvider
-from BaseService import Service
-from BasePublication import Publication
-from BaseDeployed import UserDeployment
-
-from ClusteredServiceProvider import ClusteredServiceProvider
-from ClusteredService import ClusteredService
-from ClusteredPublication import ClusteredPublication
-from ClusteredUserDeployment import ClusteredUserDeployment
-
-import Exceptions
-
-__updated__ = '2014-03-22'
-
-
-def factory():
-    '''
-    Returns factory for register/access to service providers
-    '''
-    from ServiceProviderFactory import ServiceProviderFactory
-    return ServiceProviderFactory.factory()
-
- -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/_modules/uds/core/services/Exceptions.html b/server/documentation/_build/html/_modules/uds/core/services/Exceptions.html deleted file mode 100644 index e800540f..00000000 --- a/server/documentation/_build/html/_modules/uds/core/services/Exceptions.html +++ /dev/null @@ -1,181 +0,0 @@ - - - - - - - - uds.core.services.Exceptions — UDS 1.0 documentation - - - - - - - - - - - - - - -
-
- - -
-
- -
-
-
-
- -

Source code for uds.core.services.Exceptions

-# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2012 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-#    * Redistributions of source code must retain the above copyright notice,
-#      this list of conditions and the following disclaimer.
-#    * Redistributions in binary form must reproduce the above copyright notice,
-#      this list of conditions and the following disclaimer in the documentation
-#      and/or other materials provided with the distribution.
-#    * Neither the name of Virtual Cable S.L. nor the names of its contributors
-#      may be used to endorse or promote products derived from this software
-#      without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''
-.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-from __future__ import unicode_literals
-
-__updated__ = '2014-03-22'
-
-
-
[docs]class UnsupportedException(Exception): - ''' - Reflects that we request an operation that is not supported, i.e. Cancel a publication with snapshots - ''' - pass - -
-
[docs]class OperationException(Exception): - ''' - Reflects that the operation requested can't be acomplished, i.e. remove an snapshot without snapshot reference, cancel non running operation, etc... - ''' - pass - -
-
[docs]class PublishException(Exception): - ''' - Reflects thate the publication can't be done for causes we don't know in advance - ''' - pass - -
-
[docs]class DeploymentException(Exception): - ''' - Reflects that a deployment of a service (at cache, or assigned to user) can't be done for causes we don't know in advance - ''' - pass - -
-
[docs]class CancelException(Exception): - ''' - Reflects that a "cancel" operation can't be done for some reason - ''' - -
-
[docs]class InvalidServiceException(Exception): - ''' - Invalid service specified. The service is not ready - ''' - pass - -
-
[docs]class MaxServicesReachedException(Exception): - ''' - Number of maximum services has been reached, and no more services - can be created for users. - ''' - pass
-
- -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/_modules/uds/core/ui/UserInterface.html b/server/documentation/_build/html/_modules/uds/core/ui/UserInterface.html deleted file mode 100644 index ac3067c2..00000000 --- a/server/documentation/_build/html/_modules/uds/core/ui/UserInterface.html +++ /dev/null @@ -1,940 +0,0 @@ - - - - - - - - uds.core.ui.UserInterface — UDS 1.0 documentation - - - - - - - - - - - - - - -
-
- - -
-
- -
-
-
-
- -

Source code for uds.core.ui.UserInterface

-# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2012 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-#    * Redistributions of source code must retain the above copyright notice,
-#      this list of conditions and the following disclaimer.
-#    * Redistributions in binary form must reproduce the above copyright notice,
-#      this list of conditions and the following disclaimer in the documentation
-#      and/or other materials provided with the distribution.
-#    * Neither the name of Virtual Cable S.L. nor the names of its contributors
-#      may be used to endorse or promote products derived from this software
-#      without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''
-.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-from __future__ import unicode_literals
-
-from django.utils.translation import get_language, ugettext as _
-import cPickle
-import logging
-
-logger = logging.getLogger(__name__)
-
-
-
[docs]class gui(object): - ''' - This class contains the representations of fields needed by UDS modules and - administation interface. - - This contains fields types, that modules uses to make a form and interact - with users. - - The use of this provided fields are as follows: - - The Module is descendant of "BaseModule", which also is inherited from this - class. - - At class level, we declare the fields needed to interact with the user, as - this example: - - .. code-block:: python - - class AuthModule(Authenticator): - # ... - # Other initializations - # ... - users = gui.EditableList(label = 'Users', tooltip = 'Select users', - order = 1, values = ['user1', 'user2', 'user3', 'user4']) - passw = gui.Password(label='Pass', length=32, tooltip='Password', - order = 2, required = True, defValue = '12345') - # ... - # more fields - # ... - - At class instantiation, this data is extracted and processed, so the admin - can access this form to let users - create new instances of this module. - ''' - - # : True string value - TRUE = 'true' - # : False string value - FALSE = 'false' - - # : Static Callbacks simple registry - callbacks = {} - - # Helpers - @staticmethod - def convertToChoices(vals): - ''' - Helper to convert from array of strings to the same dict used in choice, - multichoice, .. - The id is set to values in the array (strings), while text is left empty. - ''' - res = [] - for v in vals: - res.append({'id': v, 'text': ''}) - return res - - @staticmethod - def convertToList(vals): - if vals is not None: - return [unicode(v) for v in vals] - return [] - - @staticmethod - def choiceItem(id_, text): - ''' - Helper method to create a single choice item. - - Args: - id: Id of the choice to create - - text: Text to assign to the choice to create - - Returns: - An dictionary, that is the representation of a single choice item, - with 2 keys, 'id' and 'text' - - :note: Text can be anything, the method converts it first to text before - assigning to dictionary - ''' - return {'id': str(id_), 'text': str(text)} - - @staticmethod - def strToBool(str_): - ''' - Converts the string "true" (case insensitive) to True (boolean). - Anything else is converted to false - - Args: - str: Str to convert to boolean - - Returns: - True if the string is "true" (case insensitive), False else. - ''' - if isinstance(str_, bool): - return str_ - if unicode(str_).lower() == gui.TRUE: - return True - return False - - @staticmethod - def boolToStr(bol): - ''' - Converts a boolean to the string representation. True is converted to - "true", False to "false". - - Args: - bol: Boolean value (True or false) to convert - - Returns: - "true" if bol evals to True, "false" if don't. - ''' - if bol: - return gui.TRUE - return gui.FALSE - - # Classes - -
[docs] class InputField(object): - ''' - Class representing an simple input field. - This class is not directly usable, must be used by any inherited class - (fields all of them) - All fields are inherited from this one - - The data managed for an input field, and their default values are: - * length: Max length of the field. Defaults to DEFAULT_LENGTH - * required: If this field is a MUST. defaults to false - * label: Label used with this field. Defaults to '' - * defvalue: Default value for the field. Defaults to '' (this is - always an string) - * rdonly: If the field is read only on modification. On creation, - all fields are "writable". Defaults to False - * order: order inside the form, defaults to 0 (if two or more fields - has same order, the output order may be anything) - * tooltip: Tooltip used in the form, defaults to '' - * type: type of the input field, defaults to "text box" (TextField) - - In every single field, you must at least indicate: - * if required or not - * order - * label - * tooltip - * defvalue - * rdonly if can't be modified once it's created - - Any other paremeter needed is indicated in the corresponding field class. - - Also a value field is available, so you can get/set the form field value. - This property expects always an string, no matter what kind of field it is. - - Take into account also that "value" has precedence over "defValue", - so if you use both, the used one will be "value". This is valid for - all form fields. - ''' - TEXT_TYPE = 'text' - TEXTBOX_TYPE = 'textbox' - NUMERIC_TYPE = 'numeric' - PASSWORD_TYPE = 'password' - HIDDEN_TYPE = 'hidden' - CHOICE_TYPE = 'choice' - MULTI_CHOICE_TYPE = 'multichoice' - EDITABLE_LIST = 'editlist' - CHECKBOX_TYPE = 'checkbox' - - DEFAULT_LENTGH = 32 # : If length of some fields are not especified, this value is used as default - - def __init__(self, **options): - self._data = { - 'length': options.get('length', gui.InputField.DEFAULT_LENTGH), - 'required': options.get('required', False), - 'label': options.get('label', ''), - 'defvalue': unicode(options.get('defvalue', '')), - 'rdonly': options.get('rdonly', False), # This property only affects in "modify" operations - 'order': options.get('order', 0), - 'tooltip': options.get('tooltip', ''), - 'type': gui.InputField.TEXT_TYPE, - 'value': options.get('value', ''), - } - - def _type(self, type_): - ''' - Sets the type of this field. - - Args: - type: Type to set (from constants of this class) - ''' - self._data['type'] = type_ - -
[docs] def isType(self, type_): - ''' - Returns true if this field is of specified type - ''' - return self._data['type'] == type_ -
- @property - def value(self): - ''' - Obtains the stored value - ''' - return self._data['value'] - - @value.setter -
[docs] def value(self, value): - ''' - Stores new value (not the default one) - ''' - self._setValue(value) -
- def _setValue(self, value): - ''' - So we can override value setting at descendants - ''' - self._data['value'] = value - -
[docs] def guiDescription(self): - ''' - Returns the dictionary with the description of this item. - We copy it, cause we need to translate the label and tooltip fields - and don't want to - alter original values. - ''' - data = self._data.copy() - data['label'] = data['label'] != '' and _(data['label']) or '' - data['tooltip'] = data['tooltip'] != '' and _(data['tooltip']) or '' - return data -
- @property - def defValue(self): - ''' - Returns the default value for this field - ''' - return self._data['defvalue'] - - @defValue.setter -
[docs] def defValue(self, defValue): - self.setDefValue(defValue) -
-
[docs] def setDefValue(self, defValue): - ''' - Sets the default value of the field· - - Args: - defValue: Default value (string) - ''' - self._data['defvalue'] = defValue -
- @property - def label(self): - return self._data['label'] -
-
[docs] class TextField(InputField): - ''' - This represents a text field. - - The values of parameters are inherited from :py:class:`InputField` - - Additionally to standard parameters, the length parameter is a - recommended one for this kind of field. - - You can specify that this is a multiline text box with **multiline** - parameter. If it exists, and is greater than 1, indicates how much - lines will be used to display field. (Max number is 8) - - Example usage: - - .. code-block:: python - - # Declares an text form field, with label "Host", tooltip - # "Host name for this module", that is required, - # with max length of 64 chars and order = 1, and is editable - # after creation. - host = gui.TextField(length=64, label = _('Host'), order = 1, - tooltip = _('Host name for this module'), required = True) - - # Declares an text form field, with label "Other", - # tooltip "Other info", that is not required, that is not - # required and that is not editable after creation. - other = gui.TextField(length=64, label = _('Other'), order = 1, - tooltip = _('Other info'), rdonly = True) - - ''' - def __init__(self, **options): - super(self.__class__, self).__init__(**options) - self._type(gui.InputField.TEXT_TYPE) - multiline = int(options.get('multiline', 0)) - if multiline > 8: - multiline = 8 - self._data['multiline'] = multiline -
-
[docs] class NumericField(InputField): - ''' - This represents a numeric field. It apears with an spin up/down button. - - The values of parameres are inherited from :py:class:`InputField` - - Additionally to standard parameters, the length parameter indicates the - max number of digits (0-9 values). - - Example usage: - - .. code-block:: python - - # Declares an numeric form field, with max value of 99999, label - # "Port", that is required, - # with tooltip "Port (usually 443)" and order 1 - num = gui.NumericField(length=5, label = _('Port'), - defvalue = '443', order = 1, tooltip = _('Port (usually 443)'), - required = True) - ''' - def __init__(self, **options): - super(self.__class__, self).__init__(**options) - self._type(gui.InputField.NUMERIC_TYPE) - -
[docs] def num(self): - ''' - Return value as integer - ''' - return int(self.value) -
-
[docs] class PasswordField(InputField): - ''' - This represents a password field. It appears with "*" at input, so the contents is not displayed - - The values of parameres are inherited from :py:class:`InputField` - - Additionally to standard parameters, the length parameter is a recommended one for this kind of field. - - Example usage: - - .. code-block:: python - - # Declares an text form field, with label "Password", - # tooltip "Password of the user", that is required, - # with max length of 32 chars and order = 2, and is - # editable after creation. - passw = gui.PasswordField(lenth=32, label = _('Password'), - order = 4, tooltip = _('Password of the user'), - required = True) - - ''' - def __init__(self, **options): - super(self.__class__, self).__init__(**options) - self._type(gui.InputField.PASSWORD_TYPE) -
-
[docs] class HiddenField(InputField): - ''' - This represents a hidden field. It is not displayed to the user. It use - is for keeping info at form needed - by module, but not editable by user (i.e., one service can keep info - about the parent provider in hiddens) - - The values of parameres are inherited from :py:class:`InputField` - - These are almost the same as TextFields, but they do not get displayed - for user interaction. - - Example usage: - - .. code-block:: python - - # Declares an empty hidden field - hidden = gui.HiddenField() - - - After that, at initGui method of module, we can store a value inside - using setDefValue as shown here: - - .. code-block:: python - - def initGui(self): - # always set defValue using self, cause we only want to store - # value for current instance - self.hidden.setDefValue(self.parent().serialize()) - - ''' - def __init__(self, **options): - super(self.__class__, self).__init__(**options) - self._isSerializable = options.get('serializable', '') != '' - self._type(gui.InputField.HIDDEN_TYPE) - - def isSerializable(self): - return self._isSerializable -
-
[docs] class CheckBoxField(InputField): - ''' - This represents a check box field, with values "true" and "false" - - The values of parameters are inherited from :py:class:`InputField` - - The valid values for this defvalue are: "true" and "false" (as strings) - - Example usage: - - .. code-block:: python - - # Declares an check box field, with label "Use SSL", order 3, - # tooltip "If checked, will use a ssl connection", default value - # unchecked (not included, so it's empty, so it's not true :-)) - ssl = gui.CheckBoxField(label = _('Use SSL'), order = 3, - tooltip = _('If checked, will use a ssl connection')) - - ''' - def __init__(self, **options): - super(self.__class__, self).__init__(**options) - self._type(gui.InputField.CHECKBOX_TYPE) - -
[docs] def isTrue(self): - ''' - Checks that the value is true - ''' - return self.value == 'true' -
-
[docs] class ChoiceField(InputField): - ''' - This represents a simple combo box with single selection. - - The values of parameters are inherited from :py:class:`InputField` - - ChoiceField needs a function to provide values inside it. - - * We specify the values via "values" option this way: - - Example: - - .. code-block:: python - - choices = gui.ChoiceField(label="choices", values = [ {'id':'1', - 'text':'Text 1'}, {'id':'xxx', 'text':'Text 2'}]) - - You can specify a multi valuated field via id-values, or a - single-valued field via id-value - - * We can override choice values at UserInterface derived class - constructor or initGui using setValues - - There is an extra option available for this kind of field: - - fills: This options is a dictionary that contains this fields: - * 'callbackName' : Callback name for invocation via the specific - method xml-rpc. This name is a name we assign to this callback, - and is used to locate the method when callback is invoked from - admin interface. - * 'function' : Function to execute. - - This funtion receives one parameter, that is a dictionary with - all parameters (that, in time, are fields names) that we have - requested. - - The expected return value for this callback is an array of - dictionaries with fields and values to set, as - example show below shows. - * 'parameters' : Array of field names to pass back to server so - it can obtain the results. - - Of course, this fields must be part of the module. - - Example: - - .. code-block:: python - - choice1 = gui.ChoiceField(label="Choice 1", values = ...., - fills = { 'target': 'choice2', 'callback': fncValues, - 'parameters': ['choice1', 'name']} - ) - choice2 = ghui.ChoiceField(label="Choice 2") - - Here is a more detailed explanation, using the VC service module as - sample. - - .. code-block:: python - - class VCHelpers(object): - # ... - # other stuff - # ... - @staticmethod - def getMachines(parameters): - # ...initialization and other stuff... - if parameters['resourcePool'] != '': - # ... do stuff ... - data = [ { 'name' : 'machine', 'values' : 'xxxxxx' } ] - return data - - class ModuleVC(services.Service) - # ... - # stuff - # ... - resourcePool = gui.ChoiceField( - label=_("Resource Pool"), rdonly = False, order = 5, - fills = { - 'callbackName' : 'vcFillMachinesFromResource', - 'function' : VCHelpers.getMachines, - 'parameters' : ['vc', 'ev', 'resourcePool'] - }, - tooltip = _('Resource Pool containing base machine'), - required = True - ) - - machine = gui.ChoiceField(label = _("Base Machine"), order = 6, - tooltip = _('Base machine for this service'), required = True ) - - vc = gui.HiddenField() - ev = gui.HiddenField() # .... - - ''' - def __init__(self, **options): - super(self.__class__, self).__init__(**options) - self._data['values'] = options.get('values', []) - if 'fills' in options: - # Save fnc to register as callback - fills = options['fills'] - fnc = fills['function'] - fills.pop('function') - self._data['fills'] = fills - gui.callbacks[fills['callbackName']] = fnc - self._type(gui.InputField.CHOICE_TYPE) - -
[docs] def setValues(self, values): - ''' - Set the values for this choice field - ''' - self._data['values'] = values -
-
[docs] class MultiChoiceField(InputField): - ''' - Multichoices are list of items that are multi-selectable. - - There is a new parameter here, not covered by InputField: - * 'rows' to tell gui how many rows to display (the length of the - displayable list) - - "defvalue" is expresed as a comma separated list of ids - - This class do not have callback support, as ChoiceField does. - - The values is an array of dictionaries, in the form [ { 'id' : 'a', - 'text': b }, ... ] - - Example usage: - - .. code-block:: python - - # Declares a multiple choices field, with label "Datastores", that - is editable, with 5 rows for displaying - # data at most in user interface, 8th in order, that is required - and has tooltip "Datastores where to put incrementals", - # this field is required and has 2 selectable items: "datastore0" - with id "0" and "datastore1" with id "1" - datastores = gui.MultiChoiceField(label = _("Datastores"), - rdonly = False, rows = 5, order = 8, - tooltip = _('Datastores where to put incrementals'), - required = True, - values = [ {'id': '0', 'text': 'datastore0' }, - {'id': '1', 'text': 'datastore1' } ] - ) - ''' - def __init__(self, **options): - super(self.__class__, self).__init__(**options) - self._data['values'] = options.get('values', []) - self._data['rows'] = options.get('rows', -1) - self._type(gui.InputField.MULTI_CHOICE_TYPE) - -
[docs] def setValues(self, values): - ''' - Set the values for this multi choice field - ''' - self._data['values'] = values -
-
[docs] class EditableList(InputField): - ''' - Editables list are lists of editable elements (i.e., a list of IPs, macs, - names, etcc) treated as simple strings with no id - - The struct used to pass values is an array of strings, i.e. ['1', '2', - 'test', 'bebito', ...] - - This list don't have "selected" items, so its defvalue field is simply - ignored. - - We only nee to pass in "label" and, maybe, "values" to set default - content for the list. - - Keep in mind that this is an user editable list, so the user can insert - values and/or import values from files, so - by default it will probably have no content at all. - - Example usage: - - .. code-block:: python - - # - ipList = gui.EditableList(label=_('List of IPS')) - - ''' - - # : Constant for separating values at "value" method - SEPARATOR = '\001' - - def __init__(self, **options): - super(self.__class__, self).__init__(**options) - self._data['values'] = gui.convertToList(options.get('values', [])) - self._type(gui.InputField.EDITABLE_LIST) - - def _setValue(self, values): - ''' - So we can override value setting at descendants - ''' - super(self.__class__, self)._setValue(values) - self._data['values'] = gui.convertToList(values) - -
-class UserInterfaceType(type): - ''' - Metaclass definition for moving the user interface descriptions to a usable - better place - ''' - def __new__(cls, classname, bases, classDict): - newClassDict = {} - _gui = {} - # We will keep a reference to gui elements also at _gui so we can access them easily - for attrName, attr in classDict.items(): - if isinstance(attr, gui.InputField): - _gui[attrName] = attr - newClassDict[attrName] = attr - newClassDict['_gui'] = _gui - return type.__new__(cls, classname, bases, newClassDict) - - -
[docs]class UserInterface(object): - ''' - This class provides the management for gui descriptions (user forms) - - Once a class is derived from this one, that class can contain Field - Descriptions, - that will be managed correctly. - - By default, the values passed to this class constructor are used to fill - the gui form fields values. - ''' - __metaclass__ = UserInterfaceType - - def __init__(self, values=None): - import copy - # : If there is an array of elements to initialize, simply try to store values on form fields - # Generate a deep copy of inherited Gui, so each User Interface instance has its own "field" set, and do not share the "fielset" with others, what can be really dangerous - # Till now, nothing bad happened cause there where being used "serialized", but this do not have to be this way - self._gui = copy.deepcopy(self._gui) # Ensure "gui" is our own instance, deep copied from base - for key, val in self._gui.iteritems(): # And refresg references to them - setattr(self, key, val) - - if values is not None: - for k, v in self._gui.iteritems(): - if k in values: - v.value = values[k] - -
[docs] def initGui(self): - ''' - This method gives the oportunity to initialize gui fields before they - are send to administartion client. - We need this because at initialization time we probably don't have the - data for gui. - - :note: This method is used as a "trick" to allow to modify default form - data for services. Services are child of Service Providers, and - will probably need data from Provider to fill initial form data. - The rest of modules will not use this, and this only will be used - when the user requests a new service or wants to modify existing - one. - :note: There is a drawback of this, and it is that there is that this - method will modify service default data. It will run fast (probably), - but may happen that two services of same type are requested at same - time, and returned data will be probable a nonsense. We will take care - of this posibility in a near version... - ''' - pass -
-
[docs] def valuesDict(self): - ''' - Returns own data needed for user interaction as a dict of key-names -> - values. The values returned must be strings. - - Example: - we have 2 text field, first named "host" and second named "port", - we can do something like this: - - .. code-block:: python - - return { 'host' : self.host, 'port' : self.port } - - (Just the reverse of :py:meth:`.__init__`, __init__ receives this - dict, valuesDict must return the dict) - - Names must coincide with fields declared. - - Returns: - Dictionary, associated with declared fields. - Default implementation returns the values stored at the gui form - fields declared. - - :note: By default, the provided method returns the correct values - extracted from form fields - - ''' - dic = {} - for k, v in self._gui.iteritems(): - if v.isType(gui.InputField.EDITABLE_LIST): - dic[k] = gui.convertToList(v.value) - elif v.isType(gui.InputField.MULTI_CHOICE_TYPE): - dic[k] = gui.convertToChoices(v.value) - else: - dic[k] = v.value - logger.debug('Dict: {0}'.format(dic)) - return dic -
-
[docs] def serializeForm(self): - ''' - All values stored at form fields are serialized and returned as a single - string - Separating char is - - The returned string is zipped and then converted to base 64 - - Note: Hidens are not serialized, they are ignored - - ''' - arr = [] - for k, v in self._gui.iteritems(): - logger.debug('serializing Key: {0}/{1}'.format(k, v.value)) - if v.isType(gui.InputField.HIDDEN_TYPE) and v.isSerializable() is False: - logger.debug('Field {0} is not serializable'.format(k)) - continue - if v.isType(gui.InputField.EDITABLE_LIST) or v.isType(gui.InputField.MULTI_CHOICE_TYPE): - logger.debug('Serializing value {0}'.format(v.value)) - val = '\001' + cPickle.dumps(v.value) - else: - val = v.value - if val is True: - val = gui.TRUE - elif val is False: - val = gui.FALSE - arr.append(k + '\003' + val) - return '\002'.join(arr).encode('zip') -
-
[docs] def unserializeForm(self, values): - ''' - This method unserializes the values previously obtained using - :py:meth:`serializeForm`, and stores - the valid values form form fileds inside its corresponding field - ''' - if values == '': # Has nothing - return - - try: - # Set all values to defaults ones - for k in self._gui.iterkeys(): - if self._gui[k].isType(gui.InputField.HIDDEN_TYPE) and self._gui[k].isSerializable() is False: - # logger.debug('Field {0} is not unserializable'.format(k)) - continue - self._gui[k].value = self._gui[k].defValue - - values = values.decode('zip') - if values == '': # Has nothing - return - - for txt in values.split('\002'): - k, v = txt.split('\003') - if k in self._gui: - try: - if v[0] == '\001': - val = cPickle.loads(v[1:].encode('utf-8')) - else: - val = v - except: - val = '' - self._gui[k].value = val - # logger.debug('Value for {0}:{1}'.format(k, val)) - except: - # Values can contain invalid characters, so we log every single char - logger.info('Invalid serialization data on {0} {1}'.format(self, values.encode('hex'))) -
- @classmethod -
[docs] def guiDescription(cls, obj=None): - ''' - This simple method generates the gui description needed by the - administration client, so it can - represent it at user interface and manage it. - - Args: - object: If not none, object that will get its "initGui" invoked - This will only happen (not to be None) in Services. - ''' - logger.debug('Active languaje for gui translation: {0}'.format(get_language())) - gui = cls - if obj is not None: - obj.initGui() # We give the "oportunity" to fill necesary gui data before providing it to client - gui = obj - - res = [] - for key, val in gui._gui.iteritems(): - logger.debug('{0} ### {1}'.format(key, val)) - res.append({'name': key, 'gui': val.guiDescription(), 'value': ''}) - - logger.debug('>>>>>>>>>>>> Gui Description: {0} -- {1}'.format(obj, res)) - return res
-
- -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/_modules/uds/models.html b/server/documentation/_build/html/_modules/uds/models.html deleted file mode 100644 index f2135ce3..00000000 --- a/server/documentation/_build/html/_modules/uds/models.html +++ /dev/null @@ -1,183 +0,0 @@ - - - - - - - - uds.models — UDS 1.0 documentation - - - - - - - - - - - - - - -
-
- - -
-
- -
-
-
-
- -

Source code for uds.models

-# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2012 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-#    * Redistributions of source code must retain the above copyright notice,
-#      this list of conditions and the following disclaimer.
-#    * Redistributions in binary form must reproduce the above copyright notice,
-#      this list of conditions and the following disclaimer in the documentation
-#      and/or other materials provided with the distribution.
-#    * Neither the name of Virtual Cable S.L. nor the names of its contributors
-#      may be used to endorse or promote products derived from this software
-#      without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''
-.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-
-from __future__ import unicode_literals
-
-__updated__ = '2014-04-24'
-
-import logging
-
-logger = logging.getLogger(__name__)
-
-
-# Utility
-from uds.models.Util import getSqlDatetime
-from uds.models.Util import optimizeTable
-from uds.models.Util import NEVER
-from uds.models.Util import NEVER_UNIX
-
-# Services
-from uds.models.Provider import Provider
-from uds.models.Service import Service
-
-# Os managers
-from uds.models.OSManager import OSManager
-
-# Transports
-from uds.models.Transport import Transport
-from uds.models.Network import Network
-
-
-# Authenticators
-from uds.models.Authenticator import Authenticator
-from uds.models.User import User
-from uds.models.UserPreference import UserPreference
-from uds.models.Group import Group
-
-
-# Provisioned services
-from uds.models.ServicesPool import DeployedService
-from uds.models.ServicesPoolPublication import DeployedServicePublication
-from uds.models.UserService import UserService
-
-# Especific log information for an user service
-from uds.models.Log import Log
-
-# Stats
-from uds.models.StatsCounters import StatsCounters
-from uds.models.StatsEvents import StatsEvents
-
-
-# General utility models, such as a database cache (for caching remote content of slow connections to external services providers for example)
-# We could use django cache (and maybe we do it in a near future), but we need to clean up things when objecs owning them are deleted
-from uds.models.Cache import Cache
-from uds.models.Config import Config
-from uds.models.Storage import Storage
-from uds.models.UniqueId import UniqueId
-
-# Workers/Schedulers related
-from uds.models.Scheduler import Scheduler
-from uds.models.DelayedTask import DelayedTask
-
- -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/_sources/api/index.txt b/server/documentation/_build/html/_sources/api/index.txt deleted file mode 100644 index 1353be23..00000000 --- a/server/documentation/_build/html/_sources/api/index.txt +++ /dev/null @@ -1,9 +0,0 @@ -============== -UDS's core API -============== - -.. toctree:: - - models - modules - /development/samples/samples diff --git a/server/documentation/_build/html/_sources/api/models.txt b/server/documentation/_build/html/_sources/api/models.txt deleted file mode 100644 index e2639d1a..00000000 --- a/server/documentation/_build/html/_sources/api/models.txt +++ /dev/null @@ -1,24 +0,0 @@ -=================== -UDS Database Models -=================== - -This section describes de models used in UDS. - -The models described here are implemented using Django models, so you can get more -info about Django models functionalty at `Django project website `_ - -The function of the models inside UDS is to provide the persistence needed by -the core and by other utility classes that are provided, such as a Cache, Storage -or unique IDs. - -Right now the models are used all over UDS, but with time we will limit the use -of this models to be done through managers or utility clases designed for that -purpose. - -.. toctree:: - - models/services - models/authentication - models/transport - models/other - diff --git a/server/documentation/_build/html/_sources/api/models/authentication.txt b/server/documentation/_build/html/_sources/api/models/authentication.txt deleted file mode 100644 index 75d64235..00000000 --- a/server/documentation/_build/html/_sources/api/models/authentication.txt +++ /dev/null @@ -1,25 +0,0 @@ -============================= -Authentication Related models -============================= -.. toctree:: - :maxdepth: 2 - -.. module:: uds.models - -.. autoclass:: Authenticator - :members: - :show-inheritance: - -.. autoclass:: User - :members: - :show-inheritance: - -.. autoclass:: Group - :members: - :show-inheritance: - -.. autoclass:: UserPreference - :members: - :show-inheritance: - - diff --git a/server/documentation/_build/html/_sources/api/models/other.txt b/server/documentation/_build/html/_sources/api/models/other.txt deleted file mode 100644 index 6c6f9e2e..00000000 --- a/server/documentation/_build/html/_sources/api/models/other.txt +++ /dev/null @@ -1,41 +0,0 @@ -============ -Other models -============ - -Environment related -------------------- - -.. module:: uds.models - -.. toctree:: - :maxdepth: 2 - -.. autoclass:: Cache - :members: - :show-inheritance: - -.. autoclass:: Storage - :members: - :show-inheritance: - -.. autoclass:: UniqueId - :members: - :show-inheritance: - -Module related --------------- - -.. autoclass:: Config - :members: - :show-inheritance: - -Scheduling and background workers related ------------------------------------------ - -.. autoclass:: Scheduler - :members: - :show-inheritance: - -.. autoclass:: DelayedTask - :members: - :show-inheritance: diff --git a/server/documentation/_build/html/_sources/api/models/services.txt b/server/documentation/_build/html/_sources/api/models/services.txt deleted file mode 100644 index c11794cf..00000000 --- a/server/documentation/_build/html/_sources/api/models/services.txt +++ /dev/null @@ -1,33 +0,0 @@ -====================== -Service Related models -====================== - -This models takes cares of persistence of the Services and its associated elements. - - DESCRIBE HIEARARCHY HERE - - -.. toctree:: - :maxdepth: 2 - -.. module:: uds.models - -.. autoclass:: Provider - :members: - :show-inheritance: - -.. autoclass:: Service - :members: - :show-inheritance: - -.. autoclass:: DeployedService - :members: - :show-inheritance: - -.. autoclass:: DeployedServicePublication - :members: - :show-inheritance: - -.. autoclass:: UserService - :members: - :show-inheritance: diff --git a/server/documentation/_build/html/_sources/api/models/transport.txt b/server/documentation/_build/html/_sources/api/models/transport.txt deleted file mode 100644 index 3fb2545c..00000000 --- a/server/documentation/_build/html/_sources/api/models/transport.txt +++ /dev/null @@ -1,18 +0,0 @@ -======================== -Transport Related models -======================== -.. toctree:: - :maxdepth: 2 - -.. module:: uds.models - -.. autoclass:: Transport - :members: - :show-inheritance: - -.. autoclass:: Network - :members: - :show-inheritance: - - - diff --git a/server/documentation/_build/html/_sources/api/modules.txt b/server/documentation/_build/html/_sources/api/modules.txt deleted file mode 100644 index 5aaebc0d..00000000 --- a/server/documentation/_build/html/_sources/api/modules.txt +++ /dev/null @@ -1,18 +0,0 @@ -=========== -UDS Modules -=========== - - -Modules are the basic component of plugin architecture of UDS. - -As so, they are spreadly covered here, and with -:doc:`samples ` must give enough information for -allowing anyone to develop their own modules. - -.. toctree:: - - modules/BaseModule - modules/FormFields - modules/ServiceModules - modules/AuthenticatorModule - diff --git a/server/documentation/_build/html/_sources/api/modules/AuthenticatorModule.txt b/server/documentation/_build/html/_sources/api/modules/AuthenticatorModule.txt deleted file mode 100644 index b210793a..00000000 --- a/server/documentation/_build/html/_sources/api/modules/AuthenticatorModule.txt +++ /dev/null @@ -1,27 +0,0 @@ -===================== -Authenticator Modules -===================== - -Authenticator modules are responsible of providing the user authentication -part inside UDS. - -They are composed of a package where it is provided and, at least, the following -elements: - - * One icon for administration interface representation. Icon is png file of - 16x16. - * One class, derived from uds.core.auths.Authenticator, providing the needed - logic for that authenticator. - * Registration of the class inside uds at package's __init__. - -All packages included inside uds.auths will automatically be imported, but -the authenticators needs to register as valid authenticators, and the best place -to do that is at the authenticator's package __init__. - -The best way to understand what you need to create your own authenticator, -is to look at :doc:`modules samples ` - - -.. toctree:: - - auths/Authenticator \ No newline at end of file diff --git a/server/documentation/_build/html/_sources/api/modules/BaseModule.txt b/server/documentation/_build/html/_sources/api/modules/BaseModule.txt deleted file mode 100644 index 294d2add..00000000 --- a/server/documentation/_build/html/_sources/api/modules/BaseModule.txt +++ /dev/null @@ -1,53 +0,0 @@ -=========== -Base Module -=========== - -The Base module is the base class used for all modules of UDS. - -In order to deveplop an UDS Module, there is a number of basic methods that you must provide. - -There are the clases that are base of BaseModule, that are: - * BaseModule_ - * Environmentable_ - * Serializable_ - * UserInterface_ - -.. toctree:: - -BaseModule ----------- - -.. module:: uds.core - -.. autoclass:: Module - :members: - -Environmentable ---------------- - -.. autoclass:: Environmentable - :members: - - -Serializable ------------- - -.. autoclass:: Serializable - :members: - - -UserInterface -------------- - - UserInterface is the class responsible for managing the Field Descriptions of modules. - - This fields descriptions are intended for allowing an easy exposition of configuration form via the - administration interface. - - You can obtain more information about user interface fields at :doc:`User interface fields types `. - -.. module:: uds.core.ui.UserInterface - -.. autoclass:: UserInterface - :members: - diff --git a/server/documentation/_build/html/_sources/api/modules/FormFields.txt b/server/documentation/_build/html/_sources/api/modules/FormFields.txt deleted file mode 100644 index 3b15da2a..00000000 --- a/server/documentation/_build/html/_sources/api/modules/FormFields.txt +++ /dev/null @@ -1,33 +0,0 @@ -Form Fields -=========== - -Form Fields are utility clases provided for allowing easy communication of modules -and administration interface. - -It helps to define the administration level forms that will be used to manage -different modules (service providers, services, authenticators, transports, ...) - -All modules that needs to be presented to admin users, use UserInterface as one -of their base class. - -Think that not all interfaces needed by different modules need a direct representation -at administration interface level, (for example, UserDeployment do not need to be -managed by administrators, nor publications, both corresponding to service modules). - -.. module:: uds.core.ui.UserInterface - -.. toctree:: - - -The types of fields provided are: - * :py:class:`gui.TextField` - * :py:class:`gui.NumericField` - * :py:class:`gui.PasswordField` - * :py:class:`gui.HiddenField` - * :py:class:`gui.CheckBoxField` - * :py:class:`gui.ChoiceField` - * :py:class:`gui.MultiChoiceField` - * :py:class:`gui.EditableList` - -.. autoclass:: gui - :members: InputField, TextField, NumericField, PasswordField, HiddenField, CheckBoxField, ChoiceField, MultiChoiceField, EditableList diff --git a/server/documentation/_build/html/_sources/api/modules/ServiceModules.txt b/server/documentation/_build/html/_sources/api/modules/ServiceModules.txt deleted file mode 100644 index a3c9c1e4..00000000 --- a/server/documentation/_build/html/_sources/api/modules/ServiceModules.txt +++ /dev/null @@ -1,53 +0,0 @@ -=============== -Service Modules -=============== - -Service modules are responsible for giving the user consumable ip services for -users. - -They are composed of a package where it is provided, at least, the following -elements: - - * One icon for administration interface representation. Icon is png file of - 16x16. - * A Full tree of classes, derived from interfaces (descrived below) - * Registration of the class inside UDS at package's __init__. - -All packages included inside uds.services will automatically be imported, but -the service providers (root of service trees) needs to register as valid -providers, and the best place to do that is at the authenticator's package __init__. - -the Full tree of classes needed by the service modules are: - - * **Provider**: This is the root tree of any service. It represents an agrupation - of services under the same root. As sample, a service provider can be an - Open nebula server, an VC, or whataver is a common root for a number of services. - * **Service**: This is the representation of what a service will give to an user. - As such, this is not what the user will consume, but this is more the definition - of what the user will consume. Before assigning a service to an user, the admin - will need to declare a "Deployed Service", that is a definition, using this service - an a number of other modules, of what the user will consume. Inside this service - we need to provide the information needed for deploying an user consumable item, - such as if it needs to be "prepared", if it supports cache, if it must be assigned - to an user "manually", and all the custom data that the user deployments and publications - will need. - * **Publication**. Some services, before being assigned to users, needs some kind of - preparation. This process of preparation is called here "publication". The service - itself will declare if it needs a publication and, if needed, who is responsible of - that. Services with needed publication will use this kind of class to provide - such preparation. - * **User Deployment**. This is what will provide the final user consumable service. - The user deployment is the last responsible for, using the provided service - and provided publication (if needed), to create the elements that the user will - consume. - -The best way to understand what you need to create your own services, -is to look at :doc:`modules samples ` - -.. toctree:: - - services/Provider - services/Service - services/Publication - services/UserDeployment - services/Exceptions \ No newline at end of file diff --git a/server/documentation/_build/html/_sources/api/modules/auths/Authenticator.txt b/server/documentation/_build/html/_sources/api/modules/auths/Authenticator.txt deleted file mode 100644 index f30d9fb7..00000000 --- a/server/documentation/_build/html/_sources/api/modules/auths/Authenticator.txt +++ /dev/null @@ -1,15 +0,0 @@ -======================= -Authenticator Interface -======================= - -The authenticator class is in fact an interface. UDS authenticators must derive -from this, and must provide the logic so UDS can manage the users and groups that -an authenticator provides. - - -.. toctree:: - -.. module:: uds.core.auths - -.. autoclass:: Authenticator - :members: diff --git a/server/documentation/_build/html/_sources/api/modules/services/Exceptions.txt b/server/documentation/_build/html/_sources/api/modules/services/Exceptions.txt deleted file mode 100644 index f137b05b..00000000 --- a/server/documentation/_build/html/_sources/api/modules/services/Exceptions.txt +++ /dev/null @@ -1,9 +0,0 @@ -================== -Service Exceptions -================== - -.. toctree:: - -.. automodule:: uds.core.services.Exceptions - :members: - diff --git a/server/documentation/_build/html/_sources/api/modules/services/Provider.txt b/server/documentation/_build/html/_sources/api/modules/services/Provider.txt deleted file mode 100644 index ad7fde37..00000000 --- a/server/documentation/_build/html/_sources/api/modules/services/Provider.txt +++ /dev/null @@ -1,27 +0,0 @@ -================== -Provider interface -================== - -The provider class is the root class of the module. It keeps the common information -needed by all services provided by this "provider". - -Think about a provider as the class that will declare all stuff neded by core and -child services to provide and administrator user a way to create services to be -consumed by users. - -One good example is a Virtualization server. Here we keep information about that -server (ip address, protocol, ....) and services provided by that "provider" will -make use of that information to make the administrator not provide it once an again -for every service we put on that virtualization server. - -.. toctree:: - -.. module:: uds.core.services - -For a detailed example of a service provider, you can see the provided -:doc:`provider sample ` - -.. autoclass:: ServiceProvider - :members: - - diff --git a/server/documentation/_build/html/_sources/api/modules/services/Publication.txt b/server/documentation/_build/html/_sources/api/modules/services/Publication.txt deleted file mode 100644 index 290e9150..00000000 --- a/server/documentation/_build/html/_sources/api/modules/services/Publication.txt +++ /dev/null @@ -1,30 +0,0 @@ -===================== -Publication interface -===================== - -The publication class is in fact an interface. It represents, in those case that -a service needs the preparation, the logic for that preparation. - -So the publication class is responsible of doing whatever is needed to get the -deployed service (that is the compound of a service, an os manager, transports -and authenticators) ready for deploying user consumables. - -Note that not all services needs to implement this class, only in those case -where that service declares that a publication is needed. - - -As functional sample of a publication, imagine that we want to assing KVM COW -machines to users. The publication class can make a clone of the base machine -(that the service itself has taken note of which one is), and then the COWs will -be created from this cloned machine. - -.. toctree:: - -.. module:: uds.core.services - -For a detailed example of a service provider, you can see the provided -:doc:`publication sample ` - -.. autoclass:: Publication - :members: - diff --git a/server/documentation/_build/html/_sources/api/modules/services/Service.txt b/server/documentation/_build/html/_sources/api/modules/services/Service.txt deleted file mode 100644 index 6e26c128..00000000 --- a/server/documentation/_build/html/_sources/api/modules/services/Service.txt +++ /dev/null @@ -1,25 +0,0 @@ -================= -Service interface -================= - -The service class is in fact an interface. It represents the base for all user -deployments (that is, consumable user services) that will be provided. - -As such, the service is responsible for keeping the information that, at deployments, -will be neded by provided user consumable services. - -A good sample of a service can be a KVM machine that will be copied COW and that COWs -will be assigned to users. In that case, we will collect which machine will be copied, -where it is to be copied, an a few more params that the user deployments will need. - -.. toctree:: - -.. module:: uds.core.services - -For a detailed example of a service provider, you can see the provided -:doc:`service sample ` - -.. autoclass:: Service - :members: - - diff --git a/server/documentation/_build/html/_sources/api/modules/services/UserDeployment.txt b/server/documentation/_build/html/_sources/api/modules/services/UserDeployment.txt deleted file mode 100644 index 6f97c2de..00000000 --- a/server/documentation/_build/html/_sources/api/modules/services/UserDeployment.txt +++ /dev/null @@ -1,23 +0,0 @@ -======================== -UserDeployment interface -======================== - -The user deployment class is in fact an interface. It represents the final consumable -that will be assigned to an user, and, as such, it must provide some mechanisms to -allow core to manage those consumables. - -A good sample of an user deployment can be a KVM Virtual Machine, cloned COW from -another, and assigned to an user. - -.. toctree:: - -.. module:: uds.core.services - -For detailed examples of a couple of user deployments, you can see the provided -:doc:`service sample ` and -:doc:`service sample ` - -.. autoclass:: UserDeployment - :members: - - diff --git a/server/documentation/_build/html/_sources/development/architecture.txt b/server/documentation/_build/html/_sources/development/architecture.txt deleted file mode 100644 index 0bf2b1fd..00000000 --- a/server/documentation/_build/html/_sources/development/architecture.txt +++ /dev/null @@ -1,36 +0,0 @@ -================== -UDS's architecture -================== - -This section covers the current UDS Arquiceture & diagrams. - -UDS is built on the Django web framework, which itself is -built on Python, thus MyTARDIS follows the architectural model -of Django. - -Component Architecture ----------------------- - -This diagram shows the major components of UDS. - -* Core components - * `Apache Http `_ - * `WSGI `_ - * `Django `_ - * `Python `_. - -* RDBMS - UDS is currently being developed/testing on Mysql 5 Database. - May other databases will work also, but no one else has been tested. - -Functional Architecture ------------------------ - -UDS is build using Django as base support for Web acess and Database access. - -Over this, UDS uses the following diagram: - -DIAGRAM - -Core - Basic core funcionality. diff --git a/server/documentation/_build/html/_sources/development/contributing.txt b/server/documentation/_build/html/_sources/development/contributing.txt deleted file mode 100644 index ec04f5a4..00000000 --- a/server/documentation/_build/html/_sources/development/contributing.txt +++ /dev/null @@ -1,3 +0,0 @@ -=================== -Contributing to UDS -=================== diff --git a/server/documentation/_build/html/_sources/development/repository.txt b/server/documentation/_build/html/_sources/development/repository.txt deleted file mode 100644 index 36b5e39b..00000000 --- a/server/documentation/_build/html/_sources/development/repository.txt +++ /dev/null @@ -1,3 +0,0 @@ -============== -UDS Repository -============== \ No newline at end of file diff --git a/server/documentation/_build/html/_sources/development/samples/auths/Authenticator.txt b/server/documentation/_build/html/_sources/development/samples/auths/Authenticator.txt deleted file mode 100644 index f4394981..00000000 --- a/server/documentation/_build/html/_sources/development/samples/auths/Authenticator.txt +++ /dev/null @@ -1,15 +0,0 @@ -==================== -Sample Authenticator -==================== - -The authenticator is the responsible of providing the needed mechanisms to UDS for -user authentication. - -As thatm this must provide a number of methods, that will allow UDS to manage -things the way it needs to. (Access users, groups, check credentials, etc...) - -Here you can :download:`Download sample ` - - -.. literalinclude:: /_downloads/samples/auths/SampleAuth.py - :linenos: diff --git a/server/documentation/_build/html/_sources/development/samples/samples.txt b/server/documentation/_build/html/_sources/development/samples/samples.txt deleted file mode 100644 index 604170bf..00000000 --- a/server/documentation/_build/html/_sources/development/samples/samples.txt +++ /dev/null @@ -1,100 +0,0 @@ -=================== -UDS Modules Samples -=================== - -In this section we cover basic samples of the different kind of mudules supported -by UDS. - -UDS is designed in a modular way, meaning this that it has a core that allows -a number of modules to get plugged inside the whole system. - -This modules are: - - * Services, including all stuff around them. - * Transports - * OS Managers - * Authenticators - -This secion will try to give sample of every module, what it must do and how this -must be done. - -Service Sample --------------- - -A service is composed of several classes. This classes depends on how the service works. - -This are: - - * *Provider*, that is simply the "root" where services - descent, so we can configure just one part of the service parameters and rest - of them at service level. - - One sample of provider is a virtualization server, such as oVirt, Open Nebula, or - others like it. We can keep info about server at provider level, and info about - what we need in an specific service at service level. - - * *Service*, that is a service definition, that must be deployed at a later stage - to offer something to the users. - - Following our previous sample, if provider was an oVirt server, a service can - be a Virtual Machine cloned COW. - - * *Publication*, This class is optional. If service declares that needs a - publication for deployment of user instance, this class implements exactly - that, the publication for that service. Publications are in fact a way of - allowing services to prepare something in a stage prior to creating the - user consumable services. - - Following our previous sample, if provider was an oVirt Server and the service - was a Virtual Machine cloned for Cow, the poblication can be a full clone of - the service machine for making COWS from this one. - - * *DeployedService*, This class is the user consumed service itself. After a - service is created, it must be deployed, and deploy will mean that there will - be "instances" of that service (User Deployments) that will be consumed by - users. - - Following our previous sample, if the publication was a full copy machine, - an deployed service can be a machine in COW format using as base that - machine. - - -From theese, the only not really needed is Publication. Publication will only be -needed whenever a service needs a "preparation" before creating the user consumable -deployed services. For a service to be usable, we will need the full tree, meaning -this that we will provide all controllers (Provider, service or services, publication -or publications, deployed service or deployed services.). - -All class belonging to a service must be grouped under the same package, and we -well need to register this package for the system to recognize it as service. - -For this, we must register the Provider, that has references to rest of items. - -Provider declares which services it provides. Services declares which publication -and deployed service it needs. Provider can declare multiples services it offers, -but services has at most one publication and exatly one deployed service. - -So, by registering the Provider, we register the whole tree provided by de package. - -Here you can find samples of every class needed for creating a new package of -services. - -.. toctree:: - - services/whatisneeded - services/Provider - services/Service - services/Publication - services/DeployedServiceOne - services/DeployedServiceTwo - - -Authenticator Sample --------------------- - -An authenticator is composed of a single class, derived from :py:class:`uds.core.auths.Authenticator`. - -Here you can find a sample of an authenticator. - -.. toctree:: - auths/Authenticator \ No newline at end of file diff --git a/server/documentation/_build/html/_sources/development/samples/services/DeployedServiceOne.txt b/server/documentation/_build/html/_sources/development/samples/services/DeployedServiceOne.txt deleted file mode 100644 index abf2b43d..00000000 --- a/server/documentation/_build/html/_sources/development/samples/services/DeployedServiceOne.txt +++ /dev/null @@ -1,20 +0,0 @@ -========================== -Sample User Deployment One -========================== - -User deployments are the class that are responsible for creating the ultimate consumable -user service, that is, for managing that whenever the core requests a new service for -an user, this classes will take responsibility to provide it. - -Here we cover SampleUserDeploymentOne that is for SampleServiceOne, do not needs to be -published and do not uses cache. - -You can easily follow the code to see what it does, and what you have to do if you -want to provide a new one. - -:download:`Download sample ` - - -.. literalinclude:: /_downloads/samples/services/SampleUserDeploymentOne.py - :linenos: - diff --git a/server/documentation/_build/html/_sources/development/samples/services/DeployedServiceTwo.txt b/server/documentation/_build/html/_sources/development/samples/services/DeployedServiceTwo.txt deleted file mode 100644 index f3664a74..00000000 --- a/server/documentation/_build/html/_sources/development/samples/services/DeployedServiceTwo.txt +++ /dev/null @@ -1,20 +0,0 @@ -========================== -Sample User Deployment Two -========================== - -User deployments are the class that are responsible for creating the ultimate consumable -user service, that is, for managing that whenever the core requests a new service for -an user, this classes will take responsibility to provide it. - -Here we cover SampleUserDeploymentTwo that is for SampleServiceTwo, needs to be -published and has L1 and L2 cache items. - -You can easily follow the code to see what it does, and what you have to do if you -want to provide a new one. - -:download:`Download sample ` - - -.. literalinclude:: /_downloads/samples/services/SampleUserDeploymentTwo.py - :linenos: - diff --git a/server/documentation/_build/html/_sources/development/samples/services/Provider.txt b/server/documentation/_build/html/_sources/development/samples/services/Provider.txt deleted file mode 100644 index b792a642..00000000 --- a/server/documentation/_build/html/_sources/development/samples/services/Provider.txt +++ /dev/null @@ -1,19 +0,0 @@ -======================= -Sample Service Provider -======================= - -The service provider is the top of the tree of services needed clases. -It main function is to provide a base for services, where this services contains -a common parent that is, for example, a server, a range of IPs, etc... - -This sample covers a simple service provider, explains also a bit about FormFields -and shows what tasks must be done by a service provider. - -You can easily follow the code to see what it does, and what you have to do if you -want to provide a new one. - -:download:`Download sample ` - - -.. literalinclude:: /_downloads/samples/services/SampleProvider.py - :linenos: diff --git a/server/documentation/_build/html/_sources/development/samples/services/Publication.txt b/server/documentation/_build/html/_sources/development/samples/services/Publication.txt deleted file mode 100644 index 7d82cc0c..00000000 --- a/server/documentation/_build/html/_sources/development/samples/services/Publication.txt +++ /dev/null @@ -1,23 +0,0 @@ -================== -Sample publication -================== - -A publication is a class responsible for making a service defined available to be -consumed by users. - -Not all services needs publications as you have already seen if you are following -the samples. Publications are only needed for services that needs some kind of -preparation, as, for example, with Virtual Machines, clone the base virtual machine -so we can create COW copies from this clone. This kind of behavior needs a preparation -step, that is efectively to clone the virtual base, and that will be the task of a -publication for that kind of services. - -You can easily follow the code to see what it does, and what you have to do if you -want to provide a new one. - -:download:`Download sample ` - - -.. literalinclude:: /_downloads/samples/services/SamplePublication.py - :linenos: - diff --git a/server/documentation/_build/html/_sources/development/samples/services/Service.txt b/server/documentation/_build/html/_sources/development/samples/services/Service.txt deleted file mode 100644 index 49482e70..00000000 --- a/server/documentation/_build/html/_sources/development/samples/services/Service.txt +++ /dev/null @@ -1,15 +0,0 @@ -============== -Sample service -============== - -Here we cover two services. ServiceOne, that do not needs publication and -ServiceTwo, that needs publication. - -This sample should be enought to guide you through the creation of a new service. - -:download:`Download sample ` - - -.. literalinclude:: /_downloads/samples/services/SampleService.py - :linenos: - diff --git a/server/documentation/_build/html/_sources/development/samples/services/whatisneeded.txt b/server/documentation/_build/html/_sources/development/samples/services/whatisneeded.txt deleted file mode 100644 index 20eb9ffb..00000000 --- a/server/documentation/_build/html/_sources/development/samples/services/whatisneeded.txt +++ /dev/null @@ -1,32 +0,0 @@ -Needs for a service package ---------------------------- - -For a new package of services, you will need: - - - * One package (python package), of course :-). - * One icon for the provider, in png format an 16x16 size. Colours is left - to your election. This icon will be informed at Provider class. - * One icon for every service that the provider will expose. Same as provider - icons. These icons will be informed at Service class. Every single class - must provide its own icon. - * Registering the provider. For the samples show here, this will be at - __init__ of the package. - - The contents of the sample package __init__ file is: - - .. literalinclude:: /_downloads/samples/services/__init__.py - :linenos: - - :download:`Download sample ` - - * Put the package under the apropiate uds package. In the case of - services, this is under "uds.core". - - Core will look for all packages under "uds.services" and import them at - initialization of the server, so every package under this will get their - __init__ called, where we register the provider. - - * Follow the samples provided here as base - - \ No newline at end of file diff --git a/server/documentation/_build/html/_sources/index.txt b/server/documentation/_build/html/_sources/index.txt deleted file mode 100644 index b7e3f500..00000000 --- a/server/documentation/_build/html/_sources/index.txt +++ /dev/null @@ -1,71 +0,0 @@ -.. _index: - -=================== -UDS's documentation -=================== - -This documentation is provided so we can understand (hopefully) UDS, its internals, -and everything about it. - -Right now the documentation is not too ritch, but we are working on it so it will -get the needed level for this kind of project. - - -First Steps -=========== - -* **From scratch:** - :doc:`Overview ` | - :doc:`Installation ` - -.. toctree:: - :hidden: - - intro/overview - intro/install - -The internals of uds -==================== - -.. toctree:: - - development/architecture - development/development - api/index - -UDS Open source project -======================= - -* **Community:** - :doc:`How to get involved ` | - :doc:`The UDS source code repository ` - -.. toctree:: - :hidden: - - development/contributing - development/repository - - -Acknowledgements -================ - -We want to thaks all the people that has contributed to de project, an also -other Open Source project used to improve this one. - -List of other software used to build UDS: - - * `Django `_ - * `XML-RPC.NET Copyright (c) 2006 Charles Cook `_ - * `Darkglass reworked graphics `_ - * `Crystal project `_ - * `South `_ - * `Jsch `_ - * `JQuery `_ - * `Plugin detect library `_ - * `JQuery UI `_ - -I hope to do nor forget anythinh here, if i do, please, report it so we can credit -to every project that UDS makes use of. - - \ No newline at end of file diff --git a/server/documentation/_build/html/_sources/intro/install.txt b/server/documentation/_build/html/_sources/intro/install.txt deleted file mode 100644 index 39b17dcb..00000000 --- a/server/documentation/_build/html/_sources/intro/install.txt +++ /dev/null @@ -1,46 +0,0 @@ -============== -Installing UDS -============== - -In order to run UDS, you will need: - - * Django Server 1.4 - * South module for Django - * Mysql libraries for python - * Mysql Database - * Ldap Libraries for python - * Criptographic package for python - -Default transports are compiled in binary form, and keeped inside UDS repository, -so you won't need Java to put UDS to work. - -Once you have all of this, you will have to follow these steps: - - * Obtain UDS from repository, you can see how to do this from -:doc:`repository access documentation ` - * Configure a database for use with UDS. To do this, simple create a database - inside your Mysql server, and a user with all permissions in this database. - * Configure UDS settings. - Inside "server" folder, you will find "settings.py". This file contains the - configuration of UDS (if it runs in debug mode, ..). The most important part - here is the DATABASES section, where you will set up the database that UDS - will use. Simply change "host", "port", "udsername", "password" and "name" - to match your database settings. - Here, we have to take care that, if we left UDS in debug mode, Django will keep - track of all petitions to UDS, so memory will grow constantly. Do not get scared - if you see that UDS starts to waste too much memory. Simply restart it or, if it's - intended to be running for a while, set DEBUG variable to "False". - Important sections are: - - * Create initial database tables. - Inside UDS folder, where you downloaded it, you will see a "manage.py". - This python application is the responsible for managing UDS, from database creation, - migrations, backend start & stop, web server (testing web server btw), ... - To create initial databases, we will do: - - python manage.py sync - python manage.py migrate - - Now we have all databases and everything that UDS needs for starting up ready... :-) - - diff --git a/server/documentation/_build/html/_sources/intro/overview.txt b/server/documentation/_build/html/_sources/intro/overview.txt deleted file mode 100644 index 2e8705d7..00000000 --- a/server/documentation/_build/html/_sources/intro/overview.txt +++ /dev/null @@ -1,32 +0,0 @@ -=============== -UDS at a glance -=============== - -UDS has been developed to make a single open source server that allows the access -to the growing ip services catalog. - -For this, we have try to make a framework that allows the use of any ip service, -focusing initially at VDI because it's the mayor need for the people we have -contacted initially . - -Also, first version of UDS has been developed "fast" (very fast indeed), so now -we need to make a revision an adapt de code of the framework so it's more -'pythonic'. (Think that i start learning python one day like this, and less than -a week later i started this proyect). So think that, althouth UDS is fully -functional, has been tested and is stable enought for any production environment, -there is a lot of work to do. - -As so, UDS not only provides default modules for a lot of things (virtualization -provider, authentication providers, protocols, ...), but also provides the core -itself to allow anyone who wants or needs something, incorporate it to the -catalog of UDS in an easy and fast way. - -* In order to use UDS, you must simply :doc:`Follow the installation guide `. - -* In order to design and implement your own modules, you must: - - * :doc:`Understand the architecture ` - * :doc:`See some module samples ` - -* In order to contribute, you must install UDS, understand it, an read the - :doc:`contributing guide ` \ No newline at end of file diff --git a/server/documentation/_build/html/_static/ajax-loader.gif b/server/documentation/_build/html/_static/ajax-loader.gif deleted file mode 100644 index 61faf8cab23993bd3e1560bff0668bd628642330..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 673 zcmZ?wbhEHb6krfw_{6~Q|Nno%(3)e{?)x>&1u}A`t?OF7Z|1gRivOgXi&7IyQd1Pl zGfOfQ60;I3a`F>X^fL3(@);C=vM_KlFfb_o=k{|A33hf2a5d61U}gjg=>Rd%XaNQW zW@Cw{|b%Y*pl8F?4B9 zlo4Fz*0kZGJabY|>}Okf0}CCg{u4`zEPY^pV?j2@h+|igy0+Kz6p;@SpM4s6)XEMg z#3Y4GX>Hjlml5ftdH$4x0JGdn8~MX(U~_^d!Hi)=HU{V%g+mi8#UGbE-*ao8f#h+S z2a0-5+vc7MU$e-NhmBjLIC1v|)9+Im8x1yacJ7{^tLX(ZhYi^rpmXm0`@ku9b53aN zEXH@Y3JaztblgpxbJt{AtE1ad1Ca>{v$rwwvK(>{m~Gf_=-Ro7Fk{#;i~+{{>QtvI yb2P8Zac~?~=sRA>$6{!(^3;ZP0TPFR(G_-UDU(8Jl0?(IXu$~#4A!880|o%~Al1tN diff --git a/server/documentation/_build/html/_static/basic.css b/server/documentation/_build/html/_static/basic.css deleted file mode 100644 index 967e36ce..00000000 --- a/server/documentation/_build/html/_static/basic.css +++ /dev/null @@ -1,537 +0,0 @@ -/* - * basic.css - * ~~~~~~~~~ - * - * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/* -- main layout ----------------------------------------------------------- */ - -div.clearer { - clear: both; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -/* -- sidebar --------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - padding: 10px 5px 0 10px; -} - -div.sphinxsidebar { - float: left; - width: 230px; - margin-left: -100%; - font-size: 90%; -} - -div.sphinxsidebar ul { - list-style: none; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - -div.sphinxsidebar #searchbox input[type="text"] { - width: 170px; -} - -div.sphinxsidebar #searchbox input[type="submit"] { - width: 30px; -} - -img { - border: 0; - max-width: 100%; -} - -/* -- search page ----------------------------------------------------------- */ - -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li div.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* -- index page ------------------------------------------------------------ */ - -table.contentstable { - width: 90%; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* -- general index --------------------------------------------------------- */ - -table.indextable { - width: 100%; -} - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable dl, table.indextable dd { - margin-top: 0; - margin-bottom: 0; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -div.modindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -div.genindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -/* -- general body styles --------------------------------------------------- */ - -a.headerlink { - visibility: hidden; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink { - visibility: visible; -} - -div.body p.caption { - text-align: inherit; -} - -div.body td { - text-align: left; -} - -.field-list ul { - padding-left: 1em; -} - -.first { - margin-top: 0 !important; -} - -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -img.align-left, .figure.align-left, object.align-left { - clear: left; - float: left; - margin-right: 1em; -} - -img.align-right, .figure.align-right, object.align-right { - clear: right; - float: right; - margin-left: 1em; -} - -img.align-center, .figure.align-center, object.align-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -.align-left { - text-align: left; -} - -.align-center { - text-align: center; -} - -.align-right { - text-align: right; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar { - margin: 0 0 0.5em 1em; - border: 1px solid #ddb; - padding: 7px 7px 0 7px; - background-color: #ffe; - width: 40%; - float: right; -} - -p.sidebar-title { - font-weight: bold; -} - -/* -- topics ---------------------------------------------------------------- */ - -div.topic { - border: 1px solid #ccc; - padding: 7px 7px 0 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -div.admonition dl { - margin-bottom: 0; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -/* -- tables ---------------------------------------------------------------- */ - -table.docutils { - border: 0; - border-collapse: collapse; -} - -table.docutils td, table.docutils th { - padding: 1px 8px 1px 5px; - border-top: 0; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; -} - -table.field-list td, table.field-list th { - border: 0 !important; -} - -table.footnote td, table.footnote th { - border: 0 !important; -} - -th { - text-align: left; - padding-right: 5px; -} - -table.citation { - border-left: solid 1px gray; - margin-left: 1px; -} - -table.citation td { - border-bottom: none; -} - -/* -- other body styles ----------------------------------------------------- */ - -ol.arabic { - list-style: decimal; -} - -ol.loweralpha { - list-style: lower-alpha; -} - -ol.upperalpha { - list-style: upper-alpha; -} - -ol.lowerroman { - list-style: lower-roman; -} - -ol.upperroman { - list-style: upper-roman; -} - -dl { - margin-bottom: 15px; -} - -dd p { - margin-top: 0px; -} - -dd ul, dd table { - margin-bottom: 10px; -} - -dd { - margin-top: 3px; - margin-bottom: 10px; - margin-left: 30px; -} - -dt:target, .highlighted { - background-color: #fbe54e; -} - -dl.glossary dt { - font-weight: bold; - font-size: 1.1em; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -.optional { - font-size: 1.3em; -} - -.versionmodified { - font-style: italic; -} - -.system-message { - background-color: #fda; - padding: 5px; - border: 3px solid red; -} - -.footnote:target { - background-color: #ffa; -} - -.line-block { - display: block; - margin-top: 1em; - margin-bottom: 1em; -} - -.line-block .line-block { - margin-top: 0; - margin-bottom: 0; - margin-left: 1.5em; -} - -.guilabel, .menuselection { - font-family: sans-serif; -} - -.accelerator { - text-decoration: underline; -} - -.classifier { - font-style: oblique; -} - -abbr, acronym { - border-bottom: dotted 1px; - cursor: help; -} - -/* -- code displays --------------------------------------------------------- */ - -pre { - overflow: auto; - overflow-y: hidden; /* fixes display issues on Chrome browsers */ -} - -td.linenos pre { - padding: 5px 0px; - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - margin-left: 0.5em; -} - -table.highlighttable td { - padding: 0 0.5em 0 0.5em; -} - -tt.descname { - background-color: transparent; - font-weight: bold; - font-size: 1.2em; -} - -tt.descclassname { - background-color: transparent; -} - -tt.xref, a tt { - background-color: transparent; - font-weight: bold; -} - -h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { - background-color: transparent; -} - -.viewcode-link { - float: right; -} - -.viewcode-back { - float: right; - font-family: sans-serif; -} - -div.viewcode-block:target { - margin: -1px -10px; - padding: 0 10px; -} - -/* -- math display ---------------------------------------------------------- */ - -img.math { - vertical-align: middle; -} - -div.body div.math p { - text-align: center; -} - -span.eqno { - float: right; -} - -/* -- printout stylesheet --------------------------------------------------- */ - -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0 !important; - width: 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - #top-link { - display: none; - } -} \ No newline at end of file diff --git a/server/documentation/_build/html/_static/comment-bright.png b/server/documentation/_build/html/_static/comment-bright.png deleted file mode 100644 index 551517b8c83b76f734ff791f847829a760ad1903..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3500 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 A2LJ#7 diff --git a/server/documentation/_build/html/_static/comment.png b/server/documentation/_build/html/_static/comment.png deleted file mode 100644 index 92feb52b8824c6b0f59b658b1196c61de9162a95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3445 zcmV-*4T|!KP)Oz@Z0f2-7z;ux~O9+4z06=<WDR*FRcSTFz- zW=q650N5=6FiBTtNC2?60Km==3$g$R3;-}uh=nNt1bYBr$Ri_o0EC$U6h`t_Jn<{8 z5a%iY0C<_QJh>z}MS)ugEpZ1|S1ukX&Pf+56gFW3VVXcL!g-k)GJ!M?;PcD?0HBc- z5#WRK{dmp}uFlRjj{U%*%WZ25jX z{P*?XzTzZ-GF^d31o+^>%=Ap99M6&ogks$0k4OBs3;+Bb(;~!4V!2o<6ys46agIcq zjPo+3B8fthDa9qy|77CdEc*jK-!%ZRYCZvbku9iQV*~a}ClFY4z~c7+0P?$U!PF=S z1Au6Q;m>#f??3%Vpd|o+W=WE9003S@Bra6Svp>fO002awfhw>;8}z{#EWidF!3EsG z3;bXU&9EIRU@z1_9W=mEXoiz;4lcq~xDGvV5BgyU zp1~-*fe8db$Osc*A=-!mVv1NJjtCc-h4>-CNCXm#Bp}I%6j35eku^v$Qi@a{RY)E3 zJ#qp$hg?Rwkvqr$GJ^buyhkyVfwECO)C{#lxu`c9ghrwZ&}4KmnvWKso6vH!8a<3Q zq36)6Xb;+tK10Vaz~~qUGsJ8#F2=(`u{bOVlVi)VBCHIn#u~6ztOL7=^<&SmcLWlF zMZgI*1b0FpVIDz9SWH+>*hr`#93(Um+6gxa1B6k+CnA%mOSC4s5&6UzVlpv@SV$}* z))J2sFA#f(L&P^E5{W}HC%KRUNwK6<(h|}}(r!{C=`5+6G)NjFlgZj-YqAG9lq?`C z$c5yc>d>VnA`E_*3F2Qp##d8RZb=H01_mm@+|Cqnc9PsG(F5HIG_C zt)aG3uTh7n6Et<2In9F>NlT@zqLtGcXcuVrX|L#Xx)I%#9!{6gSJKPrN9dR61N3(c z4Tcqi$B1Vr8Jidf7-t!G7_XR2rWwr)$3XQ?}=hpK0&Z&W{| zep&sA23f;Q!%st`QJ}G3cbou<7-yIK2z4nfCCCtN2-XOGSWo##{8Q{ATurxr~;I`ytDs%xbip}RzP zziy}Qn4Z2~fSycmr`~zJ=lUFdFa1>gZThG6M+{g7vkW8#+YHVaJjFF}Z#*3@$J_By zLtVo_L#1JrVVB{Ak-5=4qt!-@Mh}c>#$4kh<88)m#-k<%CLtzEP3leVno>={htGUuD;o7bD)w_sX$S}eAxwzy?UvgBH(S?;#HZiQMoS*2K2 zT3xe7t(~nU*1N5{rxB;QPLocnp4Ml>u<^FZwyC!nu;thW+pe~4wtZn|Vi#w(#jeBd zlf9FDx_yoPJqHbk*$%56S{;6Kv~mM9!g3B(KJ}#RZ#@)!hR|78Dq|Iq-afF%KE1Brn_fm;Im z_u$xr8UFki1L{Ox>G0o)(&RAZ;=|I=wN2l97;cLaHH6leTB-XXa*h%dBOEvi`+x zi?=Txl?TadvyiL>SuF~-LZ;|cS}4~l2eM~nS7yJ>iOM;atDY;(?aZ^v+mJV$@1Ote z62cPUlD4IWOIIx&SmwQ~YB{nzae3Pc;}r!fhE@iwJh+OsDs9zItL;~pu715HdQEGA zUct(O!LkCy1<%NCg+}G`0PgpNm-?d@-hMgNe6^V+j6x$b<6@S<$+<4_1hi}Ti zncS4LsjI}fWY1>OX6feMEuLErma3QLmkw?X+1j)X-&VBk_4Y;EFPF_I+q;9dL%E~B zJh;4Nr^(LEJ3myURP{Rblsw%57T)g973R8o)DE9*xN#~;4_o$q%o z4K@u`jhx2fBXC4{U8Qn{*%*B$Ge=nny$HAYq{=vy|sI0 z_vss+H_qMky?OB#|JK!>IX&II^LlUh#rO5!7TtbwC;iULyV-Xq?ybB}ykGP{?LpZ? z-G|jbTmIbG@7#ZCz;~eY(cDM(28Dyq{*m>M4?_iynUBkc4TkHUI6gT!;y-fz>HMcd z&t%Ugo)`Y2{>!cx7B7DI)$7;J(U{Spm-3gBzioV_{p!H$8L!*M!p0uH$#^p{Ui4P` z?ZJ24cOCDe-w#jZd?0@)|7iKK^;6KN`;!@ylm7$*nDhK&GcDTy000JJOGiWi{{a60 z|De66lK=n!32;bRa{vGf6951U69E94oEQKA00(qQO+^RV2nzr)JMUJvzW@LNr%6OX zR5;6Zk;`k`RTRfR-*ac2G}PGmXsUu>6ce?Lsn$m^3Q`48f|TwQ+_-Qh=t8Ra7nE)y zf@08(pjZ@22^EVjG*%30TJRMkBUC$WqZ73uoiv&J=APqX;!v%AH}`Vx`999MVjXwy z{f1-vh8P<=plv&cZ>p5jjX~Vt&W0e)wpw1RFRuRdDkwlKb01tp5 zP=trFN0gH^|L4jJkB{6sCV;Q!ewpg-D&4cza%GQ*b>R*=34#dW;ek`FEiB(vnw+U# zpOX5UMJBhIN&;D1!yQoIAySC!9zqJmmfoJqmQp}p&h*HTfMh~u9rKic2oz3sNM^#F zBIq*MRLbsMt%y{EHj8}LeqUUvoxf0=kqji62>ne+U`d#%J)abyK&Y`=eD%oA!36<)baZyK zXJh5im6umkS|_CSGXips$nI)oBHXojzBzyY_M5K*uvb0_9viuBVyV%5VtJ*Am1ag# zczbv4B?u8j68iOz<+)nDu^oWnL+$_G{PZOCcOGQ?!1VCefves~rfpaEZs-PdVYMiV z98ElaJ2}7f;htSXFY#Zv?__sQeckE^HV{ItO=)2hMQs=(_ Xn!ZpXD%P(H00000NkvXXu0mjf;VkfoEM{Qf z76xHPhFNnYfP(BLp1!W^HyC+E#mt?nx10eANtU=qlsM<-=BDPAFgO>bCYGe8D3oWG zWGJ|M`UZqI@`(c#nR~i8hHzY8+H1+jpulh_>fir3VfEN66+L= 0 && !jQuery(node.parentNode).hasClass(className)) { - var span = document.createElement("span"); - span.className = className; - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - node.parentNode.insertBefore(span, node.parentNode.insertBefore( - document.createTextNode(val.substr(pos + text.length)), - node.nextSibling)); - node.nodeValue = val.substr(0, pos); - } - } - else if (!jQuery(node).is("button, select, textarea")) { - jQuery.each(node.childNodes, function() { - highlight(this); - }); - } - } - return this.each(function() { - highlight(this); - }); -}; - -/** - * Small JavaScript module for the documentation. - */ -var Documentation = { - - init : function() { - this.fixFirefoxAnchorBug(); - this.highlightSearchWords(); - this.initIndexTable(); - }, - - /** - * i18n support - */ - TRANSLATIONS : {}, - PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, - LOCALE : 'unknown', - - // gettext and ngettext don't access this so that the functions - // can safely bound to a different name (_ = Documentation.gettext) - gettext : function(string) { - var translated = Documentation.TRANSLATIONS[string]; - if (typeof translated == 'undefined') - return string; - return (typeof translated == 'string') ? translated : translated[0]; - }, - - ngettext : function(singular, plural, n) { - var translated = Documentation.TRANSLATIONS[singular]; - if (typeof translated == 'undefined') - return (n == 1) ? singular : plural; - return translated[Documentation.PLURALEXPR(n)]; - }, - - addTranslations : function(catalog) { - for (var key in catalog.messages) - this.TRANSLATIONS[key] = catalog.messages[key]; - this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); - this.LOCALE = catalog.locale; - }, - - /** - * add context elements like header anchor links - */ - addContextElements : function() { - $('div[id] > :header:first').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this headline')). - appendTo(this); - }); - $('dt[id]').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this definition')). - appendTo(this); - }); - }, - - /** - * workaround a firefox stupidity - */ - fixFirefoxAnchorBug : function() { - if (document.location.hash && $.browser.mozilla) - window.setTimeout(function() { - document.location.href += ''; - }, 10); - }, - - /** - * highlight the search words provided in the url in the text - */ - highlightSearchWords : function() { - var params = $.getQueryParameters(); - var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; - if (terms.length) { - var body = $('div.body'); - if (!body.length) { - body = $('body'); - } - window.setTimeout(function() { - $.each(terms, function() { - body.highlightText(this.toLowerCase(), 'highlighted'); - }); - }, 10); - $('') - .appendTo($('#searchbox')); - } - }, - - /** - * init the domain index toggle buttons - */ - initIndexTable : function() { - var togglers = $('img.toggler').click(function() { - var src = $(this).attr('src'); - var idnum = $(this).attr('id').substr(7); - $('tr.cg-' + idnum).toggle(); - if (src.substr(-9) == 'minus.png') - $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); - else - $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); - }).css('display', ''); - if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { - togglers.click(); - } - }, - - /** - * helper function to hide the search marks again - */ - hideSearchWords : function() { - $('#searchbox .highlight-link').fadeOut(300); - $('span.highlighted').removeClass('highlighted'); - }, - - /** - * make the url absolute - */ - makeURL : function(relativeURL) { - return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; - }, - - /** - * get the current relative url - */ - getCurrentURL : function() { - var path = document.location.pathname; - var parts = path.split(/\//); - $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { - if (this == '..') - parts.pop(); - }); - var url = parts.join('/'); - return path.substring(url.lastIndexOf('/') + 1, path.length - 1); - } -}; - -// quick alias for translations -_ = Documentation.gettext; - -$(document).ready(function() { - Documentation.init(); -}); diff --git a/server/documentation/_build/html/_static/down-pressed.png b/server/documentation/_build/html/_static/down-pressed.png deleted file mode 100644 index 6f7ad782782e4f8e39b0c6e15c7344700cdd2527..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 368 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6U4S$Y z{B+)352QE?JR*yM+OLB!qm#z$3ZNi+iKnkC`z>}Z23@f-Ava~9&<9T!#}JFtXD=!G zGdl{fK6ro2OGiOl+hKvH6i=D3%%Y^j`yIkRn!8O>@bG)IQR0{Kf+mxNd=_WScA8u_ z3;8(7x2){m9`nt+U(Nab&1G)!{`SPVpDX$w8McLTzAJ39wprG3p4XLq$06M`%}2Yk zRPPsbES*dnYm1wkGL;iioAUB*Or2kz6(-M_r_#Me-`{mj$Z%( diff --git a/server/documentation/_build/html/_static/down.png b/server/documentation/_build/html/_static/down.png deleted file mode 100644 index 3003a88770de3977d47a2ba69893436a2860f9e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 363 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6U4S$Y z{B+)352QE?JR*yM+OLB!qm#z$3ZNi+iKnkC`z>}xaV3tUZ$qnrLa#kt978NlpS`ru z&)HFc^}^>{UOEce+71h5nn>6&w6A!ieNbu1wh)UGh{8~et^#oZ1# z>T7oM=FZ~xXWnTo{qnXm$ZLOlqGswI_m2{XwVK)IJmBjW{J3-B3x@C=M{ShWt#fYS9M?R;8K$~YwlIqwf>VA7q=YKcwf2DS4Zj5inDKXXB1zl=(YO3ST6~rDq)&z z*o>z)=hxrfG-cDBW0G$!?6{M<$@{_4{m1o%Ub!naEtn|@^frU1tDnm{r-UW|!^@B8 diff --git a/server/documentation/_build/html/_static/file.png b/server/documentation/_build/html/_static/file.png deleted file mode 100644 index d18082e397e7e54f20721af768c4c2983258f1b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 392 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP$HyOL$D9)yc9|lc|nKf<9@eUiWd>3GuTC!a5vdfWYEazjncPj5ZQX%+1 zt8B*4=d)!cdDz4wr^#OMYfqGz$1LDFF>|#>*O?AGil(WEs?wLLy{Gj2J_@opDm%`dlax3yA*@*N$G&*ukFv>P8+2CBWO(qz zD0k1@kN>hhb1_6`&wrCswzINE(evt-5C1B^STi2@PmdKI;Vst0PQB6!2kdN diff --git a/server/documentation/_build/html/_static/jquery.js b/server/documentation/_build/html/_static/jquery.js deleted file mode 100644 index 12581195..00000000 --- a/server/documentation/_build/html/_static/jquery.js +++ /dev/null @@ -1,9404 +0,0 @@ -/*! - * jQuery JavaScript Library v1.7.2 - * http://jquery.com/ - * - * Copyright 2011, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * - * Date: Thu Aug 1 23:20:30 BRT 2013 - */ -(function( window, undefined ) { - -// Use the correct document accordingly with window argument (sandbox) -var document = window.document, - navigator = window.navigator, - location = window.location; -var jQuery = (function() { - -// Define a local copy of jQuery -var jQuery = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - return new jQuery.fn.init( selector, context, rootjQuery ); - }, - - // Map over jQuery in case of overwrite - _jQuery = window.jQuery, - - // Map over the $ in case of overwrite - _$ = window.$, - - // A central reference to the root jQuery(document) - rootjQuery, - - // A simple way to check for HTML strings or ID strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, - - // Check if a string has a non-whitespace character in it - rnotwhite = /\S/, - - // Used for trimming whitespace - trimLeft = /^\s+/, - trimRight = /\s+$/, - - // Match a standalone tag - rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, - - // JSON RegExp - rvalidchars = /^[\],:{}\s]*$/, - rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, - rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, - rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, - - // Useragent RegExp - rwebkit = /(webkit)[ \/]([\w.]+)/, - ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, - rmsie = /(msie) ([\w.]+)/, - rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, - - // Matches dashed string for camelizing - rdashAlpha = /-([a-z]|[0-9])/ig, - rmsPrefix = /^-ms-/, - - // Used by jQuery.camelCase as callback to replace() - fcamelCase = function( all, letter ) { - return ( letter + "" ).toUpperCase(); - }, - - // Keep a UserAgent string for use with jQuery.browser - userAgent = navigator.userAgent, - - // For matching the engine and version of the browser - browserMatch, - - // The deferred used on DOM ready - readyList, - - // The ready event handler - DOMContentLoaded, - - // Save a reference to some core methods - toString = Object.prototype.toString, - hasOwn = Object.prototype.hasOwnProperty, - push = Array.prototype.push, - slice = Array.prototype.slice, - trim = String.prototype.trim, - indexOf = Array.prototype.indexOf, - - // [[Class]] -> type pairs - class2type = {}; - -jQuery.fn = jQuery.prototype = { - constructor: jQuery, - init: function( selector, context, rootjQuery ) { - var match, elem, ret, doc; - - // Handle $(""), $(null), or $(undefined) - if ( !selector ) { - return this; - } - - // Handle $(DOMElement) - if ( selector.nodeType ) { - this.context = this[0] = selector; - this.length = 1; - return this; - } - - // The body element only exists once, optimize finding it - if ( selector === "body" && !context && document.body ) { - this.context = document; - this[0] = document.body; - this.selector = selector; - this.length = 1; - return this; - } - - // Handle HTML strings - if ( typeof selector === "string" ) { - // Are we dealing with HTML string or an ID? - if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = quickExpr.exec( selector ); - } - - // Verify a match, and that no context was specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) { - context = context instanceof jQuery ? context[0] : context; - doc = ( context ? context.ownerDocument || context : document ); - - // If a single string is passed in and it's a single tag - // just do a createElement and skip the rest - ret = rsingleTag.exec( selector ); - - if ( ret ) { - if ( jQuery.isPlainObject( context ) ) { - selector = [ document.createElement( ret[1] ) ]; - jQuery.fn.attr.call( selector, context, true ); - - } else { - selector = [ doc.createElement( ret[1] ) ]; - } - - } else { - ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); - selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; - } - - return jQuery.merge( this, selector ); - - // HANDLE: $("#id") - } else { - elem = document.getElementById( match[2] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id !== match[2] ) { - return rootjQuery.find( selector ); - } - - // Otherwise, we inject the element directly into the jQuery object - this.length = 1; - this[0] = elem; - } - - this.context = document; - this.selector = selector; - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || rootjQuery ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return rootjQuery.ready( selector ); - } - - if ( selector.selector !== undefined ) { - this.selector = selector.selector; - this.context = selector.context; - } - - return jQuery.makeArray( selector, this ); - }, - - // Start with an empty selector - selector: "", - - // The current version of jQuery being used - jquery: "1.7.2", - - // The default length of a jQuery object is 0 - length: 0, - - // The number of elements contained in the matched element set - size: function() { - return this.length; - }, - - toArray: function() { - return slice.call( this, 0 ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num == null ? - - // Return a 'clean' array - this.toArray() : - - // Return just the object - ( num < 0 ? this[ this.length + num ] : this[ num ] ); - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems, name, selector ) { - // Build a new jQuery matched element set - var ret = this.constructor(); - - if ( jQuery.isArray( elems ) ) { - push.apply( ret, elems ); - - } else { - jQuery.merge( ret, elems ); - } - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - ret.context = this.context; - - if ( name === "find" ) { - ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; - } else if ( name ) { - ret.selector = this.selector + "." + name + "(" + selector + ")"; - } - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); - }, - - ready: function( fn ) { - // Attach the listeners - jQuery.bindReady(); - - // Add the callback - readyList.add( fn ); - - return this; - }, - - eq: function( i ) { - i = +i; - return i === -1 ? - this.slice( i ) : - this.slice( i, i + 1 ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ), - "slice", slice.call(arguments).join(",") ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function( elem, i ) { - return callback.call( elem, i, elem ); - })); - }, - - end: function() { - return this.prevObject || this.constructor(null); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: [].sort, - splice: [].splice -}; - -// Give the init function the jQuery prototype for later instantiation -jQuery.fn.init.prototype = jQuery.fn; - -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if ( length === i ) { - target = this; - --i; - } - - for ( ; i < length; i++ ) { - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { - if ( copyIsArray ) { - copyIsArray = false; - clone = src && jQuery.isArray(src) ? src : []; - - } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend({ - noConflict: function( deep ) { - if ( window.$ === jQuery ) { - window.$ = _$; - } - - if ( deep && window.jQuery === jQuery ) { - window.jQuery = _jQuery; - } - - return jQuery; - }, - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Hold (or release) the ready event - holdReady: function( hold ) { - if ( hold ) { - jQuery.readyWait++; - } else { - jQuery.ready( true ); - } - }, - - // Handle when the DOM is ready - ready: function( wait ) { - // Either a released hold or an DOMready/load event and not yet ready - if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( !document.body ) { - return setTimeout( jQuery.ready, 1 ); - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.fireWith( document, [ jQuery ] ); - - // Trigger any bound ready events - if ( jQuery.fn.trigger ) { - jQuery( document ).trigger( "ready" ).off( "ready" ); - } - } - }, - - bindReady: function() { - if ( readyList ) { - return; - } - - readyList = jQuery.Callbacks( "once memory" ); - - // Catch cases where $(document).ready() is called after the - // browser event has already occurred. - if ( document.readyState === "complete" ) { - // Handle it asynchronously to allow scripts the opportunity to delay ready - return setTimeout( jQuery.ready, 1 ); - } - - // Mozilla, Opera and webkit nightlies currently support this event - if ( document.addEventListener ) { - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", jQuery.ready, false ); - - // If IE event model is used - } else if ( document.attachEvent ) { - // ensure firing before onload, - // maybe late but safe also for iframes - document.attachEvent( "onreadystatechange", DOMContentLoaded ); - - // A fallback to window.onload, that will always work - window.attachEvent( "onload", jQuery.ready ); - - // If IE and not a frame - // continually check to see if the document is ready - var toplevel = false; - - try { - toplevel = window.frameElement == null; - } catch(e) {} - - if ( document.documentElement.doScroll && toplevel ) { - doScrollCheck(); - } - } - }, - - // See test/unit/core.js for details concerning isFunction. - // Since version 1.3, DOM methods and functions like alert - // aren't supported. They return false on IE (#2968). - isFunction: function( obj ) { - return jQuery.type(obj) === "function"; - }, - - isArray: Array.isArray || function( obj ) { - return jQuery.type(obj) === "array"; - }, - - isWindow: function( obj ) { - return obj != null && obj == obj.window; - }, - - isNumeric: function( obj ) { - return !isNaN( parseFloat(obj) ) && isFinite( obj ); - }, - - type: function( obj ) { - return obj == null ? - String( obj ) : - class2type[ toString.call(obj) ] || "object"; - }, - - isPlainObject: function( obj ) { - // Must be an Object. - // Because of IE, we also have to check the presence of the constructor property. - // Make sure that DOM nodes and window objects don't pass through, as well - if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { - return false; - } - - try { - // Not own constructor property must be Object - if ( obj.constructor && - !hasOwn.call(obj, "constructor") && - !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { - return false; - } - } catch ( e ) { - // IE8,9 Will throw exceptions on certain host objects #9897 - return false; - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - - var key; - for ( key in obj ) {} - - return key === undefined || hasOwn.call( obj, key ); - }, - - isEmptyObject: function( obj ) { - for ( var name in obj ) { - return false; - } - return true; - }, - - error: function( msg ) { - throw new Error( msg ); - }, - - parseJSON: function( data ) { - if ( typeof data !== "string" || !data ) { - return null; - } - - // Make sure leading/trailing whitespace is removed (IE can't handle it) - data = jQuery.trim( data ); - - // Attempt to parse using the native JSON parser first - if ( window.JSON && window.JSON.parse ) { - return window.JSON.parse( data ); - } - - // Make sure the incoming data is actual JSON - // Logic borrowed from http://json.org/json2.js - if ( rvalidchars.test( data.replace( rvalidescape, "@" ) - .replace( rvalidtokens, "]" ) - .replace( rvalidbraces, "")) ) { - - return ( new Function( "return " + data ) )(); - - } - jQuery.error( "Invalid JSON: " + data ); - }, - - // Cross-browser xml parsing - parseXML: function( data ) { - if ( typeof data !== "string" || !data ) { - return null; - } - var xml, tmp; - try { - if ( window.DOMParser ) { // Standard - tmp = new DOMParser(); - xml = tmp.parseFromString( data , "text/xml" ); - } else { // IE - xml = new ActiveXObject( "Microsoft.XMLDOM" ); - xml.async = "false"; - xml.loadXML( data ); - } - } catch( e ) { - xml = undefined; - } - if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { - jQuery.error( "Invalid XML: " + data ); - } - return xml; - }, - - noop: function() {}, - - // Evaluates a script in a global context - // Workarounds based on findings by Jim Driscoll - // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context - globalEval: function( data ) { - if ( data && rnotwhite.test( data ) ) { - // We use execScript on Internet Explorer - // We use an anonymous function so that context is window - // rather than jQuery in Firefox - ( window.execScript || function( data ) { - window[ "eval" ].call( window, data ); - } )( data ); - } - }, - - // Convert dashed to camelCase; used by the css and data modules - // Microsoft forgot to hump their vendor prefix (#9572) - camelCase: function( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); - }, - - // args is for internal usage only - each: function( object, callback, args ) { - var name, i = 0, - length = object.length, - isObj = length === undefined || jQuery.isFunction( object ); - - if ( args ) { - if ( isObj ) { - for ( name in object ) { - if ( callback.apply( object[ name ], args ) === false ) { - break; - } - } - } else { - for ( ; i < length; ) { - if ( callback.apply( object[ i++ ], args ) === false ) { - break; - } - } - } - - // A special, fast, case for the most common use of each - } else { - if ( isObj ) { - for ( name in object ) { - if ( callback.call( object[ name ], name, object[ name ] ) === false ) { - break; - } - } - } else { - for ( ; i < length; ) { - if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { - break; - } - } - } - } - - return object; - }, - - // Use native String.trim function wherever possible - trim: trim ? - function( text ) { - return text == null ? - "" : - trim.call( text ); - } : - - // Otherwise use our own trimming functionality - function( text ) { - return text == null ? - "" : - text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); - }, - - // results is for internal usage only - makeArray: function( array, results ) { - var ret = results || []; - - if ( array != null ) { - // The window, strings (and functions) also have 'length' - // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 - var type = jQuery.type( array ); - - if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { - push.call( ret, array ); - } else { - jQuery.merge( ret, array ); - } - } - - return ret; - }, - - inArray: function( elem, array, i ) { - var len; - - if ( array ) { - if ( indexOf ) { - return indexOf.call( array, elem, i ); - } - - len = array.length; - i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; - - for ( ; i < len; i++ ) { - // Skip accessing in sparse arrays - if ( i in array && array[ i ] === elem ) { - return i; - } - } - } - - return -1; - }, - - merge: function( first, second ) { - var i = first.length, - j = 0; - - if ( typeof second.length === "number" ) { - for ( var l = second.length; j < l; j++ ) { - first[ i++ ] = second[ j ]; - } - - } else { - while ( second[j] !== undefined ) { - first[ i++ ] = second[ j++ ]; - } - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, inv ) { - var ret = [], retVal; - inv = !!inv; - - // Go through the array, only saving the items - // that pass the validator function - for ( var i = 0, length = elems.length; i < length; i++ ) { - retVal = !!callback( elems[ i ], i ); - if ( inv !== retVal ) { - ret.push( elems[ i ] ); - } - } - - return ret; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var value, key, ret = [], - i = 0, - length = elems.length, - // jquery objects are treated as arrays - isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; - - // Go through the array, translating each of the items to their - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret[ ret.length ] = value; - } - } - - // Go through every key on the object, - } else { - for ( key in elems ) { - value = callback( elems[ key ], key, arg ); - - if ( value != null ) { - ret[ ret.length ] = value; - } - } - } - - // Flatten any nested arrays - return ret.concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // Bind a function to a context, optionally partially applying any - // arguments. - proxy: function( fn, context ) { - if ( typeof context === "string" ) { - var tmp = fn[ context ]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if ( !jQuery.isFunction( fn ) ) { - return undefined; - } - - // Simulated bind - var args = slice.call( arguments, 2 ), - proxy = function() { - return fn.apply( context, args.concat( slice.call( arguments ) ) ); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; - - return proxy; - }, - - // Mutifunctional method to get and set values to a collection - // The value/s can optionally be executed if it's a function - access: function( elems, fn, key, value, chainable, emptyGet, pass ) { - var exec, - bulk = key == null, - i = 0, - length = elems.length; - - // Sets many values - if ( key && typeof key === "object" ) { - for ( i in key ) { - jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); - } - chainable = 1; - - // Sets one value - } else if ( value !== undefined ) { - // Optionally, function values get executed if exec is true - exec = pass === undefined && jQuery.isFunction( value ); - - if ( bulk ) { - // Bulk operations only iterate when executing function values - if ( exec ) { - exec = fn; - fn = function( elem, key, value ) { - return exec.call( jQuery( elem ), value ); - }; - - // Otherwise they run against the entire set - } else { - fn.call( elems, value ); - fn = null; - } - } - - if ( fn ) { - for (; i < length; i++ ) { - fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); - } - } - - chainable = 1; - } - - return chainable ? - elems : - - // Gets - bulk ? - fn.call( elems ) : - length ? fn( elems[0], key ) : emptyGet; - }, - - now: function() { - return ( new Date() ).getTime(); - }, - - // Use of jQuery.browser is frowned upon. - // More details: http://docs.jquery.com/Utilities/jQuery.browser - uaMatch: function( ua ) { - ua = ua.toLowerCase(); - - var match = rwebkit.exec( ua ) || - ropera.exec( ua ) || - rmsie.exec( ua ) || - ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || - []; - - return { browser: match[1] || "", version: match[2] || "0" }; - }, - - sub: function() { - function jQuerySub( selector, context ) { - return new jQuerySub.fn.init( selector, context ); - } - jQuery.extend( true, jQuerySub, this ); - jQuerySub.superclass = this; - jQuerySub.fn = jQuerySub.prototype = this(); - jQuerySub.fn.constructor = jQuerySub; - jQuerySub.sub = this.sub; - jQuerySub.fn.init = function init( selector, context ) { - if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { - context = jQuerySub( context ); - } - - return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); - }; - jQuerySub.fn.init.prototype = jQuerySub.fn; - var rootjQuerySub = jQuerySub(document); - return jQuerySub; - }, - - browser: {} -}); - -// Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -}); - -browserMatch = jQuery.uaMatch( userAgent ); -if ( browserMatch.browser ) { - jQuery.browser[ browserMatch.browser ] = true; - jQuery.browser.version = browserMatch.version; -} - -// Deprecated, use jQuery.browser.webkit instead -if ( jQuery.browser.webkit ) { - jQuery.browser.safari = true; -} - -// IE doesn't match non-breaking spaces with \s -if ( rnotwhite.test( "\xA0" ) ) { - trimLeft = /^[\s\xA0]+/; - trimRight = /[\s\xA0]+$/; -} - -// All jQuery objects should point back to these -rootjQuery = jQuery(document); - -// Cleanup functions for the document ready method -if ( document.addEventListener ) { - DOMContentLoaded = function() { - document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - jQuery.ready(); - }; - -} else if ( document.attachEvent ) { - DOMContentLoaded = function() { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( document.readyState === "complete" ) { - document.detachEvent( "onreadystatechange", DOMContentLoaded ); - jQuery.ready(); - } - }; -} - -// The DOM ready check for Internet Explorer -function doScrollCheck() { - if ( jQuery.isReady ) { - return; - } - - try { - // If IE is used, use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - document.documentElement.doScroll("left"); - } catch(e) { - setTimeout( doScrollCheck, 1 ); - return; - } - - // and execute any waiting functions - jQuery.ready(); -} - -return jQuery; - -})(); - - -// String to Object flags format cache -var flagsCache = {}; - -// Convert String-formatted flags into Object-formatted ones and store in cache -function createFlags( flags ) { - var object = flagsCache[ flags ] = {}, - i, length; - flags = flags.split( /\s+/ ); - for ( i = 0, length = flags.length; i < length; i++ ) { - object[ flags[i] ] = true; - } - return object; -} - -/* - * Create a callback list using the following parameters: - * - * flags: an optional list of space-separated flags that will change how - * the callback list behaves - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible flags: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( flags ) { - - // Convert flags from String-formatted to Object-formatted - // (we check in cache first) - flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; - - var // Actual callback list - list = [], - // Stack of fire calls for repeatable lists - stack = [], - // Last fire value (for non-forgettable lists) - memory, - // Flag to know if list was already fired - fired, - // Flag to know if list is currently firing - firing, - // First callback to fire (used internally by add and fireWith) - firingStart, - // End of the loop when firing - firingLength, - // Index of currently firing callback (modified by remove if needed) - firingIndex, - // Add one or several callbacks to the list - add = function( args ) { - var i, - length, - elem, - type, - actual; - for ( i = 0, length = args.length; i < length; i++ ) { - elem = args[ i ]; - type = jQuery.type( elem ); - if ( type === "array" ) { - // Inspect recursively - add( elem ); - } else if ( type === "function" ) { - // Add if not in unique mode and callback is not in - if ( !flags.unique || !self.has( elem ) ) { - list.push( elem ); - } - } - } - }, - // Fire callbacks - fire = function( context, args ) { - args = args || []; - memory = !flags.memory || [ context, args ]; - fired = true; - firing = true; - firingIndex = firingStart || 0; - firingStart = 0; - firingLength = list.length; - for ( ; list && firingIndex < firingLength; firingIndex++ ) { - if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { - memory = true; // Mark as halted - break; - } - } - firing = false; - if ( list ) { - if ( !flags.once ) { - if ( stack && stack.length ) { - memory = stack.shift(); - self.fireWith( memory[ 0 ], memory[ 1 ] ); - } - } else if ( memory === true ) { - self.disable(); - } else { - list = []; - } - } - }, - // Actual Callbacks object - self = { - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - var length = list.length; - add( arguments ); - // Do we need to add the callbacks to the - // current firing batch? - if ( firing ) { - firingLength = list.length; - // With memory, if we're not firing then - // we should call right away, unless previous - // firing was halted (stopOnFalse) - } else if ( memory && memory !== true ) { - firingStart = length; - fire( memory[ 0 ], memory[ 1 ] ); - } - } - return this; - }, - // Remove a callback from the list - remove: function() { - if ( list ) { - var args = arguments, - argIndex = 0, - argLength = args.length; - for ( ; argIndex < argLength ; argIndex++ ) { - for ( var i = 0; i < list.length; i++ ) { - if ( args[ argIndex ] === list[ i ] ) { - // Handle firingIndex and firingLength - if ( firing ) { - if ( i <= firingLength ) { - firingLength--; - if ( i <= firingIndex ) { - firingIndex--; - } - } - } - // Remove the element - list.splice( i--, 1 ); - // If we have some unicity property then - // we only need to do this once - if ( flags.unique ) { - break; - } - } - } - } - } - return this; - }, - // Control if a given callback is in the list - has: function( fn ) { - if ( list ) { - var i = 0, - length = list.length; - for ( ; i < length; i++ ) { - if ( fn === list[ i ] ) { - return true; - } - } - } - return false; - }, - // Remove all callbacks from the list - empty: function() { - list = []; - return this; - }, - // Have the list do nothing anymore - disable: function() { - list = stack = memory = undefined; - return this; - }, - // Is it disabled? - disabled: function() { - return !list; - }, - // Lock the list in its current state - lock: function() { - stack = undefined; - if ( !memory || memory === true ) { - self.disable(); - } - return this; - }, - // Is it locked? - locked: function() { - return !stack; - }, - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( stack ) { - if ( firing ) { - if ( !flags.once ) { - stack.push( [ context, args ] ); - } - } else if ( !( flags.once && memory ) ) { - fire( context, args ); - } - } - return this; - }, - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - // To know if the callbacks have already been called at least once - fired: function() { - return !!fired; - } - }; - - return self; -}; - - - - -var // Static reference to slice - sliceDeferred = [].slice; - -jQuery.extend({ - - Deferred: function( func ) { - var doneList = jQuery.Callbacks( "once memory" ), - failList = jQuery.Callbacks( "once memory" ), - progressList = jQuery.Callbacks( "memory" ), - state = "pending", - lists = { - resolve: doneList, - reject: failList, - notify: progressList - }, - promise = { - done: doneList.add, - fail: failList.add, - progress: progressList.add, - - state: function() { - return state; - }, - - // Deprecated - isResolved: doneList.fired, - isRejected: failList.fired, - - then: function( doneCallbacks, failCallbacks, progressCallbacks ) { - deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); - return this; - }, - always: function() { - deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); - return this; - }, - pipe: function( fnDone, fnFail, fnProgress ) { - return jQuery.Deferred(function( newDefer ) { - jQuery.each( { - done: [ fnDone, "resolve" ], - fail: [ fnFail, "reject" ], - progress: [ fnProgress, "notify" ] - }, function( handler, data ) { - var fn = data[ 0 ], - action = data[ 1 ], - returned; - if ( jQuery.isFunction( fn ) ) { - deferred[ handler ](function() { - returned = fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); - } else { - newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); - } - }); - } else { - deferred[ handler ]( newDefer[ action ] ); - } - }); - }).promise(); - }, - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - if ( obj == null ) { - obj = promise; - } else { - for ( var key in promise ) { - obj[ key ] = promise[ key ]; - } - } - return obj; - } - }, - deferred = promise.promise({}), - key; - - for ( key in lists ) { - deferred[ key ] = lists[ key ].fire; - deferred[ key + "With" ] = lists[ key ].fireWith; - } - - // Handle state - deferred.done( function() { - state = "resolved"; - }, failList.disable, progressList.lock ).fail( function() { - state = "rejected"; - }, doneList.disable, progressList.lock ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( firstParam ) { - var args = sliceDeferred.call( arguments, 0 ), - i = 0, - length = args.length, - pValues = new Array( length ), - count = length, - pCount = length, - deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? - firstParam : - jQuery.Deferred(), - promise = deferred.promise(); - function resolveFunc( i ) { - return function( value ) { - args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; - if ( !( --count ) ) { - deferred.resolveWith( deferred, args ); - } - }; - } - function progressFunc( i ) { - return function( value ) { - pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; - deferred.notifyWith( promise, pValues ); - }; - } - if ( length > 1 ) { - for ( ; i < length; i++ ) { - if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { - args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); - } else { - --count; - } - } - if ( !count ) { - deferred.resolveWith( deferred, args ); - } - } else if ( deferred !== firstParam ) { - deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); - } - return promise; - } -}); - - - - -jQuery.support = (function() { - - var support, - all, - a, - select, - opt, - input, - fragment, - tds, - events, - eventName, - i, - isSupported, - div = document.createElement( "div" ), - documentElement = document.documentElement; - - // Preliminary tests - div.setAttribute("className", "t"); - div.innerHTML = "
a"; - - all = div.getElementsByTagName( "*" ); - a = div.getElementsByTagName( "a" )[ 0 ]; - - // Can't get basic test support - if ( !all || !all.length || !a ) { - return {}; - } - - // First batch of supports tests - select = document.createElement( "select" ); - opt = select.appendChild( document.createElement("option") ); - input = div.getElementsByTagName( "input" )[ 0 ]; - - support = { - // IE strips leading whitespace when .innerHTML is used - leadingWhitespace: ( div.firstChild.nodeType === 3 ), - - // Make sure that tbody elements aren't automatically inserted - // IE will insert them into empty tables - tbody: !div.getElementsByTagName("tbody").length, - - // Make sure that link elements get serialized correctly by innerHTML - // This requires a wrapper element in IE - htmlSerialize: !!div.getElementsByTagName("link").length, - - // Get the style information from getAttribute - // (IE uses .cssText instead) - style: /top/.test( a.getAttribute("style") ), - - // Make sure that URLs aren't manipulated - // (IE normalizes it by default) - hrefNormalized: ( a.getAttribute("href") === "/a" ), - - // Make sure that element opacity exists - // (IE uses filter instead) - // Use a regex to work around a WebKit issue. See #5145 - opacity: /^0.55/.test( a.style.opacity ), - - // Verify style float existence - // (IE uses styleFloat instead of cssFloat) - cssFloat: !!a.style.cssFloat, - - // Make sure that if no value is specified for a checkbox - // that it defaults to "on". - // (WebKit defaults to "" instead) - checkOn: ( input.value === "on" ), - - // Make sure that a selected-by-default option has a working selected property. - // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) - optSelected: opt.selected, - - // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) - getSetAttribute: div.className !== "t", - - // Tests for enctype support on a form(#6743) - enctype: !!document.createElement("form").enctype, - - // Makes sure cloning an html5 element does not cause problems - // Where outerHTML is undefined, this still works - html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", - - // Will be defined later - submitBubbles: true, - changeBubbles: true, - focusinBubbles: false, - deleteExpando: true, - noCloneEvent: true, - inlineBlockNeedsLayout: false, - shrinkWrapBlocks: false, - reliableMarginRight: true, - pixelMargin: true - }; - - // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead - jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat"); - - // Make sure checked status is properly cloned - input.checked = true; - support.noCloneChecked = input.cloneNode( true ).checked; - - // Make sure that the options inside disabled selects aren't marked as disabled - // (WebKit marks them as disabled) - select.disabled = true; - support.optDisabled = !opt.disabled; - - // Test to see if it's possible to delete an expando from an element - // Fails in Internet Explorer - try { - delete div.test; - } catch( e ) { - support.deleteExpando = false; - } - - if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { - div.attachEvent( "onclick", function() { - // Cloning a node shouldn't copy over any - // bound event handlers (IE does this) - support.noCloneEvent = false; - }); - div.cloneNode( true ).fireEvent( "onclick" ); - } - - // Check if a radio maintains its value - // after being appended to the DOM - input = document.createElement("input"); - input.value = "t"; - input.setAttribute("type", "radio"); - support.radioValue = input.value === "t"; - - input.setAttribute("checked", "checked"); - - // #11217 - WebKit loses check when the name is after the checked attribute - input.setAttribute( "name", "t" ); - - div.appendChild( input ); - fragment = document.createDocumentFragment(); - fragment.appendChild( div.lastChild ); - - // WebKit doesn't clone checked state correctly in fragments - support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Check if a disconnected checkbox will retain its checked - // value of true after appended to the DOM (IE6/7) - support.appendChecked = input.checked; - - fragment.removeChild( input ); - fragment.appendChild( div ); - - // Technique from Juriy Zaytsev - // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ - // We only care about the case where non-standard event systems - // are used, namely in IE. Short-circuiting here helps us to - // avoid an eval call (in setAttribute) which can cause CSP - // to go haywire. See: https://developer.mozilla.org/en/Security/CSP - if ( div.attachEvent ) { - for ( i in { - submit: 1, - change: 1, - focusin: 1 - }) { - eventName = "on" + i; - isSupported = ( eventName in div ); - if ( !isSupported ) { - div.setAttribute( eventName, "return;" ); - isSupported = ( typeof div[ eventName ] === "function" ); - } - support[ i + "Bubbles" ] = isSupported; - } - } - - fragment.removeChild( div ); - - // Null elements to avoid leaks in IE - fragment = select = opt = div = input = null; - - // Run tests that need a body at doc ready - jQuery(function() { - var container, outer, inner, table, td, offsetSupport, - marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight, - paddingMarginBorderVisibility, paddingMarginBorder, - body = document.getElementsByTagName("body")[0]; - - if ( !body ) { - // Return for frameset docs that don't have a body - return; - } - - conMarginTop = 1; - paddingMarginBorder = "padding:0;margin:0;border:"; - positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;"; - paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;"; - style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;"; - html = "
" + - "" + - "
"; - - container = document.createElement("div"); - container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; - body.insertBefore( container, body.firstChild ); - - // Construct the test element - div = document.createElement("div"); - container.appendChild( div ); - - // Check if table cells still have offsetWidth/Height when they are set - // to display:none and there are still other visible table cells in a - // table row; if so, offsetWidth/Height are not reliable for use when - // determining if an element has been hidden directly using - // display:none (it is still safe to use offsets if a parent element is - // hidden; don safety goggles and see bug #4512 for more information). - // (only IE 8 fails this test) - div.innerHTML = "
t
"; - tds = div.getElementsByTagName( "td" ); - isSupported = ( tds[ 0 ].offsetHeight === 0 ); - - tds[ 0 ].style.display = ""; - tds[ 1 ].style.display = "none"; - - // Check if empty table cells still have offsetWidth/Height - // (IE <= 8 fail this test) - support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); - - // Check if div with explicit width and no margin-right incorrectly - // gets computed margin-right based on width of container. For more - // info see bug #3333 - // Fails in WebKit before Feb 2011 nightlies - // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right - if ( window.getComputedStyle ) { - div.innerHTML = ""; - marginDiv = document.createElement( "div" ); - marginDiv.style.width = "0"; - marginDiv.style.marginRight = "0"; - div.style.width = "2px"; - div.appendChild( marginDiv ); - support.reliableMarginRight = - ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; - } - - if ( typeof div.style.zoom !== "undefined" ) { - // Check if natively block-level elements act like inline-block - // elements when setting their display to 'inline' and giving - // them layout - // (IE < 8 does this) - div.innerHTML = ""; - div.style.width = div.style.padding = "1px"; - div.style.border = 0; - div.style.overflow = "hidden"; - div.style.display = "inline"; - div.style.zoom = 1; - support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); - - // Check if elements with layout shrink-wrap their children - // (IE 6 does this) - div.style.display = "block"; - div.style.overflow = "visible"; - div.innerHTML = "
"; - support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); - } - - div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility; - div.innerHTML = html; - - outer = div.firstChild; - inner = outer.firstChild; - td = outer.nextSibling.firstChild.firstChild; - - offsetSupport = { - doesNotAddBorder: ( inner.offsetTop !== 5 ), - doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) - }; - - inner.style.position = "fixed"; - inner.style.top = "20px"; - - // safari subtracts parent border width here which is 5px - offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); - inner.style.position = inner.style.top = ""; - - outer.style.overflow = "hidden"; - outer.style.position = "relative"; - - offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); - offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); - - if ( window.getComputedStyle ) { - div.style.marginTop = "1%"; - support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%"; - } - - if ( typeof container.style.zoom !== "undefined" ) { - container.style.zoom = 1; - } - - body.removeChild( container ); - marginDiv = div = container = null; - - jQuery.extend( support, offsetSupport ); - }); - - return support; -})(); - - - - -var rbrace = /^(?:\{.*\}|\[.*\])$/, - rmultiDash = /([A-Z])/g; - -jQuery.extend({ - cache: {}, - - // Please use with caution - uuid: 0, - - // Unique for each copy of jQuery on the page - // Non-digits removed to match rinlinejQuery - expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), - - // The following elements throw uncatchable exceptions if you - // attempt to add expando properties to them. - noData: { - "embed": true, - // Ban all objects except for Flash (which handle expandos) - "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", - "applet": true - }, - - hasData: function( elem ) { - elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; - return !!elem && !isEmptyDataObject( elem ); - }, - - data: function( elem, name, data, pvt /* Internal Use Only */ ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var privateCache, thisCache, ret, - internalKey = jQuery.expando, - getByName = typeof name === "string", - - // We have to handle DOM nodes and JS objects differently because IE6-7 - // can't GC object references properly across the DOM-JS boundary - isNode = elem.nodeType, - - // Only DOM nodes need the global jQuery cache; JS object data is - // attached directly to the object so GC can occur automatically - cache = isNode ? jQuery.cache : elem, - - // Only defining an ID for JS objects if its cache already exists allows - // the code to shortcut on the same path as a DOM node with no cache - id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, - isEvents = name === "events"; - - // Avoid doing any more work than we need to when trying to get data on an - // object that has no data at all - if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { - return; - } - - if ( !id ) { - // Only DOM nodes need a new unique ID for each element since their data - // ends up in the global cache - if ( isNode ) { - elem[ internalKey ] = id = ++jQuery.uuid; - } else { - id = internalKey; - } - } - - if ( !cache[ id ] ) { - cache[ id ] = {}; - - // Avoids exposing jQuery metadata on plain JS objects when the object - // is serialized using JSON.stringify - if ( !isNode ) { - cache[ id ].toJSON = jQuery.noop; - } - } - - // An object can be passed to jQuery.data instead of a key/value pair; this gets - // shallow copied over onto the existing cache - if ( typeof name === "object" || typeof name === "function" ) { - if ( pvt ) { - cache[ id ] = jQuery.extend( cache[ id ], name ); - } else { - cache[ id ].data = jQuery.extend( cache[ id ].data, name ); - } - } - - privateCache = thisCache = cache[ id ]; - - // jQuery data() is stored in a separate object inside the object's internal data - // cache in order to avoid key collisions between internal data and user-defined - // data. - if ( !pvt ) { - if ( !thisCache.data ) { - thisCache.data = {}; - } - - thisCache = thisCache.data; - } - - if ( data !== undefined ) { - thisCache[ jQuery.camelCase( name ) ] = data; - } - - // Users should not attempt to inspect the internal events object using jQuery.data, - // it is undocumented and subject to change. But does anyone listen? No. - if ( isEvents && !thisCache[ name ] ) { - return privateCache.events; - } - - // Check for both converted-to-camel and non-converted data property names - // If a data property was specified - if ( getByName ) { - - // First Try to find as-is property data - ret = thisCache[ name ]; - - // Test for null|undefined property data - if ( ret == null ) { - - // Try to find the camelCased property - ret = thisCache[ jQuery.camelCase( name ) ]; - } - } else { - ret = thisCache; - } - - return ret; - }, - - removeData: function( elem, name, pvt /* Internal Use Only */ ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var thisCache, i, l, - - // Reference to internal data cache key - internalKey = jQuery.expando, - - isNode = elem.nodeType, - - // See jQuery.data for more information - cache = isNode ? jQuery.cache : elem, - - // See jQuery.data for more information - id = isNode ? elem[ internalKey ] : internalKey; - - // If there is already no cache entry for this object, there is no - // purpose in continuing - if ( !cache[ id ] ) { - return; - } - - if ( name ) { - - thisCache = pvt ? cache[ id ] : cache[ id ].data; - - if ( thisCache ) { - - // Support array or space separated string names for data keys - if ( !jQuery.isArray( name ) ) { - - // try the string as a key before any manipulation - if ( name in thisCache ) { - name = [ name ]; - } else { - - // split the camel cased version by spaces unless a key with the spaces exists - name = jQuery.camelCase( name ); - if ( name in thisCache ) { - name = [ name ]; - } else { - name = name.split( " " ); - } - } - } - - for ( i = 0, l = name.length; i < l; i++ ) { - delete thisCache[ name[i] ]; - } - - // If there is no data left in the cache, we want to continue - // and let the cache object itself get destroyed - if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { - return; - } - } - } - - // See jQuery.data for more information - if ( !pvt ) { - delete cache[ id ].data; - - // Don't destroy the parent cache unless the internal data object - // had been the only thing left in it - if ( !isEmptyDataObject(cache[ id ]) ) { - return; - } - } - - // Browsers that fail expando deletion also refuse to delete expandos on - // the window, but it will allow it on all other JS objects; other browsers - // don't care - // Ensure that `cache` is not a window object #10080 - if ( jQuery.support.deleteExpando || !cache.setInterval ) { - delete cache[ id ]; - } else { - cache[ id ] = null; - } - - // We destroyed the cache and need to eliminate the expando on the node to avoid - // false lookups in the cache for entries that no longer exist - if ( isNode ) { - // IE does not allow us to delete expando properties from nodes, - // nor does it have a removeAttribute function on Document nodes; - // we must handle all of these cases - if ( jQuery.support.deleteExpando ) { - delete elem[ internalKey ]; - } else if ( elem.removeAttribute ) { - elem.removeAttribute( internalKey ); - } else { - elem[ internalKey ] = null; - } - } - }, - - // For internal use only. - _data: function( elem, name, data ) { - return jQuery.data( elem, name, data, true ); - }, - - // A method for determining if a DOM node can handle the data expando - acceptData: function( elem ) { - if ( elem.nodeName ) { - var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; - - if ( match ) { - return !(match === true || elem.getAttribute("classid") !== match); - } - } - - return true; - } -}); - -jQuery.fn.extend({ - data: function( key, value ) { - var parts, part, attr, name, l, - elem = this[0], - i = 0, - data = null; - - // Gets all values - if ( key === undefined ) { - if ( this.length ) { - data = jQuery.data( elem ); - - if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { - attr = elem.attributes; - for ( l = attr.length; i < l; i++ ) { - name = attr[i].name; - - if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.substring(5) ); - - dataAttr( elem, name, data[ name ] ); - } - } - jQuery._data( elem, "parsedAttrs", true ); - } - } - - return data; - } - - // Sets multiple values - if ( typeof key === "object" ) { - return this.each(function() { - jQuery.data( this, key ); - }); - } - - parts = key.split( ".", 2 ); - parts[1] = parts[1] ? "." + parts[1] : ""; - part = parts[1] + "!"; - - return jQuery.access( this, function( value ) { - - if ( value === undefined ) { - data = this.triggerHandler( "getData" + part, [ parts[0] ] ); - - // Try to fetch any internally stored data first - if ( data === undefined && elem ) { - data = jQuery.data( elem, key ); - data = dataAttr( elem, key, data ); - } - - return data === undefined && parts[1] ? - this.data( parts[0] ) : - data; - } - - parts[1] = value; - this.each(function() { - var self = jQuery( this ); - - self.triggerHandler( "setData" + part, parts ); - jQuery.data( this, key, value ); - self.triggerHandler( "changeData" + part, parts ); - }); - }, null, value, arguments.length > 1, null, false ); - }, - - removeData: function( key ) { - return this.each(function() { - jQuery.removeData( this, key ); - }); - } -}); - -function dataAttr( elem, key, data ) { - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - - var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); - - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : - jQuery.isNumeric( data ) ? +data : - rbrace.test( data ) ? jQuery.parseJSON( data ) : - data; - } catch( e ) {} - - // Make sure we set the data so it isn't changed later - jQuery.data( elem, key, data ); - - } else { - data = undefined; - } - } - - return data; -} - -// checks a cache object for emptiness -function isEmptyDataObject( obj ) { - for ( var name in obj ) { - - // if the public data object is empty, the private is still empty - if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { - continue; - } - if ( name !== "toJSON" ) { - return false; - } - } - - return true; -} - - - - -function handleQueueMarkDefer( elem, type, src ) { - var deferDataKey = type + "defer", - queueDataKey = type + "queue", - markDataKey = type + "mark", - defer = jQuery._data( elem, deferDataKey ); - if ( defer && - ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && - ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { - // Give room for hard-coded callbacks to fire first - // and eventually mark/queue something else on the element - setTimeout( function() { - if ( !jQuery._data( elem, queueDataKey ) && - !jQuery._data( elem, markDataKey ) ) { - jQuery.removeData( elem, deferDataKey, true ); - defer.fire(); - } - }, 0 ); - } -} - -jQuery.extend({ - - _mark: function( elem, type ) { - if ( elem ) { - type = ( type || "fx" ) + "mark"; - jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); - } - }, - - _unmark: function( force, elem, type ) { - if ( force !== true ) { - type = elem; - elem = force; - force = false; - } - if ( elem ) { - type = type || "fx"; - var key = type + "mark", - count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); - if ( count ) { - jQuery._data( elem, key, count ); - } else { - jQuery.removeData( elem, key, true ); - handleQueueMarkDefer( elem, type, "mark" ); - } - } - }, - - queue: function( elem, type, data ) { - var q; - if ( elem ) { - type = ( type || "fx" ) + "queue"; - q = jQuery._data( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !q || jQuery.isArray(data) ) { - q = jQuery._data( elem, type, jQuery.makeArray(data) ); - } else { - q.push( data ); - } - } - return q || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - fn = queue.shift(), - hooks = {}; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - } - - if ( fn ) { - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } - - jQuery._data( elem, type + ".run", hooks ); - fn.call( elem, function() { - jQuery.dequeue( elem, type ); - }, hooks ); - } - - if ( !queue.length ) { - jQuery.removeData( elem, type + "queue " + type + ".run", true ); - handleQueueMarkDefer( elem, type, "queue" ); - } - } -}); - -jQuery.fn.extend({ - queue: function( type, data ) { - var setter = 2; - - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - setter--; - } - - if ( arguments.length < setter ) { - return jQuery.queue( this[0], type ); - } - - return data === undefined ? - this : - this.each(function() { - var queue = jQuery.queue( this, type, data ); - - if ( type === "fx" && queue[0] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - }); - }, - dequeue: function( type ) { - return this.each(function() { - jQuery.dequeue( this, type ); - }); - }, - // Based off of the plugin by Clint Helfers, with permission. - // http://blindsignals.com/index.php/2009/07/jquery-delay/ - delay: function( time, type ) { - time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; - type = type || "fx"; - - return this.queue( type, function( next, hooks ) { - var timeout = setTimeout( next, time ); - hooks.stop = function() { - clearTimeout( timeout ); - }; - }); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, object ) { - if ( typeof type !== "string" ) { - object = type; - type = undefined; - } - type = type || "fx"; - var defer = jQuery.Deferred(), - elements = this, - i = elements.length, - count = 1, - deferDataKey = type + "defer", - queueDataKey = type + "queue", - markDataKey = type + "mark", - tmp; - function resolve() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - } - while( i-- ) { - if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || - ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || - jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && - jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { - count++; - tmp.add( resolve ); - } - } - resolve(); - return defer.promise( object ); - } -}); - - - - -var rclass = /[\n\t\r]/g, - rspace = /\s+/, - rreturn = /\r/g, - rtype = /^(?:button|input)$/i, - rfocusable = /^(?:button|input|object|select|textarea)$/i, - rclickable = /^a(?:rea)?$/i, - rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, - getSetAttribute = jQuery.support.getSetAttribute, - nodeHook, boolHook, fixSpecified; - -jQuery.fn.extend({ - attr: function( name, value ) { - return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); - }, - - removeAttr: function( name ) { - return this.each(function() { - jQuery.removeAttr( this, name ); - }); - }, - - prop: function( name, value ) { - return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); - }, - - removeProp: function( name ) { - name = jQuery.propFix[ name ] || name; - return this.each(function() { - // try/catch handles cases where IE balks (such as removing a property on window) - try { - this[ name ] = undefined; - delete this[ name ]; - } catch( e ) {} - }); - }, - - addClass: function( value ) { - var classNames, i, l, elem, - setClass, c, cl; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).addClass( value.call(this, j, this.className) ); - }); - } - - if ( value && typeof value === "string" ) { - classNames = value.split( rspace ); - - for ( i = 0, l = this.length; i < l; i++ ) { - elem = this[ i ]; - - if ( elem.nodeType === 1 ) { - if ( !elem.className && classNames.length === 1 ) { - elem.className = value; - - } else { - setClass = " " + elem.className + " "; - - for ( c = 0, cl = classNames.length; c < cl; c++ ) { - if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { - setClass += classNames[ c ] + " "; - } - } - elem.className = jQuery.trim( setClass ); - } - } - } - } - - return this; - }, - - removeClass: function( value ) { - var classNames, i, l, elem, className, c, cl; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).removeClass( value.call(this, j, this.className) ); - }); - } - - if ( (value && typeof value === "string") || value === undefined ) { - classNames = ( value || "" ).split( rspace ); - - for ( i = 0, l = this.length; i < l; i++ ) { - elem = this[ i ]; - - if ( elem.nodeType === 1 && elem.className ) { - if ( value ) { - className = (" " + elem.className + " ").replace( rclass, " " ); - for ( c = 0, cl = classNames.length; c < cl; c++ ) { - className = className.replace(" " + classNames[ c ] + " ", " "); - } - elem.className = jQuery.trim( className ); - - } else { - elem.className = ""; - } - } - } - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - var type = typeof value, - isBool = typeof stateVal === "boolean"; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( i ) { - jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); - }); - } - - return this.each(function() { - if ( type === "string" ) { - // toggle individual class names - var className, - i = 0, - self = jQuery( this ), - state = stateVal, - classNames = value.split( rspace ); - - while ( (className = classNames[ i++ ]) ) { - // check each className given, space seperated list - state = isBool ? state : !self.hasClass( className ); - self[ state ? "addClass" : "removeClass" ]( className ); - } - - } else if ( type === "undefined" || type === "boolean" ) { - if ( this.className ) { - // store className if set - jQuery._data( this, "__className__", this.className ); - } - - // toggle whole className - this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; - } - }); - }, - - hasClass: function( selector ) { - var className = " " + selector + " ", - i = 0, - l = this.length; - for ( ; i < l; i++ ) { - if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { - return true; - } - } - - return false; - }, - - val: function( value ) { - var hooks, ret, isFunction, - elem = this[0]; - - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; - - if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { - return ret; - } - - ret = elem.value; - - return typeof ret === "string" ? - // handle most common string cases - ret.replace(rreturn, "") : - // handle cases where value is null/undef or number - ret == null ? "" : ret; - } - - return; - } - - isFunction = jQuery.isFunction( value ); - - return this.each(function( i ) { - var self = jQuery(this), val; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( isFunction ) { - val = value.call( this, i, self.val() ); - } else { - val = value; - } - - // Treat null/undefined as ""; convert numbers to string - if ( val == null ) { - val = ""; - } else if ( typeof val === "number" ) { - val += ""; - } else if ( jQuery.isArray( val ) ) { - val = jQuery.map(val, function ( value ) { - return value == null ? "" : value + ""; - }); - } - - hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; - - // If set returns undefined, fall back to normal setting - if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { - this.value = val; - } - }); - } -}); - -jQuery.extend({ - valHooks: { - option: { - get: function( elem ) { - // attributes.value is undefined in Blackberry 4.7 but - // uses .value. See #6932 - var val = elem.attributes.value; - return !val || val.specified ? elem.value : elem.text; - } - }, - select: { - get: function( elem ) { - var value, i, max, option, - index = elem.selectedIndex, - values = [], - options = elem.options, - one = elem.type === "select-one"; - - // Nothing was selected - if ( index < 0 ) { - return null; - } - - // Loop through all the selected options - i = one ? index : 0; - max = one ? index + 1 : options.length; - for ( ; i < max; i++ ) { - option = options[ i ]; - - // Don't return options that are disabled or in a disabled optgroup - if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && - (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { - - // Get the specific value for the option - value = jQuery( option ).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - // Fixes Bug #2551 -- select.val() broken in IE after form.reset() - if ( one && !values.length && options.length ) { - return jQuery( options[ index ] ).val(); - } - - return values; - }, - - set: function( elem, value ) { - var values = jQuery.makeArray( value ); - - jQuery(elem).find("option").each(function() { - this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; - }); - - if ( !values.length ) { - elem.selectedIndex = -1; - } - return values; - } - } - }, - - attrFn: { - val: true, - css: true, - html: true, - text: true, - data: true, - width: true, - height: true, - offset: true - }, - - attr: function( elem, name, value, pass ) { - var ret, hooks, notxml, - nType = elem.nodeType; - - // don't get/set attributes on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - if ( pass && name in jQuery.attrFn ) { - return jQuery( elem )[ name ]( value ); - } - - // Fallback to prop when attributes are not supported - if ( typeof elem.getAttribute === "undefined" ) { - return jQuery.prop( elem, name, value ); - } - - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); - - // All attributes are lowercase - // Grab necessary hook if one is defined - if ( notxml ) { - name = name.toLowerCase(); - hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); - } - - if ( value !== undefined ) { - - if ( value === null ) { - jQuery.removeAttr( elem, name ); - return; - - } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { - return ret; - - } else { - elem.setAttribute( name, "" + value ); - return value; - } - - } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { - return ret; - - } else { - - ret = elem.getAttribute( name ); - - // Non-existent attributes return null, we normalize to undefined - return ret === null ? - undefined : - ret; - } - }, - - removeAttr: function( elem, value ) { - var propName, attrNames, name, l, isBool, - i = 0; - - if ( value && elem.nodeType === 1 ) { - attrNames = value.toLowerCase().split( rspace ); - l = attrNames.length; - - for ( ; i < l; i++ ) { - name = attrNames[ i ]; - - if ( name ) { - propName = jQuery.propFix[ name ] || name; - isBool = rboolean.test( name ); - - // See #9699 for explanation of this approach (setting first, then removal) - // Do not do this for boolean attributes (see #10870) - if ( !isBool ) { - jQuery.attr( elem, name, "" ); - } - elem.removeAttribute( getSetAttribute ? name : propName ); - - // Set corresponding property to false for boolean attributes - if ( isBool && propName in elem ) { - elem[ propName ] = false; - } - } - } - } - }, - - attrHooks: { - type: { - set: function( elem, value ) { - // We can't allow the type property to be changed (since it causes problems in IE) - if ( rtype.test( elem.nodeName ) && elem.parentNode ) { - jQuery.error( "type property can't be changed" ); - } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { - // Setting the type on a radio button after the value resets the value in IE6-9 - // Reset value to it's default in case type is set after value - // This is for element creation - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } - }, - // Use the value property for back compat - // Use the nodeHook for button elements in IE6/7 (#1954) - value: { - get: function( elem, name ) { - if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { - return nodeHook.get( elem, name ); - } - return name in elem ? - elem.value : - null; - }, - set: function( elem, value, name ) { - if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { - return nodeHook.set( elem, value, name ); - } - // Does not return so that setAttribute is also used - elem.value = value; - } - } - }, - - propFix: { - tabindex: "tabIndex", - readonly: "readOnly", - "for": "htmlFor", - "class": "className", - maxlength: "maxLength", - cellspacing: "cellSpacing", - cellpadding: "cellPadding", - rowspan: "rowSpan", - colspan: "colSpan", - usemap: "useMap", - frameborder: "frameBorder", - contenteditable: "contentEditable" - }, - - prop: function( elem, name, value ) { - var ret, hooks, notxml, - nType = elem.nodeType; - - // don't get/set properties on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); - - if ( notxml ) { - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } - - if ( value !== undefined ) { - if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { - return ret; - - } else { - return ( elem[ name ] = value ); - } - - } else { - if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { - return ret; - - } else { - return elem[ name ]; - } - } - }, - - propHooks: { - tabIndex: { - get: function( elem ) { - // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set - // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - var attributeNode = elem.getAttributeNode("tabindex"); - - return attributeNode && attributeNode.specified ? - parseInt( attributeNode.value, 10 ) : - rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? - 0 : - undefined; - } - } - } -}); - -// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) -jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; - -// Hook for boolean attributes -boolHook = { - get: function( elem, name ) { - // Align boolean attributes with corresponding properties - // Fall back to attribute presence where some booleans are not supported - var attrNode, - property = jQuery.prop( elem, name ); - return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? - name.toLowerCase() : - undefined; - }, - set: function( elem, value, name ) { - var propName; - if ( value === false ) { - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else { - // value is true since we know at this point it's type boolean and not false - // Set boolean attributes to the same name and set the DOM property - propName = jQuery.propFix[ name ] || name; - if ( propName in elem ) { - // Only set the IDL specifically if it already exists on the element - elem[ propName ] = true; - } - - elem.setAttribute( name, name.toLowerCase() ); - } - return name; - } -}; - -// IE6/7 do not support getting/setting some attributes with get/setAttribute -if ( !getSetAttribute ) { - - fixSpecified = { - name: true, - id: true, - coords: true - }; - - // Use this for any attribute in IE6/7 - // This fixes almost every IE6/7 issue - nodeHook = jQuery.valHooks.button = { - get: function( elem, name ) { - var ret; - ret = elem.getAttributeNode( name ); - return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? - ret.nodeValue : - undefined; - }, - set: function( elem, value, name ) { - // Set the existing or create a new attribute node - var ret = elem.getAttributeNode( name ); - if ( !ret ) { - ret = document.createAttribute( name ); - elem.setAttributeNode( ret ); - } - return ( ret.nodeValue = value + "" ); - } - }; - - // Apply the nodeHook to tabindex - jQuery.attrHooks.tabindex.set = nodeHook.set; - - // Set width and height to auto instead of 0 on empty string( Bug #8150 ) - // This is for removals - jQuery.each([ "width", "height" ], function( i, name ) { - jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { - set: function( elem, value ) { - if ( value === "" ) { - elem.setAttribute( name, "auto" ); - return value; - } - } - }); - }); - - // Set contenteditable to false on removals(#10429) - // Setting to empty string throws an error as an invalid value - jQuery.attrHooks.contenteditable = { - get: nodeHook.get, - set: function( elem, value, name ) { - if ( value === "" ) { - value = "false"; - } - nodeHook.set( elem, value, name ); - } - }; -} - - -// Some attributes require a special call on IE -if ( !jQuery.support.hrefNormalized ) { - jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { - jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { - get: function( elem ) { - var ret = elem.getAttribute( name, 2 ); - return ret === null ? undefined : ret; - } - }); - }); -} - -if ( !jQuery.support.style ) { - jQuery.attrHooks.style = { - get: function( elem ) { - // Return undefined in the case of empty string - // Normalize to lowercase since IE uppercases css property names - return elem.style.cssText.toLowerCase() || undefined; - }, - set: function( elem, value ) { - return ( elem.style.cssText = "" + value ); - } - }; -} - -// Safari mis-reports the default selected property of an option -// Accessing the parent's selectedIndex property fixes it -if ( !jQuery.support.optSelected ) { - jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { - get: function( elem ) { - var parent = elem.parentNode; - - if ( parent ) { - parent.selectedIndex; - - // Make sure that it also works with optgroups, see #5701 - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - return null; - } - }); -} - -// IE6/7 call enctype encoding -if ( !jQuery.support.enctype ) { - jQuery.propFix.enctype = "encoding"; -} - -// Radios and checkboxes getter/setter -if ( !jQuery.support.checkOn ) { - jQuery.each([ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - get: function( elem ) { - // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified - return elem.getAttribute("value") === null ? "on" : elem.value; - } - }; - }); -} -jQuery.each([ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { - set: function( elem, value ) { - if ( jQuery.isArray( value ) ) { - return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); - } - } - }); -}); - - - - -var rformElems = /^(?:textarea|input|select)$/i, - rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, - rhoverHack = /(?:^|\s)hover(\.\S+)?\b/, - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|contextmenu)|click/, - rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, - quickParse = function( selector ) { - var quick = rquickIs.exec( selector ); - if ( quick ) { - // 0 1 2 3 - // [ _, tag, id, class ] - quick[1] = ( quick[1] || "" ).toLowerCase(); - quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); - } - return quick; - }, - quickIs = function( elem, m ) { - var attrs = elem.attributes || {}; - return ( - (!m[1] || elem.nodeName.toLowerCase() === m[1]) && - (!m[2] || (attrs.id || {}).value === m[2]) && - (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) - ); - }, - hoverHack = function( events ) { - return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); - }; - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - add: function( elem, types, handler, data, selector ) { - - var elemData, eventHandle, events, - t, tns, type, namespaces, handleObj, - handleObjIn, quick, handlers, special; - - // Don't attach events to noData or text/comment nodes (allow plain objects tho) - if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - events = elemData.events; - if ( !events ) { - elemData.events = events = {}; - } - eventHandle = elemData.handle; - if ( !eventHandle ) { - elemData.handle = eventHandle = function( e ) { - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? - jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : - undefined; - }; - // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events - eventHandle.elem = elem; - } - - // Handle multiple events separated by a space - // jQuery(...).bind("mouseover mouseout", fn); - types = jQuery.trim( hoverHack(types) ).split( " " ); - for ( t = 0; t < types.length; t++ ) { - - tns = rtypenamespace.exec( types[t] ) || []; - type = tns[1]; - namespaces = ( tns[2] || "" ).split( "." ).sort(); - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend({ - type: type, - origType: tns[1], - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - quick: selector && quickParse( selector ), - namespace: namespaces.join(".") - }, handleObjIn ); - - // Init the event handler queue if we're the first - handlers = events[ type ]; - if ( !handlers ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener/attachEvent if the special events handler returns false - if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - // Bind the global event handler to the element - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle, false ); - - } else if ( elem.attachEvent ) { - elem.attachEvent( "on" + type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - // Nullify elem to prevent memory leaks in IE - elem = null; - }, - - global: {}, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - - var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), - t, tns, type, origType, namespaces, origCount, - j, events, special, handle, eventType, handleObj; - - if ( !elemData || !(events = elemData.events) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = jQuery.trim( hoverHack( types || "" ) ).split(" "); - for ( t = 0; t < types.length; t++ ) { - tns = rtypenamespace.exec( types[t] ) || []; - type = origType = tns[1]; - namespaces = tns[2]; - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector? special.delegateType : special.bindType ) || type; - eventType = events[ type ] || []; - origCount = eventType.length; - namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; - - // Remove matching events - for ( j = 0; j < eventType.length; j++ ) { - handleObj = eventType[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !namespaces || namespaces.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { - eventType.splice( j--, 1 ); - - if ( handleObj.selector ) { - eventType.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( eventType.length === 0 && origCount !== eventType.length ) { - if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - handle = elemData.handle; - if ( handle ) { - handle.elem = null; - } - - // removeData also checks for emptiness and clears the expando if empty - // so use it instead of delete - jQuery.removeData( elem, [ "events", "handle" ], true ); - } - }, - - // Events that are safe to short-circuit if no handlers are attached. - // Native DOM events should not be added, they may have inline handlers. - customEvent: { - "getData": true, - "setData": true, - "changeData": true - }, - - trigger: function( event, data, elem, onlyHandlers ) { - // Don't do events on text and comment nodes - if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { - return; - } - - // Event object or event type - var type = event.type || event, - namespaces = [], - cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf( "!" ) >= 0 ) { - // Exclusive events trigger only for the exact event (no namespaces) - type = type.slice(0, -1); - exclusive = true; - } - - if ( type.indexOf( "." ) >= 0 ) { - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split("."); - type = namespaces.shift(); - namespaces.sort(); - } - - if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { - // No jQuery handlers for this event type, and it can't have inline handlers - return; - } - - // Caller can pass in an Event, Object, or just an event type string - event = typeof event === "object" ? - // jQuery.Event object - event[ jQuery.expando ] ? event : - // Object literal - new jQuery.Event( type, event ) : - // Just the event type (string) - new jQuery.Event( type ); - - event.type = type; - event.isTrigger = true; - event.exclusive = exclusive; - event.namespace = namespaces.join( "." ); - event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; - ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; - - // Handle a global trigger - if ( !elem ) { - - // TODO: Stop taunting the data cache; remove global events and always attach to document - cache = jQuery.cache; - for ( i in cache ) { - if ( cache[ i ].events && cache[ i ].events[ type ] ) { - jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); - } - } - return; - } - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data != null ? jQuery.makeArray( data ) : []; - data.unshift( event ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - eventPath = [[ elem, special.bindType || type ]]; - if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; - old = null; - for ( ; cur; cur = cur.parentNode ) { - eventPath.push([ cur, bubbleType ]); - old = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( old && old === elem.ownerDocument ) { - eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); - } - } - - // Fire handlers on the event path - for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { - - cur = eventPath[i][0]; - event.type = eventPath[i][1]; - - handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - // Note that this is a bare JS function and not a jQuery handler - handle = ontype && cur[ ontype ]; - if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { - event.preventDefault(); - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && - !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name name as the event. - // Can't use an .isFunction() check here because IE6/7 fails that test. - // Don't do default actions on window, that's where global variables be (#6170) - // IE<9 dies on focus/blur to hidden element (#1486) - if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - old = elem[ ontype ]; - - if ( old ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - elem[ type ](); - jQuery.event.triggered = undefined; - - if ( old ) { - elem[ ontype ] = old; - } - } - } - } - - return event.result; - }, - - dispatch: function( event ) { - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( event || window.event ); - - var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), - delegateCount = handlers.delegateCount, - args = [].slice.call( arguments, 0 ), - run_all = !event.exclusive && !event.namespace, - special = jQuery.event.special[ event.type ] || {}, - handlerQueue = [], - i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[0] = event; - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers that should run if there are delegated events - // Avoid non-left-click bubbling in Firefox (#3861) - if ( delegateCount && !(event.button && event.type === "click") ) { - - // Pregenerate a single jQuery object for reuse with .is() - jqcur = jQuery(this); - jqcur.context = this.ownerDocument || this; - - for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { - - // Don't process events on disabled elements (#6911, #8165) - if ( cur.disabled !== true ) { - selMatch = {}; - matches = []; - jqcur[0] = cur; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - sel = handleObj.selector; - - if ( selMatch[ sel ] === undefined ) { - selMatch[ sel ] = ( - handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) - ); - } - if ( selMatch[ sel ] ) { - matches.push( handleObj ); - } - } - if ( matches.length ) { - handlerQueue.push({ elem: cur, matches: matches }); - } - } - } - } - - // Add the remaining (directly-bound) handlers - if ( handlers.length > delegateCount ) { - handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); - } - - // Run delegates first; they may want to stop propagation beneath us - for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { - matched = handlerQueue[ i ]; - event.currentTarget = matched.elem; - - for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { - handleObj = matched.matches[ j ]; - - // Triggered event must either 1) be non-exclusive and have no namespace, or - // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). - if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { - - event.data = handleObj.data; - event.handleObj = handleObj; - - ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) - .apply( matched.elem, args ); - - if ( ret !== undefined ) { - event.result = ret; - if ( ret === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - // Includes some event props shared by KeyEvent and MouseEvent - // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** - props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), - - fixHooks: {}, - - keyHooks: { - props: "char charCode key keyCode".split(" "), - filter: function( event, original ) { - - // Add which for key events - if ( event.which == null ) { - event.which = original.charCode != null ? original.charCode : original.keyCode; - } - - return event; - } - }, - - mouseHooks: { - props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), - filter: function( event, original ) { - var eventDoc, doc, body, - button = original.button, - fromElement = original.fromElement; - - // Calculate pageX/Y if missing and clientX/Y available - if ( event.pageX == null && original.clientX != null ) { - eventDoc = event.target.ownerDocument || document; - doc = eventDoc.documentElement; - body = eventDoc.body; - - event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); - event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); - } - - // Add relatedTarget, if necessary - if ( !event.relatedTarget && fromElement ) { - event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && button !== undefined ) { - event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); - } - - return event; - } - }, - - fix: function( event ) { - if ( event[ jQuery.expando ] ) { - return event; - } - - // Create a writable copy of the event object and normalize some properties - var i, prop, - originalEvent = event, - fixHook = jQuery.event.fixHooks[ event.type ] || {}, - copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; - - event = jQuery.Event( originalEvent ); - - for ( i = copy.length; i; ) { - prop = copy[ --i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) - if ( !event.target ) { - event.target = originalEvent.srcElement || document; - } - - // Target should not be a text node (#504, Safari) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) - if ( event.metaKey === undefined ) { - event.metaKey = event.ctrlKey; - } - - return fixHook.filter? fixHook.filter( event, originalEvent ) : event; - }, - - special: { - ready: { - // Make sure the ready event is setup - setup: jQuery.bindReady - }, - - load: { - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - - focus: { - delegateType: "focusin" - }, - blur: { - delegateType: "focusout" - }, - - beforeunload: { - setup: function( data, namespaces, eventHandle ) { - // We only want to do this special case on windows - if ( jQuery.isWindow( this ) ) { - this.onbeforeunload = eventHandle; - } - }, - - teardown: function( namespaces, eventHandle ) { - if ( this.onbeforeunload === eventHandle ) { - this.onbeforeunload = null; - } - } - } - }, - - simulate: function( type, elem, event, bubble ) { - // Piggyback on a donor event to simulate a different one. - // Fake originalEvent to avoid donor's stopPropagation, but if the - // simulated event prevents default then we do the same on the donor. - var e = jQuery.extend( - new jQuery.Event(), - event, - { type: type, - isSimulated: true, - originalEvent: {} - } - ); - if ( bubble ) { - jQuery.event.trigger( e, null, elem ); - } else { - jQuery.event.dispatch.call( elem, e ); - } - if ( e.isDefaultPrevented() ) { - event.preventDefault(); - } - } -}; - -// Some plugins are using, but it's undocumented/deprecated and will be removed. -// The 1.7 special event interface should provide all the hooks needed now. -jQuery.event.handle = jQuery.event.dispatch; - -jQuery.removeEvent = document.removeEventListener ? - function( elem, type, handle ) { - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle, false ); - } - } : - function( elem, type, handle ) { - if ( elem.detachEvent ) { - elem.detachEvent( "on" + type, handle ); - } - }; - -jQuery.Event = function( src, props ) { - // Allow instantiation without the 'new' keyword - if ( !(this instanceof jQuery.Event) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || - src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || jQuery.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -function returnFalse() { - return false; -} -function returnTrue() { - return true; -} - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - preventDefault: function() { - this.isDefaultPrevented = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - - // if preventDefault exists run it on the original event - if ( e.preventDefault ) { - e.preventDefault(); - - // otherwise set the returnValue property of the original event to false (IE) - } else { - e.returnValue = false; - } - }, - stopPropagation: function() { - this.isPropagationStopped = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - // if stopPropagation exists run it on the original event - if ( e.stopPropagation ) { - e.stopPropagation(); - } - // otherwise set the cancelBubble property of the original event to true (IE) - e.cancelBubble = true; - }, - stopImmediatePropagation: function() { - this.isImmediatePropagationStopped = returnTrue; - this.stopPropagation(); - }, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse -}; - -// Create mouseenter/leave events using mouseover/out and event-time checks -jQuery.each({ - mouseenter: "mouseover", - mouseleave: "mouseout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var target = this, - related = event.relatedTarget, - handleObj = event.handleObj, - selector = handleObj.selector, - ret; - - // For mousenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || (related !== target && !jQuery.contains( target, related )) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -}); - -// IE submit delegation -if ( !jQuery.support.submitBubbles ) { - - jQuery.event.special.submit = { - setup: function() { - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Lazy-add a submit handler when a descendant form may potentially be submitted - jQuery.event.add( this, "click._submit keypress._submit", function( e ) { - // Node name check avoids a VML-related crash in IE (#9807) - var elem = e.target, - form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; - if ( form && !form._submit_attached ) { - jQuery.event.add( form, "submit._submit", function( event ) { - event._submit_bubble = true; - }); - form._submit_attached = true; - } - }); - // return undefined since we don't need an event listener - }, - - postDispatch: function( event ) { - // If form was submitted by the user, bubble the event up the tree - if ( event._submit_bubble ) { - delete event._submit_bubble; - if ( this.parentNode && !event.isTrigger ) { - jQuery.event.simulate( "submit", this.parentNode, event, true ); - } - } - }, - - teardown: function() { - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Remove delegated handlers; cleanData eventually reaps submit handlers attached above - jQuery.event.remove( this, "._submit" ); - } - }; -} - -// IE change delegation and checkbox/radio fix -if ( !jQuery.support.changeBubbles ) { - - jQuery.event.special.change = { - - setup: function() { - - if ( rformElems.test( this.nodeName ) ) { - // IE doesn't fire change on a check/radio until blur; trigger it on click - // after a propertychange. Eat the blur-change in special.change.handle. - // This still fires onchange a second time for check/radio after blur. - if ( this.type === "checkbox" || this.type === "radio" ) { - jQuery.event.add( this, "propertychange._change", function( event ) { - if ( event.originalEvent.propertyName === "checked" ) { - this._just_changed = true; - } - }); - jQuery.event.add( this, "click._change", function( event ) { - if ( this._just_changed && !event.isTrigger ) { - this._just_changed = false; - jQuery.event.simulate( "change", this, event, true ); - } - }); - } - return false; - } - // Delegated event; lazy-add a change handler on descendant inputs - jQuery.event.add( this, "beforeactivate._change", function( e ) { - var elem = e.target; - - if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { - jQuery.event.add( elem, "change._change", function( event ) { - if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { - jQuery.event.simulate( "change", this.parentNode, event, true ); - } - }); - elem._change_attached = true; - } - }); - }, - - handle: function( event ) { - var elem = event.target; - - // Swallow native change events from checkbox/radio, we already triggered them above - if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { - return event.handleObj.handler.apply( this, arguments ); - } - }, - - teardown: function() { - jQuery.event.remove( this, "._change" ); - - return rformElems.test( this.nodeName ); - } - }; -} - -// Create "bubbling" focus and blur events -if ( !jQuery.support.focusinBubbles ) { - jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler while someone wants focusin/focusout - var attaches = 0, - handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - if ( attaches++ === 0 ) { - document.addEventListener( orig, handler, true ); - } - }, - teardown: function() { - if ( --attaches === 0 ) { - document.removeEventListener( orig, handler, true ); - } - } - }; - }); -} - -jQuery.fn.extend({ - - on: function( types, selector, data, fn, /*INTERNAL*/ one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { // && selector != null - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - this.on( type, selector, data, types[ type ], one ); - } - return this; - } - - if ( data == null && fn == null ) { - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return this; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return this.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - }); - }, - one: function( types, selector, data, fn ) { - return this.on( types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - if ( types && types.preventDefault && types.handleObj ) { - // ( event ) dispatched jQuery.Event - var handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - // ( types-object [, selector] ) - for ( var type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each(function() { - jQuery.event.remove( this, types, fn, selector ); - }); - }, - - bind: function( types, data, fn ) { - return this.on( types, null, data, fn ); - }, - unbind: function( types, fn ) { - return this.off( types, null, fn ); - }, - - live: function( types, data, fn ) { - jQuery( this.context ).on( types, this.selector, data, fn ); - return this; - }, - die: function( types, fn ) { - jQuery( this.context ).off( types, this.selector || "**", fn ); - return this; - }, - - delegate: function( selector, types, data, fn ) { - return this.on( types, selector, data, fn ); - }, - undelegate: function( selector, types, fn ) { - // ( namespace ) or ( selector, types [, fn] ) - return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); - }, - - trigger: function( type, data ) { - return this.each(function() { - jQuery.event.trigger( type, data, this ); - }); - }, - triggerHandler: function( type, data ) { - if ( this[0] ) { - return jQuery.event.trigger( type, data, this[0], true ); - } - }, - - toggle: function( fn ) { - // Save reference to arguments for access in closure - var args = arguments, - guid = fn.guid || jQuery.guid++, - i = 0, - toggler = function( event ) { - // Figure out which function to execute - var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; - jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); - - // Make sure that clicks stop - event.preventDefault(); - - // and execute the function - return args[ lastToggle ].apply( this, arguments ) || false; - }; - - // link all the functions, so any of them can unbind this click handler - toggler.guid = guid; - while ( i < args.length ) { - args[ i++ ].guid = guid; - } - - return this.click( toggler ); - }, - - hover: function( fnOver, fnOut ) { - return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); - } -}); - -jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + - "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + - "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { - - // Handle event binding - jQuery.fn[ name ] = function( data, fn ) { - if ( fn == null ) { - fn = data; - data = null; - } - - return arguments.length > 0 ? - this.on( name, null, data, fn ) : - this.trigger( name ); - }; - - if ( jQuery.attrFn ) { - jQuery.attrFn[ name ] = true; - } - - if ( rkeyEvent.test( name ) ) { - jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; - } - - if ( rmouseEvent.test( name ) ) { - jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; - } -}); - - - -/*! - * Sizzle CSS Selector Engine - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){ - -var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, - expando = "sizcache" + (Math.random() + '').replace('.', ''), - done = 0, - toString = Object.prototype.toString, - hasDuplicate = false, - baseHasDuplicate = true, - rBackslash = /\\/g, - rReturn = /\r\n/g, - rNonWord = /\W/; - -// Here we check if the JavaScript engine is using some sort of -// optimization where it does not always call our comparision -// function. If that is the case, discard the hasDuplicate value. -// Thus far that includes Google Chrome. -[0, 0].sort(function() { - baseHasDuplicate = false; - return 0; -}); - -var Sizzle = function( selector, context, results, seed ) { - results = results || []; - context = context || document; - - var origContext = context; - - if ( context.nodeType !== 1 && context.nodeType !== 9 ) { - return []; - } - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - var m, set, checkSet, extra, ret, cur, pop, i, - prune = true, - contextXML = Sizzle.isXML( context ), - parts = [], - soFar = selector; - - // Reset the position of the chunker regexp (start from head) - do { - chunker.exec( "" ); - m = chunker.exec( soFar ); - - if ( m ) { - soFar = m[3]; - - parts.push( m[1] ); - - if ( m[2] ) { - extra = m[3]; - break; - } - } - } while ( m ); - - if ( parts.length > 1 && origPOS.exec( selector ) ) { - - if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { - set = posProcess( parts[0] + parts[1], context, seed ); - - } else { - set = Expr.relative[ parts[0] ] ? - [ context ] : - Sizzle( parts.shift(), context ); - - while ( parts.length ) { - selector = parts.shift(); - - if ( Expr.relative[ selector ] ) { - selector += parts.shift(); - } - - set = posProcess( selector, set, seed ); - } - } - - } else { - // Take a shortcut and set the context if the root selector is an ID - // (but not if it'll be faster if the inner selector is an ID) - if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && - Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { - - ret = Sizzle.find( parts.shift(), context, contextXML ); - context = ret.expr ? - Sizzle.filter( ret.expr, ret.set )[0] : - ret.set[0]; - } - - if ( context ) { - ret = seed ? - { expr: parts.pop(), set: makeArray(seed) } : - Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); - - set = ret.expr ? - Sizzle.filter( ret.expr, ret.set ) : - ret.set; - - if ( parts.length > 0 ) { - checkSet = makeArray( set ); - - } else { - prune = false; - } - - while ( parts.length ) { - cur = parts.pop(); - pop = cur; - - if ( !Expr.relative[ cur ] ) { - cur = ""; - } else { - pop = parts.pop(); - } - - if ( pop == null ) { - pop = context; - } - - Expr.relative[ cur ]( checkSet, pop, contextXML ); - } - - } else { - checkSet = parts = []; - } - } - - if ( !checkSet ) { - checkSet = set; - } - - if ( !checkSet ) { - Sizzle.error( cur || selector ); - } - - if ( toString.call(checkSet) === "[object Array]" ) { - if ( !prune ) { - results.push.apply( results, checkSet ); - - } else if ( context && context.nodeType === 1 ) { - for ( i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { - results.push( set[i] ); - } - } - - } else { - for ( i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && checkSet[i].nodeType === 1 ) { - results.push( set[i] ); - } - } - } - - } else { - makeArray( checkSet, results ); - } - - if ( extra ) { - Sizzle( extra, origContext, results, seed ); - Sizzle.uniqueSort( results ); - } - - return results; -}; - -Sizzle.uniqueSort = function( results ) { - if ( sortOrder ) { - hasDuplicate = baseHasDuplicate; - results.sort( sortOrder ); - - if ( hasDuplicate ) { - for ( var i = 1; i < results.length; i++ ) { - if ( results[i] === results[ i - 1 ] ) { - results.splice( i--, 1 ); - } - } - } - } - - return results; -}; - -Sizzle.matches = function( expr, set ) { - return Sizzle( expr, null, null, set ); -}; - -Sizzle.matchesSelector = function( node, expr ) { - return Sizzle( expr, null, null, [node] ).length > 0; -}; - -Sizzle.find = function( expr, context, isXML ) { - var set, i, len, match, type, left; - - if ( !expr ) { - return []; - } - - for ( i = 0, len = Expr.order.length; i < len; i++ ) { - type = Expr.order[i]; - - if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { - left = match[1]; - match.splice( 1, 1 ); - - if ( left.substr( left.length - 1 ) !== "\\" ) { - match[1] = (match[1] || "").replace( rBackslash, "" ); - set = Expr.find[ type ]( match, context, isXML ); - - if ( set != null ) { - expr = expr.replace( Expr.match[ type ], "" ); - break; - } - } - } - } - - if ( !set ) { - set = typeof context.getElementsByTagName !== "undefined" ? - context.getElementsByTagName( "*" ) : - []; - } - - return { set: set, expr: expr }; -}; - -Sizzle.filter = function( expr, set, inplace, not ) { - var match, anyFound, - type, found, item, filter, left, - i, pass, - old = expr, - result = [], - curLoop = set, - isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); - - while ( expr && set.length ) { - for ( type in Expr.filter ) { - if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { - filter = Expr.filter[ type ]; - left = match[1]; - - anyFound = false; - - match.splice(1,1); - - if ( left.substr( left.length - 1 ) === "\\" ) { - continue; - } - - if ( curLoop === result ) { - result = []; - } - - if ( Expr.preFilter[ type ] ) { - match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); - - if ( !match ) { - anyFound = found = true; - - } else if ( match === true ) { - continue; - } - } - - if ( match ) { - for ( i = 0; (item = curLoop[i]) != null; i++ ) { - if ( item ) { - found = filter( item, match, i, curLoop ); - pass = not ^ found; - - if ( inplace && found != null ) { - if ( pass ) { - anyFound = true; - - } else { - curLoop[i] = false; - } - - } else if ( pass ) { - result.push( item ); - anyFound = true; - } - } - } - } - - if ( found !== undefined ) { - if ( !inplace ) { - curLoop = result; - } - - expr = expr.replace( Expr.match[ type ], "" ); - - if ( !anyFound ) { - return []; - } - - break; - } - } - } - - // Improper expression - if ( expr === old ) { - if ( anyFound == null ) { - Sizzle.error( expr ); - - } else { - break; - } - } - - old = expr; - } - - return curLoop; -}; - -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Utility function for retreiving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -var getText = Sizzle.getText = function( elem ) { - var i, node, - nodeType = elem.nodeType, - ret = ""; - - if ( nodeType ) { - if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { - // Use textContent || innerText for elements - if ( typeof elem.textContent === 'string' ) { - return elem.textContent; - } else if ( typeof elem.innerText === 'string' ) { - // Replace IE's carriage returns - return elem.innerText.replace( rReturn, '' ); - } else { - // Traverse it's children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - } else { - - // If no nodeType, this is expected to be an array - for ( i = 0; (node = elem[i]); i++ ) { - // Do not traverse comment nodes - if ( node.nodeType !== 8 ) { - ret += getText( node ); - } - } - } - return ret; -}; - -var Expr = Sizzle.selectors = { - order: [ "ID", "NAME", "TAG" ], - - match: { - ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, - CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, - NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, - ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, - TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, - CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, - POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, - PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ - }, - - leftMatch: {}, - - attrMap: { - "class": "className", - "for": "htmlFor" - }, - - attrHandle: { - href: function( elem ) { - return elem.getAttribute( "href" ); - }, - type: function( elem ) { - return elem.getAttribute( "type" ); - } - }, - - relative: { - "+": function(checkSet, part){ - var isPartStr = typeof part === "string", - isTag = isPartStr && !rNonWord.test( part ), - isPartStrNotTag = isPartStr && !isTag; - - if ( isTag ) { - part = part.toLowerCase(); - } - - for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { - if ( (elem = checkSet[i]) ) { - while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} - - checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? - elem || false : - elem === part; - } - } - - if ( isPartStrNotTag ) { - Sizzle.filter( part, checkSet, true ); - } - }, - - ">": function( checkSet, part ) { - var elem, - isPartStr = typeof part === "string", - i = 0, - l = checkSet.length; - - if ( isPartStr && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - - for ( ; i < l; i++ ) { - elem = checkSet[i]; - - if ( elem ) { - var parent = elem.parentNode; - checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; - } - } - - } else { - for ( ; i < l; i++ ) { - elem = checkSet[i]; - - if ( elem ) { - checkSet[i] = isPartStr ? - elem.parentNode : - elem.parentNode === part; - } - } - - if ( isPartStr ) { - Sizzle.filter( part, checkSet, true ); - } - } - }, - - "": function(checkSet, part, isXML){ - var nodeCheck, - doneName = done++, - checkFn = dirCheck; - - if ( typeof part === "string" && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - nodeCheck = part; - checkFn = dirNodeCheck; - } - - checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); - }, - - "~": function( checkSet, part, isXML ) { - var nodeCheck, - doneName = done++, - checkFn = dirCheck; - - if ( typeof part === "string" && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - nodeCheck = part; - checkFn = dirNodeCheck; - } - - checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); - } - }, - - find: { - ID: function( match, context, isXML ) { - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - return m && m.parentNode ? [m] : []; - } - }, - - NAME: function( match, context ) { - if ( typeof context.getElementsByName !== "undefined" ) { - var ret = [], - results = context.getElementsByName( match[1] ); - - for ( var i = 0, l = results.length; i < l; i++ ) { - if ( results[i].getAttribute("name") === match[1] ) { - ret.push( results[i] ); - } - } - - return ret.length === 0 ? null : ret; - } - }, - - TAG: function( match, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( match[1] ); - } - } - }, - preFilter: { - CLASS: function( match, curLoop, inplace, result, not, isXML ) { - match = " " + match[1].replace( rBackslash, "" ) + " "; - - if ( isXML ) { - return match; - } - - for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { - if ( elem ) { - if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { - if ( !inplace ) { - result.push( elem ); - } - - } else if ( inplace ) { - curLoop[i] = false; - } - } - } - - return false; - }, - - ID: function( match ) { - return match[1].replace( rBackslash, "" ); - }, - - TAG: function( match, curLoop ) { - return match[1].replace( rBackslash, "" ).toLowerCase(); - }, - - CHILD: function( match ) { - if ( match[1] === "nth" ) { - if ( !match[2] ) { - Sizzle.error( match[0] ); - } - - match[2] = match[2].replace(/^\+|\s*/g, ''); - - // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' - var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( - match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || - !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); - - // calculate the numbers (first)n+(last) including if they are negative - match[2] = (test[1] + (test[2] || 1)) - 0; - match[3] = test[3] - 0; - } - else if ( match[2] ) { - Sizzle.error( match[0] ); - } - - // TODO: Move to normal caching system - match[0] = done++; - - return match; - }, - - ATTR: function( match, curLoop, inplace, result, not, isXML ) { - var name = match[1] = match[1].replace( rBackslash, "" ); - - if ( !isXML && Expr.attrMap[name] ) { - match[1] = Expr.attrMap[name]; - } - - // Handle if an un-quoted value was used - match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); - - if ( match[2] === "~=" ) { - match[4] = " " + match[4] + " "; - } - - return match; - }, - - PSEUDO: function( match, curLoop, inplace, result, not ) { - if ( match[1] === "not" ) { - // If we're dealing with a complex expression, or a simple one - if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { - match[3] = Sizzle(match[3], null, null, curLoop); - - } else { - var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); - - if ( !inplace ) { - result.push.apply( result, ret ); - } - - return false; - } - - } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { - return true; - } - - return match; - }, - - POS: function( match ) { - match.unshift( true ); - - return match; - } - }, - - filters: { - enabled: function( elem ) { - return elem.disabled === false && elem.type !== "hidden"; - }, - - disabled: function( elem ) { - return elem.disabled === true; - }, - - checked: function( elem ) { - return elem.checked === true; - }, - - selected: function( elem ) { - // Accessing this property makes selected-by-default - // options in Safari work properly - if ( elem.parentNode ) { - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - parent: function( elem ) { - return !!elem.firstChild; - }, - - empty: function( elem ) { - return !elem.firstChild; - }, - - has: function( elem, i, match ) { - return !!Sizzle( match[3], elem ).length; - }, - - header: function( elem ) { - return (/h\d/i).test( elem.nodeName ); - }, - - text: function( elem ) { - var attr = elem.getAttribute( "type" ), type = elem.type; - // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) - // use getAttribute instead to test this case - return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); - }, - - radio: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; - }, - - checkbox: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; - }, - - file: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; - }, - - password: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; - }, - - submit: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && "submit" === elem.type; - }, - - image: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; - }, - - reset: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && "reset" === elem.type; - }, - - button: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && "button" === elem.type || name === "button"; - }, - - input: function( elem ) { - return (/input|select|textarea|button/i).test( elem.nodeName ); - }, - - focus: function( elem ) { - return elem === elem.ownerDocument.activeElement; - } - }, - setFilters: { - first: function( elem, i ) { - return i === 0; - }, - - last: function( elem, i, match, array ) { - return i === array.length - 1; - }, - - even: function( elem, i ) { - return i % 2 === 0; - }, - - odd: function( elem, i ) { - return i % 2 === 1; - }, - - lt: function( elem, i, match ) { - return i < match[3] - 0; - }, - - gt: function( elem, i, match ) { - return i > match[3] - 0; - }, - - nth: function( elem, i, match ) { - return match[3] - 0 === i; - }, - - eq: function( elem, i, match ) { - return match[3] - 0 === i; - } - }, - filter: { - PSEUDO: function( elem, match, i, array ) { - var name = match[1], - filter = Expr.filters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - - } else if ( name === "contains" ) { - return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; - - } else if ( name === "not" ) { - var not = match[3]; - - for ( var j = 0, l = not.length; j < l; j++ ) { - if ( not[j] === elem ) { - return false; - } - } - - return true; - - } else { - Sizzle.error( name ); - } - }, - - CHILD: function( elem, match ) { - var first, last, - doneName, parent, cache, - count, diff, - type = match[1], - node = elem; - - switch ( type ) { - case "only": - case "first": - while ( (node = node.previousSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - - if ( type === "first" ) { - return true; - } - - node = elem; - - /* falls through */ - case "last": - while ( (node = node.nextSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - - return true; - - case "nth": - first = match[2]; - last = match[3]; - - if ( first === 1 && last === 0 ) { - return true; - } - - doneName = match[0]; - parent = elem.parentNode; - - if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { - count = 0; - - for ( node = parent.firstChild; node; node = node.nextSibling ) { - if ( node.nodeType === 1 ) { - node.nodeIndex = ++count; - } - } - - parent[ expando ] = doneName; - } - - diff = elem.nodeIndex - last; - - if ( first === 0 ) { - return diff === 0; - - } else { - return ( diff % first === 0 && diff / first >= 0 ); - } - } - }, - - ID: function( elem, match ) { - return elem.nodeType === 1 && elem.getAttribute("id") === match; - }, - - TAG: function( elem, match ) { - return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; - }, - - CLASS: function( elem, match ) { - return (" " + (elem.className || elem.getAttribute("class")) + " ") - .indexOf( match ) > -1; - }, - - ATTR: function( elem, match ) { - var name = match[1], - result = Sizzle.attr ? - Sizzle.attr( elem, name ) : - Expr.attrHandle[ name ] ? - Expr.attrHandle[ name ]( elem ) : - elem[ name ] != null ? - elem[ name ] : - elem.getAttribute( name ), - value = result + "", - type = match[2], - check = match[4]; - - return result == null ? - type === "!=" : - !type && Sizzle.attr ? - result != null : - type === "=" ? - value === check : - type === "*=" ? - value.indexOf(check) >= 0 : - type === "~=" ? - (" " + value + " ").indexOf(check) >= 0 : - !check ? - value && result !== false : - type === "!=" ? - value !== check : - type === "^=" ? - value.indexOf(check) === 0 : - type === "$=" ? - value.substr(value.length - check.length) === check : - type === "|=" ? - value === check || value.substr(0, check.length + 1) === check + "-" : - false; - }, - - POS: function( elem, match, i, array ) { - var name = match[2], - filter = Expr.setFilters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } - } - } -}; - -var origPOS = Expr.match.POS, - fescape = function(all, num){ - return "\\" + (num - 0 + 1); - }; - -for ( var type in Expr.match ) { - Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); - Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); -} -// Expose origPOS -// "global" as in regardless of relation to brackets/parens -Expr.match.globalPOS = origPOS; - -var makeArray = function( array, results ) { - array = Array.prototype.slice.call( array, 0 ); - - if ( results ) { - results.push.apply( results, array ); - return results; - } - - return array; -}; - -// Perform a simple check to determine if the browser is capable of -// converting a NodeList to an array using builtin methods. -// Also verifies that the returned array holds DOM nodes -// (which is not the case in the Blackberry browser) -try { - Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; - -// Provide a fallback method if it does not work -} catch( e ) { - makeArray = function( array, results ) { - var i = 0, - ret = results || []; - - if ( toString.call(array) === "[object Array]" ) { - Array.prototype.push.apply( ret, array ); - - } else { - if ( typeof array.length === "number" ) { - for ( var l = array.length; i < l; i++ ) { - ret.push( array[i] ); - } - - } else { - for ( ; array[i]; i++ ) { - ret.push( array[i] ); - } - } - } - - return ret; - }; -} - -var sortOrder, siblingCheck; - -if ( document.documentElement.compareDocumentPosition ) { - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { - return a.compareDocumentPosition ? -1 : 1; - } - - return a.compareDocumentPosition(b) & 4 ? -1 : 1; - }; - -} else { - sortOrder = function( a, b ) { - // The nodes are identical, we can exit early - if ( a === b ) { - hasDuplicate = true; - return 0; - - // Fallback to using sourceIndex (in IE) if it's available on both nodes - } else if ( a.sourceIndex && b.sourceIndex ) { - return a.sourceIndex - b.sourceIndex; - } - - var al, bl, - ap = [], - bp = [], - aup = a.parentNode, - bup = b.parentNode, - cur = aup; - - // If the nodes are siblings (or identical) we can do a quick check - if ( aup === bup ) { - return siblingCheck( a, b ); - - // If no parents were found then the nodes are disconnected - } else if ( !aup ) { - return -1; - - } else if ( !bup ) { - return 1; - } - - // Otherwise they're somewhere else in the tree so we need - // to build up a full list of the parentNodes for comparison - while ( cur ) { - ap.unshift( cur ); - cur = cur.parentNode; - } - - cur = bup; - - while ( cur ) { - bp.unshift( cur ); - cur = cur.parentNode; - } - - al = ap.length; - bl = bp.length; - - // Start walking down the tree looking for a discrepancy - for ( var i = 0; i < al && i < bl; i++ ) { - if ( ap[i] !== bp[i] ) { - return siblingCheck( ap[i], bp[i] ); - } - } - - // We ended someplace up the tree so do a sibling check - return i === al ? - siblingCheck( a, bp[i], -1 ) : - siblingCheck( ap[i], b, 1 ); - }; - - siblingCheck = function( a, b, ret ) { - if ( a === b ) { - return ret; - } - - var cur = a.nextSibling; - - while ( cur ) { - if ( cur === b ) { - return -1; - } - - cur = cur.nextSibling; - } - - return 1; - }; -} - -// Check to see if the browser returns elements by name when -// querying by getElementById (and provide a workaround) -(function(){ - // We're going to inject a fake input element with a specified name - var form = document.createElement("div"), - id = "script" + (new Date()).getTime(), - root = document.documentElement; - - form.innerHTML = ""; - - // Inject it into the root element, check its status, and remove it quickly - root.insertBefore( form, root.firstChild ); - - // The workaround has to do additional checks after a getElementById - // Which slows things down for other browsers (hence the branching) - if ( document.getElementById( id ) ) { - Expr.find.ID = function( match, context, isXML ) { - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - - return m ? - m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? - [m] : - undefined : - []; - } - }; - - Expr.filter.ID = function( elem, match ) { - var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); - - return elem.nodeType === 1 && node && node.nodeValue === match; - }; - } - - root.removeChild( form ); - - // release memory in IE - root = form = null; -})(); - -(function(){ - // Check to see if the browser returns only elements - // when doing getElementsByTagName("*") - - // Create a fake element - var div = document.createElement("div"); - div.appendChild( document.createComment("") ); - - // Make sure no comments are found - if ( div.getElementsByTagName("*").length > 0 ) { - Expr.find.TAG = function( match, context ) { - var results = context.getElementsByTagName( match[1] ); - - // Filter out possible comments - if ( match[1] === "*" ) { - var tmp = []; - - for ( var i = 0; results[i]; i++ ) { - if ( results[i].nodeType === 1 ) { - tmp.push( results[i] ); - } - } - - results = tmp; - } - - return results; - }; - } - - // Check to see if an attribute returns normalized href attributes - div.innerHTML = ""; - - if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && - div.firstChild.getAttribute("href") !== "#" ) { - - Expr.attrHandle.href = function( elem ) { - return elem.getAttribute( "href", 2 ); - }; - } - - // release memory in IE - div = null; -})(); - -if ( document.querySelectorAll ) { - (function(){ - var oldSizzle = Sizzle, - div = document.createElement("div"), - id = "__sizzle__"; - - div.innerHTML = "

"; - - // Safari can't handle uppercase or unicode characters when - // in quirks mode. - if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { - return; - } - - Sizzle = function( query, context, extra, seed ) { - context = context || document; - - // Only use querySelectorAll on non-XML documents - // (ID selectors don't work in non-HTML documents) - if ( !seed && !Sizzle.isXML(context) ) { - // See if we find a selector to speed up - var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); - - if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { - // Speed-up: Sizzle("TAG") - if ( match[1] ) { - return makeArray( context.getElementsByTagName( query ), extra ); - - // Speed-up: Sizzle(".CLASS") - } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { - return makeArray( context.getElementsByClassName( match[2] ), extra ); - } - } - - if ( context.nodeType === 9 ) { - // Speed-up: Sizzle("body") - // The body element only exists once, optimize finding it - if ( query === "body" && context.body ) { - return makeArray( [ context.body ], extra ); - - // Speed-up: Sizzle("#ID") - } else if ( match && match[3] ) { - var elem = context.getElementById( match[3] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id === match[3] ) { - return makeArray( [ elem ], extra ); - } - - } else { - return makeArray( [], extra ); - } - } - - try { - return makeArray( context.querySelectorAll(query), extra ); - } catch(qsaError) {} - - // qSA works strangely on Element-rooted queries - // We can work around this by specifying an extra ID on the root - // and working up from there (Thanks to Andrew Dupont for the technique) - // IE 8 doesn't work on object elements - } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - var oldContext = context, - old = context.getAttribute( "id" ), - nid = old || id, - hasParent = context.parentNode, - relativeHierarchySelector = /^\s*[+~]/.test( query ); - - if ( !old ) { - context.setAttribute( "id", nid ); - } else { - nid = nid.replace( /'/g, "\\$&" ); - } - if ( relativeHierarchySelector && hasParent ) { - context = context.parentNode; - } - - try { - if ( !relativeHierarchySelector || hasParent ) { - return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); - } - - } catch(pseudoError) { - } finally { - if ( !old ) { - oldContext.removeAttribute( "id" ); - } - } - } - } - - return oldSizzle(query, context, extra, seed); - }; - - for ( var prop in oldSizzle ) { - Sizzle[ prop ] = oldSizzle[ prop ]; - } - - // release memory in IE - div = null; - })(); -} - -(function(){ - var html = document.documentElement, - matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; - - if ( matches ) { - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9 fails this) - var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), - pseudoWorks = false; - - try { - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( document.documentElement, "[test!='']:sizzle" ); - - } catch( pseudoError ) { - pseudoWorks = true; - } - - Sizzle.matchesSelector = function( node, expr ) { - // Make sure that attribute selectors are quoted - expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); - - if ( !Sizzle.isXML( node ) ) { - try { - if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { - var ret = matches.call( node, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || !disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9, so check for that - node.document && node.document.nodeType !== 11 ) { - return ret; - } - } - } catch(e) {} - } - - return Sizzle(expr, null, null, [node]).length > 0; - }; - } -})(); - -(function(){ - var div = document.createElement("div"); - - div.innerHTML = "
"; - - // Opera can't find a second classname (in 9.6) - // Also, make sure that getElementsByClassName actually exists - if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { - return; - } - - // Safari caches class attributes, doesn't catch changes (in 3.2) - div.lastChild.className = "e"; - - if ( div.getElementsByClassName("e").length === 1 ) { - return; - } - - Expr.order.splice(1, 0, "CLASS"); - Expr.find.CLASS = function( match, context, isXML ) { - if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { - return context.getElementsByClassName(match[1]); - } - }; - - // release memory in IE - div = null; -})(); - -function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - - if ( elem ) { - var match = false; - - elem = elem[dir]; - - while ( elem ) { - if ( elem[ expando ] === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 && !isXML ){ - elem[ expando ] = doneName; - elem.sizset = i; - } - - if ( elem.nodeName.toLowerCase() === cur ) { - match = elem; - break; - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - - if ( elem ) { - var match = false; - - elem = elem[dir]; - - while ( elem ) { - if ( elem[ expando ] === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 ) { - if ( !isXML ) { - elem[ expando ] = doneName; - elem.sizset = i; - } - - if ( typeof cur !== "string" ) { - if ( elem === cur ) { - match = true; - break; - } - - } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { - match = elem; - break; - } - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -if ( document.documentElement.contains ) { - Sizzle.contains = function( a, b ) { - return a !== b && (a.contains ? a.contains(b) : true); - }; - -} else if ( document.documentElement.compareDocumentPosition ) { - Sizzle.contains = function( a, b ) { - return !!(a.compareDocumentPosition(b) & 16); - }; - -} else { - Sizzle.contains = function() { - return false; - }; -} - -Sizzle.isXML = function( elem ) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; - - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -var posProcess = function( selector, context, seed ) { - var match, - tmpSet = [], - later = "", - root = context.nodeType ? [context] : context; - - // Position selectors must be done after the filter - // And so must :not(positional) so we move all PSEUDOs to the end - while ( (match = Expr.match.PSEUDO.exec( selector )) ) { - later += match[0]; - selector = selector.replace( Expr.match.PSEUDO, "" ); - } - - selector = Expr.relative[selector] ? selector + "*" : selector; - - for ( var i = 0, l = root.length; i < l; i++ ) { - Sizzle( selector, root[i], tmpSet, seed ); - } - - return Sizzle.filter( later, tmpSet ); -}; - -// EXPOSE -// Override sizzle attribute retrieval -Sizzle.attr = jQuery.attr; -Sizzle.selectors.attrMap = {}; -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.filters; -jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; - - -})(); - - -var runtil = /Until$/, - rparentsprev = /^(?:parents|prevUntil|prevAll)/, - // Note: This RegExp should be improved, or likely pulled from Sizzle - rmultiselector = /,/, - isSimple = /^.[^:#\[\.,]*$/, - slice = Array.prototype.slice, - POS = jQuery.expr.match.globalPOS, - // methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.fn.extend({ - find: function( selector ) { - var self = this, - i, l; - - if ( typeof selector !== "string" ) { - return jQuery( selector ).filter(function() { - for ( i = 0, l = self.length; i < l; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - }); - } - - var ret = this.pushStack( "", "find", selector ), - length, n, r; - - for ( i = 0, l = this.length; i < l; i++ ) { - length = ret.length; - jQuery.find( selector, this[i], ret ); - - if ( i > 0 ) { - // Make sure that the results are unique - for ( n = length; n < ret.length; n++ ) { - for ( r = 0; r < length; r++ ) { - if ( ret[r] === ret[n] ) { - ret.splice(n--, 1); - break; - } - } - } - } - } - - return ret; - }, - - has: function( target ) { - var targets = jQuery( target ); - return this.filter(function() { - for ( var i = 0, l = targets.length; i < l; i++ ) { - if ( jQuery.contains( this, targets[i] ) ) { - return true; - } - } - }); - }, - - not: function( selector ) { - return this.pushStack( winnow(this, selector, false), "not", selector); - }, - - filter: function( selector ) { - return this.pushStack( winnow(this, selector, true), "filter", selector ); - }, - - is: function( selector ) { - return !!selector && ( - typeof selector === "string" ? - // If this is a positional selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - POS.test( selector ) ? - jQuery( selector, this.context ).index( this[0] ) >= 0 : - jQuery.filter( selector, this ).length > 0 : - this.filter( selector ).length > 0 ); - }, - - closest: function( selectors, context ) { - var ret = [], i, l, cur = this[0]; - - // Array (deprecated as of jQuery 1.7) - if ( jQuery.isArray( selectors ) ) { - var level = 1; - - while ( cur && cur.ownerDocument && cur !== context ) { - for ( i = 0; i < selectors.length; i++ ) { - - if ( jQuery( cur ).is( selectors[ i ] ) ) { - ret.push({ selector: selectors[ i ], elem: cur, level: level }); - } - } - - cur = cur.parentNode; - level++; - } - - return ret; - } - - // String - var pos = POS.test( selectors ) || typeof selectors !== "string" ? - jQuery( selectors, context || this.context ) : - 0; - - for ( i = 0, l = this.length; i < l; i++ ) { - cur = this[i]; - - while ( cur ) { - if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { - ret.push( cur ); - break; - - } else { - cur = cur.parentNode; - if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { - break; - } - } - } - } - - ret = ret.length > 1 ? jQuery.unique( ret ) : ret; - - return this.pushStack( ret, "closest", selectors ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; - } - - // index in selector - if ( typeof elem === "string" ) { - return jQuery.inArray( this[0], jQuery( elem ) ); - } - - // Locate the position of the desired element - return jQuery.inArray( - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[0] : elem, this ); - }, - - add: function( selector, context ) { - var set = typeof selector === "string" ? - jQuery( selector, context ) : - jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), - all = jQuery.merge( this.get(), set ); - - return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? - all : - jQuery.unique( all ) ); - }, - - andSelf: function() { - return this.add( this.prevObject ); - } -}); - -// A painfully simple check to see if an element is disconnected -// from a document (should be improved, where feasible). -function isDisconnected( node ) { - return !node || !node.parentNode || node.parentNode.nodeType === 11; -} - -jQuery.each({ - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return jQuery.dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, i, until ) { - return jQuery.dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return jQuery.nth( elem, 2, "nextSibling" ); - }, - prev: function( elem ) { - return jQuery.nth( elem, 2, "previousSibling" ); - }, - nextAll: function( elem ) { - return jQuery.dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return jQuery.dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, i, until ) { - return jQuery.dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, i, until ) { - return jQuery.dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); - }, - children: function( elem ) { - return jQuery.sibling( elem.firstChild ); - }, - contents: function( elem ) { - return jQuery.nodeName( elem, "iframe" ) ? - elem.contentDocument || elem.contentWindow.document : - jQuery.makeArray( elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var ret = jQuery.map( this, fn, until ); - - if ( !runtil.test( name ) ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; - - if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { - ret = ret.reverse(); - } - - return this.pushStack( ret, name, slice.call( arguments ).join(",") ); - }; -}); - -jQuery.extend({ - filter: function( expr, elems, not ) { - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return elems.length === 1 ? - jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : - jQuery.find.matches(expr, elems); - }, - - dir: function( elem, dir, until ) { - var matched = [], - cur = elem[ dir ]; - - while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { - if ( cur.nodeType === 1 ) { - matched.push( cur ); - } - cur = cur[dir]; - } - return matched; - }, - - nth: function( cur, result, dir, elem ) { - result = result || 1; - var num = 0; - - for ( ; cur; cur = cur[dir] ) { - if ( cur.nodeType === 1 && ++num === result ) { - break; - } - } - - return cur; - }, - - sibling: function( n, elem ) { - var r = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - r.push( n ); - } - } - - return r; - } -}); - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, keep ) { - - // Can't pass null or undefined to indexOf in Firefox 4 - // Set to 0 to skip string check - qualifier = qualifier || 0; - - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep(elements, function( elem, i ) { - var retVal = !!qualifier.call( elem, i, elem ); - return retVal === keep; - }); - - } else if ( qualifier.nodeType ) { - return jQuery.grep(elements, function( elem, i ) { - return ( elem === qualifier ) === keep; - }); - - } else if ( typeof qualifier === "string" ) { - var filtered = jQuery.grep(elements, function( elem ) { - return elem.nodeType === 1; - }); - - if ( isSimple.test( qualifier ) ) { - return jQuery.filter(qualifier, filtered, !keep); - } else { - qualifier = jQuery.filter( qualifier, filtered ); - } - } - - return jQuery.grep(elements, function( elem, i ) { - return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; - }); -} - - - - -function createSafeFragment( document ) { - var list = nodeNames.split( "|" ), - safeFrag = document.createDocumentFragment(); - - if ( safeFrag.createElement ) { - while ( list.length ) { - safeFrag.createElement( - list.pop() - ); - } - } - return safeFrag; -} - -var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + - "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", - rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, - rleadingWhitespace = /^\s+/, - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, - rtagName = /<([\w:]+)/, - rtbody = /]", "i"), - // checked="checked" or checked - rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, - rscriptType = /\/(java|ecma)script/i, - rcleanScript = /^\s*", "" ], - legend: [ 1, "
", "
" ], - thead: [ 1, "", "
" ], - tr: [ 2, "", "
" ], - td: [ 3, "", "
" ], - col: [ 2, "", "
" ], - area: [ 1, "", "" ], - _default: [ 0, "", "" ] - }, - safeFragment = createSafeFragment( document ); - -wrapMap.optgroup = wrapMap.option; -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// IE can't serialize and - - - - - - - - - - -
-
-

Previous topic

-

UDS’s architecture

-

Next topic

-

UDS Database Models

-

This Page

- - - -
-
- - - - - - \ No newline at end of file diff --git a/server/documentation/_build/html/api/models.html b/server/documentation/_build/html/api/models.html deleted file mode 100644 index a1156e8f..00000000 --- a/server/documentation/_build/html/api/models.html +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - - UDS Database Models — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

UDS’s core API

-

Next topic

-

Service Related models

-

This Page

- - - -
-
- -
-
-
-
- -
-

UDS Database Models¶

-

This section describes de models used in UDS.

-

The models described here are implemented using Django models, so you can get more -info about Django models functionalty at Django project website

-

The function of the models inside UDS is to provide the persistence needed by -the core and by other utility classes that are provided, such as a Cache, Storage -or unique IDs.

-

Right now the models are used all over UDS, but with time we will limit the use -of this models to be done through managers or utility clases designed for that -purpose.

- -
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/api/models/authentication.html b/server/documentation/_build/html/api/models/authentication.html deleted file mode 100644 index 551a3da3..00000000 --- a/server/documentation/_build/html/api/models/authentication.html +++ /dev/null @@ -1,367 +0,0 @@ - - - - - - - - Authentication Related models — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Service Related models

-

Next topic

-

Transport Related models

-

This Page

- - - -
-
- -
-
-
-
- - - - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/api/models/other.html b/server/documentation/_build/html/api/models/other.html deleted file mode 100644 index d6843782..00000000 --- a/server/documentation/_build/html/api/models/other.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - - - Other models — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Table Of Contents

- - -

Previous topic

-

Transport Related models

-

Next topic

-

UDS Modules

-

This Page

- - - -
-
- -
-
-
-
- -
-

Other models¶

-
-

Environment related¶

-
-
    -
-
-
-
-class uds.models.Cache(*args, **kwargs)¶
-

Bases: django.db.models.base.Model

-

General caching model. This model is managed via uds.core.util.Cache.Cache class

-
-
-static cleanUp()¶
-

Purges the cache items that are no longer vaild.

-
- -
- -
-
-class uds.models.Storage(*args, **kwargs)¶
-

Bases: django.db.models.base.Model

-

General storage model. Used to store specific instances (transport, service, servicemanager, ...) persinstent information -not intended to be serialized/deserialized everytime one object instance is loaded/saved.

-
- -
-
-class uds.models.UniqueId(*args, **kwargs)¶
-

Bases: django.db.models.base.Model

-

Unique ID Database. Used to store unique names, unique macs, etc... -Managed via uds.core.util.UniqueIDGenerator.UniqueIDGenerator

-
- -
- - -
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/api/models/services.html b/server/documentation/_build/html/api/models/services.html deleted file mode 100644 index 9304eff9..00000000 --- a/server/documentation/_build/html/api/models/services.html +++ /dev/null @@ -1,808 +0,0 @@ - - - - - - - - Service Related models — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

UDS Database Models

-

Next topic

-

Authentication Related models

-

This Page

- - - -
-
- -
-
-
-
- - - - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/api/models/transport.html b/server/documentation/_build/html/api/models/transport.html deleted file mode 100644 index 21bf8444..00000000 --- a/server/documentation/_build/html/api/models/transport.html +++ /dev/null @@ -1,280 +0,0 @@ - - - - - - - - Transport Related models — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Authentication Related models

-

Next topic

-

Other models

-

This Page

- - - -
-
- -
-
-
-
- - - - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/api/modules.html b/server/documentation/_build/html/api/modules.html deleted file mode 100644 index 44ba1947..00000000 --- a/server/documentation/_build/html/api/modules.html +++ /dev/null @@ -1,162 +0,0 @@ - - - - - - - - UDS Modules — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Other models

-

Next topic

-

Base Module

-

This Page

- - - -
-
- -
-
-
-
- -
-

UDS Modules¶

-

Modules are the basic component of plugin architecture of UDS.

-

As so, they are spreadly covered here, and with -samples must give enough information for -allowing anyone to develop their own modules.

- -
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/api/modules/AuthenticatorModule.html b/server/documentation/_build/html/api/modules/AuthenticatorModule.html deleted file mode 100644 index 7447a22d..00000000 --- a/server/documentation/_build/html/api/modules/AuthenticatorModule.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - - Authenticator Modules — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Service Exceptions

-

Next topic

-

Authenticator Interface

-

This Page

- - - -
-
- -
-
-
-
- -
-

Authenticator Modules¶

-

Authenticator modules are responsible of providing the user authentication -part inside UDS.

-

They are composed of a package where it is provided and, at least, the following -elements:

-
-
    -
  • One icon for administration interface representation. Icon is png file of -16x16.
  • -
  • One class, derived from uds.core.auths.Authenticator, providing the needed -logic for that authenticator.
  • -
  • Registration of the class inside uds at package’s __init__.
  • -
-
-

All packages included inside uds.auths will automatically be imported, but -the authenticators needs to register as valid authenticators, and the best place -to do that is at the authenticator’s package __init__.

-

The best way to understand what you need to create your own authenticator, -is to look at modules samples

- -
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/api/modules/BaseModule.html b/server/documentation/_build/html/api/modules/BaseModule.html deleted file mode 100644 index 103d9b6d..00000000 --- a/server/documentation/_build/html/api/modules/BaseModule.html +++ /dev/null @@ -1,595 +0,0 @@ - - - - - - - - Base Module — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Table Of Contents

- - -

Previous topic

-

UDS Modules

-

Next topic

-

Form Fields

-

This Page

- - - -
-
- -
-
-
-
- -
-

Base Module¶

-

The Base module is the base class used for all modules of UDS.

-

In order to deveplop an UDS Module, there is a number of basic methods that you must provide.

-
-
There are the clases that are base of BaseModule, that are:
-
-
-
-
-
    -
-
-
-

BaseModule¶

-
-
-class uds.core.Module(environment, values=None)¶
-

Base class for all modules used by UDS. -This base module provides all the needed methods that modules must implement

-

All modules must, at least, implement the following:

-
    -
  • -
    Attributes:
    -
      -
    • typeName: -Name for this type of module (human readable) to assign to the module (string) -This name will be used to let the administrator identify this module.
    • -
    • typeType: -Name for this type of module (machine only) to assing to the module (string) -This name will be used internally to identify when a serialized module corresponds with this class.
    • -
    • typeDescription: -Description for this type of module. -This descriptio will be used to let the administrator identify what this module provides
    • -
    • iconFile: This is an icon file, in png format, used at administration client to identify this module. -This parameter may be optionall if you override the “icon” method.
    • -
    -
    -
    -
  • -
  • -
    Own Methods:
    -
      -
    • __init__() -The default constructor. The environment value is always provided (see Environment), but the -default values provided can be None. -Remember to allow the instantiation of the module with default params, because when deserialization is done, -the process is first instatiate with an environment but no parameters and then call “unmarshal” from Serializable.

      -
    • -
    • test()

      -
    • -
    • check()

      -
    • -
    • destroy(): Optional

      -
    • -
    • icon(): Optional, if you provide an icon file, this method loads it from module folder, -but you can override this so the icon is obtained from other source.

      -
    • -
    • marshal() -By default, this method serializes the values provided by user in form fields. You can override it, -but now it’s not needed because you can access config vars using Form Fields.

      -

      Anyway, if you override this method, you must also override next one

      -
    • -
    • unmarshal() -By default, this method de-serializes the values provided by user in form fields. You can override it, -but now it’s not needed because you can access config vars using Form Fields.

      -

      Anyway, if you override this method, you must also override previous one

      -
    • -
    -
    -
    -
  • -
  • -
    UserInterface Methods:
    -
    -
    -
    -
  • -
-

Environmentable is a base class that provides utility method to access a separate Environment for every single -module.

-
-
-exception ValidationException¶
-

Exception used to indicate that the params assigned are invalid

-
- -
-
-Module.check()¶
-

Method that will provide the “check” capability for the module.

-

The return value that this method must provide is simply an string, -preferable internacionalizated.

-
-
Returns:
-
Internacionalized (using ugettext) string of result of the check.
-
-
- -
-
-classmethod Module.description()¶
-

This method returns the “translated” description, that is, using -ugettext for transforming cls.typeDescription.

-
-
Args:
-
cls: This is a class method, so cls is the class
-
Returns:
-
Translated description (using ugettext)
-
-
- -
-
-Module.destroy()¶
-

Invoked before deleting an module from database.

-

Do whatever needed here, as deleting associated data if needed -(no example come to my head right now... :-) )

-
-
Returns:
-
Nothing
-
-
- -
-
-classmethod Module.icon(inBase64=True)¶
-

Reads the file specified by iconFile at module folder, and returns it content. -This is used to obtain an icon so administration can represent it.

-
-
Args:
-

cls: Class

-

inBase64: If true, the image will be returned as base 64 encoded

-
-
Returns:
-
Base 64 encoded or raw image, obtained from the specified file at -‘iconFile’ class attribute
-
-
- -
-
-Module.isDirty()¶
-

This method informs the core if the module has changed serializable data, -and that must be re-serialized

-

Default implemetation is that on every method call, module will be dirty

-

Note: The implementation of this is a work in progress, so right now the module will be serialized out on every acess

-
- -
-
-Module.marshal()¶
-

By default and if not overriden by descendants, this method, overridden -from Serializable, and returns the serialization of -form field stored values.

-
- -
-
-classmethod Module.name()¶
-

Returns “translated” typeName, using ugettext for transforming -cls.typeName

-
-
Args:
-
cls: This is a class method, so cls is the class
-
Returns:
-
Translated type name (using ugettext)
-
-
- -
-
-static Module.test(env, data)¶
-

Test if the connection data is ok.

-

Returns an array, first value indicates “Ok” if true, “Bad” or “Error” -if false. Second is a string describing operation

-
-
Args:
-

env: environment passed for testing (temporal environment passed)

-

data: data passed for testing (data obtained from the form -definition)

-
-
Returns:
-
Array of two elements, first is True of False, depending on test -(True is all right, false is error), -second is an String with error, preferably internacionalizated..
-
-
- -
-
-classmethod Module.type()¶
-

Returns typeType

-
-
Args:
-
cls: This is a class method, so cls is the class
-
Returns:
-
the typeType of this class (or derived class)
-
-
- -
-
-Module.unmarshal(str_)¶
-

By default and if not overriden by descendants, this method recovers -data serialized using serializeForm

-
- -
- -
-
-

Environmentable¶

-
-
-class uds.core.Environmentable(environment)¶
-

This is a base class provided for all objects that have an environment associated. These are mainly modules

-
-
-cache()¶
-

Utility method to access the cache of the environment containe by this object

-
-
Returns:
-
Cache for the object
-
-
- -
-
-env()¶
-

Utility method to access the envionment contained by this object

-
-
Returns:
-
Environmnet for the object
-
-
- -
-
-idGenerators(generatorId)¶
-

Utility method to access the id generator of the environment containe by this object

-
-
Args:
-
generatorId: Id of the generator to obtain
-
Returns:
-
Generator for the object and the id specified
-
-
- -
-
-setEnv(environment)¶
-

Assigns a new environment

-
-
Args:
-
environment: Environment to assign
-
-
- -
-
-storage()¶
-

Utility method to access the storage of the environment containe by this object

-
-
Returns:
-
Storage for the object
-
-
- -
- -
-
-

Serializable¶

-
-
-class uds.core.Serializable¶
-

This class represents the interface that all serializable objects must provide.

-

Every single serializable class must implement marshall & unmarshall methods. Also, the class must allow -to be initialized without parameters, so we can: -- Initialize the object with default values -- Read values from seralized data

-
-
-marshal()¶
-

This is the method that must be overriden in order to serialize an object.

-

The system will use in fact ‘seralize’ and ‘deserialize’ methods, but theese are -only suitable methods to “codify” serialized values

- --- - - - -
Note:This method must be overridden
-
- -
-
-serialize()¶
-

Serializes and “obfuscates’ the data.

-

The codec used to encode the string is obtained from the instance CODEC, so derived classes can -overwrite this attribute to set another codec

-
- -
-
-unmarshal(str_)¶
-

This is the method that must be overriden in order to unserialize an object.

-

The system will use in fact ‘seralize’ and ‘deserialize’ methods, but theese are -only convenients methods to “codify” serialized values.

-

Take into account that _str can be ‘’ (empty string), but hopefully it will never be none. -In that case, initialize the object with default values

-
-
Args:
-
str_ _ : String readed from persistent storage to deseralilize
-
- --- - - - -
Note:This method must be overridden
-
- -
-
-unserialize(str_)¶
-

des-obfuscates the data and then de-serializes it via unmarshal method

-

The codec used to decode the string is obtained from the instance CODEC, so derived classes can -overwrite this attribute to set another codec

-
- -
- -
-
-

UserInterface¶

-
-

UserInterface is the class responsible for managing the Field Descriptions of modules.

-

This fields descriptions are intended for allowing an easy exposition of configuration form via the -administration interface.

-

You can obtain more information about user interface fields at User interface fields types.

-
-
-
-class uds.core.ui.UserInterface.UserInterface(values=None)[source]¶
-

This class provides the management for gui descriptions (user forms)

-

Once a class is derived from this one, that class can contain Field -Descriptions, -that will be managed correctly.

-

By default, the values passed to this class constructor are used to fill -the gui form fields values.

-
-
-classmethod guiDescription(obj=None)[source]¶
-

This simple method generates the gui description needed by the -administration client, so it can -represent it at user interface and manage it.

-
-
Args:
-
-
object: If not none, object that will get its “initGui” invoked
-
This will only happen (not to be None) in Services.
-
-
-
-
- -
-
-initGui()[source]¶
-

This method gives the oportunity to initialize gui fields before they -are send to administartion client. -We need this because at initialization time we probably don’t have the -data for gui.

- --- - - - - - -
Note:This method is used as a “trick” to allow to modify default form -data for services. Services are child of Service Providers, and -will probably need data from Provider to fill initial form data. -The rest of modules will not use this, and this only will be used -when the user requests a new service or wants to modify existing -one.
Note:There is a drawback of this, and it is that there is that this -method will modify service default data. It will run fast (probably), -but may happen that two services of same type are requested at same -time, and returned data will be probable a nonsense. We will take care -of this posibility in a near version...
-
- -
-
-serializeForm()[source]¶
-

All values stored at form fields are serialized and returned as a single -string -Separating char is

-

The returned string is zipped and then converted to base 64

-

Note: Hidens are not serialized, they are ignored

-
- -
-
-unserializeForm(values)[source]¶
-

This method unserializes the values previously obtained using -serializeForm(), and stores -the valid values form form fileds inside its corresponding field

-
- -
-
-valuesDict()[source]¶
-

Returns own data needed for user interaction as a dict of key-names -> -values. The values returned must be strings.

-
-
Example:
-

we have 2 text field, first named “host” and second named “port”, -we can do something like this:

-
return { 'host' : self.host, 'port' : self.port }
-
-
-

(Just the reverse of __init__(), __init__ receives this -dict, valuesDict must return the dict)

-
-
-

Names must coincide with fields declared.

-
-
Returns:
-
Dictionary, associated with declared fields. -Default implementation returns the values stored at the gui form -fields declared.
-
- --- - - - -
Note:By default, the provided method returns the correct values -extracted from form fields
-
- -
- -
-
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/api/modules/FormFields.html b/server/documentation/_build/html/api/modules/FormFields.html deleted file mode 100644 index 3922c59b..00000000 --- a/server/documentation/_build/html/api/modules/FormFields.html +++ /dev/null @@ -1,559 +0,0 @@ - - - - - - - - Form Fields — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Base Module

-

Next topic

-

Service Modules

-

This Page

- - - -
-
- -
-
-
-
- -
-

Form Fields¶

-

Form Fields are utility clases provided for allowing easy communication of modules -and administration interface.

-

It helps to define the administration level forms that will be used to manage -different modules (service providers, services, authenticators, transports, ...)

-

All modules that needs to be presented to admin users, use UserInterface as one -of their base class.

-

Think that not all interfaces needed by different modules need a direct representation -at administration interface level, (for example, UserDeployment do not need to be -managed by administrators, nor publications, both corresponding to service modules).

-
-
    -
-
-
-
The types of fields provided are:
-
-
-
-
-
-class uds.core.ui.UserInterface.gui[source]¶
-

This class contains the representations of fields needed by UDS modules and -administation interface.

-

This contains fields types, that modules uses to make a form and interact -with users.

-

The use of this provided fields are as follows:

-

The Module is descendant of “BaseModule”, which also is inherited from this -class.

-

At class level, we declare the fields needed to interact with the user, as -this example:

-
class AuthModule(Authenticator):
-    # ...
-    # Other initializations
-    # ...
-    users = gui.EditableList(label = 'Users', tooltip = 'Select users',
-        order = 1, values = ['user1', 'user2', 'user3', 'user4'])
-    passw = gui.Password(label='Pass', length=32, tooltip='Password',
-        order = 2, required = True, defValue = '12345')
-    # ...
-    # more fields
-    # ...
-
-
-

At class instantiation, this data is extracted and processed, so the admin -can access this form to let users -create new instances of this module.

-
-
-class CheckBoxField(**options)[source]¶
-

This represents a check box field, with values “true” and “false”

-

The values of parameters are inherited from InputField

-

The valid values for this defvalue are: “true” and “false” (as strings)

-

Example usage:

-
-
# Declares an check box field, with label "Use SSL", order 3,
-# tooltip "If checked, will use a ssl connection", default value
-# unchecked (not included, so it's empty, so it's not true :-))
-ssl = gui.CheckBoxField(label = _('Use SSL'), order = 3,
-    tooltip = _('If checked, will use a ssl connection'))
-
-
-
-
-
-isTrue()[source]¶
-

Checks that the value is true

-
- -
- -
-
-class gui.ChoiceField(**options)[source]¶
-

This represents a simple combo box with single selection.

-

The values of parameters are inherited from InputField

-

ChoiceField needs a function to provide values inside it.

-
    -
  • We specify the values via “values” option this way:

    -
    -

    Example:

    -
    choices = gui.ChoiceField(label="choices", values = [ {'id':'1',
    -    'text':'Text 1'}, {'id':'xxx', 'text':'Text 2'}])
    -
    -
    -

    You can specify a multi valuated field via id-values, or a -single-valued field via id-value

    -
    -
  • -
  • We can override choice values at UserInterface derived class -constructor or initGui using setValues

    -
  • -
-

There is an extra option available for this kind of field:

-
-
-
fills: This options is a dictionary that contains this fields:
-
    -
  • -
    ‘callbackName’ : Callback name for invocation via the specific
    -

    method xml-rpc. This name is a name we assign to this callback, -and is used to locate the method when callback is invoked from -admin interface.

    -
    -
    -
  • -
  • ‘function’ : Function to execute.

    -
    -

    This funtion receives one parameter, that is a dictionary with -all parameters (that, in time, are fields names) that we have -requested.

    -

    The expected return value for this callback is an array of -dictionaries with fields and values to set, as -example show below shows.

    -
    -
  • -
  • -
    ‘parameters’ : Array of field names to pass back to server so
    -

    it can obtain the results.

    -

    Of course, this fields must be part of the module.

    -
    -
    -
  • -
-
-
-

Example:

-
-
choice1 = gui.ChoiceField(label="Choice 1", values = ....,
-    fills = { 'target': 'choice2', 'callback': fncValues,
-        'parameters': ['choice1', 'name']}
-    )
-choice2 = ghui.ChoiceField(label="Choice 2")
-
-
-

Here is a more detailed explanation, using the VC service module as -sample.

-
class VCHelpers(object):
-    # ...
-    # other stuff
-    # ...
-    @staticmethod
-    def getMachines(parameters):
-        # ...initialization and other stuff...
-        if parameters['resourcePool'] != '':
-            # ... do stuff ...
-        data = [ { 'name' : 'machine', 'values' : 'xxxxxx' } ]
-        return data
-
-class ModuleVC(services.Service)
-   # ...
-   # stuff
-   # ...
-   resourcePool = gui.ChoiceField(
-       label=_("Resource Pool"), rdonly = False, order = 5,
-       fills = {
-           'callbackName' : 'vcFillMachinesFromResource',
-           'function' : VCHelpers.getMachines,
-           'parameters' : ['vc', 'ev', 'resourcePool']
-       },
-       tooltip = _('Resource Pool containing base machine'),
-       required = True
-   )
-
-   machine = gui.ChoiceField(label = _("Base Machine"), order = 6,
-       tooltip = _('Base machine for this service'), required = True )
-
-   vc = gui.HiddenField()
-   ev = gui.HiddenField() # ....
-
-
-
-
-
-
-setValues(values)[source]¶
-

Set the values for this choice field

-
- -
- -
-
-class gui.EditableList(**options)[source]¶
-

Editables list are lists of editable elements (i.e., a list of IPs, macs, -names, etcc) treated as simple strings with no id

-

The struct used to pass values is an array of strings, i.e. [‘1’, ‘2’, -‘test’, ‘bebito’, ...]

-

This list don’t have “selected” items, so its defvalue field is simply -ignored.

-

We only nee to pass in “label” and, maybe, “values” to set default -content for the list.

-

Keep in mind that this is an user editable list, so the user can insert -values and/or import values from files, so -by default it will probably have no content at all.

-

Example usage:

-
-
#
-ipList = gui.EditableList(label=_('List of IPS'))
-
-
-
-
- -
-
-class gui.HiddenField(**options)[source]¶
-

This represents a hidden field. It is not displayed to the user. It use -is for keeping info at form needed -by module, but not editable by user (i.e., one service can keep info -about the parent provider in hiddens)

-

The values of parameres are inherited from InputField

-

These are almost the same as TextFields, but they do not get displayed -for user interaction.

-

Example usage:

-
-
# Declares an empty hidden field
-hidden = gui.HiddenField()
-
-
-

After that, at initGui method of module, we can store a value inside -using setDefValue as shown here:

-
def initGui(self):
-    # always set defValue using self, cause we only want to store
-    # value for current instance
-    self.hidden.setDefValue(self.parent().serialize())
-
-
-
-
- -
-
-class gui.InputField(**options)[source]¶
-

Class representing an simple input field. -This class is not directly usable, must be used by any inherited class -(fields all of them) -All fields are inherited from this one

-
-
The data managed for an input field, and their default values are:
-
    -
  • length: Max length of the field. Defaults to DEFAULT_LENGTH
  • -
  • required: If this field is a MUST. defaults to false
  • -
  • label: Label used with this field. Defaults to ‘’
  • -
  • defvalue: Default value for the field. Defaults to ‘’ (this is -always an string)
  • -
  • rdonly: If the field is read only on modification. On creation, -all fields are “writable”. Defaults to False
  • -
  • order: order inside the form, defaults to 0 (if two or more fields -has same order, the output order may be anything)
  • -
  • tooltip: Tooltip used in the form, defaults to ‘’
  • -
  • type: type of the input field, defaults to “text box” (TextField)
  • -
-
-
In every single field, you must at least indicate:
-
    -
  • if required or not
  • -
  • order
  • -
  • label
  • -
  • tooltip
  • -
  • defvalue
  • -
  • rdonly if can’t be modified once it’s created
  • -
-
-
-

Any other paremeter needed is indicated in the corresponding field class.

-

Also a value field is available, so you can get/set the form field value. -This property expects always an string, no matter what kind of field it is.

-

Take into account also that “value” has precedence over “defValue”, -so if you use both, the used one will be “value”. This is valid for -all form fields.

-
-
-defValue[source]¶
-

Returns the default value for this field

-
- -
-
-guiDescription()[source]¶
-

Returns the dictionary with the description of this item. -We copy it, cause we need to translate the label and tooltip fields -and don’t want to -alter original values.

-
- -
-
-isType(type_)[source]¶
-

Returns true if this field is of specified type

-
- -
-
-setDefValue(defValue)[source]¶
-

Sets the default value of the field·

-
-
Args:
-
defValue: Default value (string)
-
-
- -
-
-value[source]¶
-

Obtains the stored value

-
- -
- -
-
-class gui.MultiChoiceField(**options)[source]¶
-

Multichoices are list of items that are multi-selectable.

-
-
There is a new parameter here, not covered by InputField:
-
    -
  • ‘rows’ to tell gui how many rows to display (the length of the -displayable list)
  • -
-
-
-

“defvalue” is expresed as a comma separated list of ids

-

This class do not have callback support, as ChoiceField does.

-

The values is an array of dictionaries, in the form [ { ‘id’ : ‘a’, -‘text’: b }, ... ]

-

Example usage:

-
-
# Declares a multiple choices field, with label "Datastores", that
-is editable, with 5 rows for displaying
-# data at most in user interface, 8th in order, that is required
-and has tooltip "Datastores where to put incrementals",
-# this field is required and has 2 selectable items: "datastore0"
-with id "0" and "datastore1" with id "1"
-datastores =  gui.MultiChoiceField(label = _("Datastores"),
-    rdonly = False, rows = 5, order = 8,
-    tooltip = _('Datastores where to put incrementals'),
-    required = True,
-    values = [ {'id': '0', 'text': 'datastore0' },
-        {'id': '1', 'text': 'datastore1' } ]
-    )
-
-
-
-
-
-setValues(values)[source]¶
-

Set the values for this multi choice field

-
- -
- -
-
-class gui.NumericField(**options)[source]¶
-

This represents a numeric field. It apears with an spin up/down button.

-

The values of parameres are inherited from InputField

-

Additionally to standard parameters, the length parameter indicates the -max number of digits (0-9 values).

-

Example usage:

-
-
# Declares an numeric form field, with max value of 99999, label
-# "Port", that is required,
-# with tooltip "Port (usually 443)" and order 1
-num = gui.NumericField(length=5, label = _('Port'),
-    defvalue = '443', order = 1, tooltip = _('Port (usually 443)'),
-    required = True)
-
-
-
-
-
-num()[source]¶
-

Return value as integer

-
- -
- -
-
-class gui.PasswordField(**options)[source]¶
-

This represents a password field. It appears with “*” at input, so the contents is not displayed

-

The values of parameres are inherited from InputField

-

Additionally to standard parameters, the length parameter is a recommended one for this kind of field.

-

Example usage:

-
-
# Declares an text form field, with label "Password",
-# tooltip "Password of the user", that is required,
-# with max length of 32 chars and order = 2, and is
-# editable after creation.
-passw = gui.PasswordField(lenth=32, label = _('Password'),
-    order = 4, tooltip = _('Password of the user'),
-    required = True)
-
-
-
-
- -
-
-class gui.TextField(**options)[source]¶
-

This represents a text field.

-

The values of parameters are inherited from InputField

-

Additionally to standard parameters, the length parameter is a -recommended one for this kind of field.

-

You can specify that this is a multiline text box with multiline -parameter. If it exists, and is greater than 1, indicates how much -lines will be used to display field. (Max number is 8)

-

Example usage:

-
-
# Declares an text form field, with label "Host", tooltip
-# "Host name for this module", that is required,
-# with max length of 64 chars and order = 1, and is editable
-# after creation.
-host = gui.TextField(length=64, label = _('Host'), order = 1,
-    tooltip = _('Host name for this module'), required = True)
-
-# Declares an text form field, with label "Other",
-# tooltip "Other info", that is not required, that is not
-# required and that is not editable after creation.
-other = gui.TextField(length=64, label = _('Other'), order = 1,
-    tooltip = _('Other info'), rdonly = True)
-
-
-
-
- -
- -
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/api/modules/ServiceModules.html b/server/documentation/_build/html/api/modules/ServiceModules.html deleted file mode 100644 index a5ea8796..00000000 --- a/server/documentation/_build/html/api/modules/ServiceModules.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - - - Service Modules — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Form Fields

-

Next topic

-

Provider interface

-

This Page

- - - -
-
- -
-
-
-
- -
-

Service Modules¶

-

Service modules are responsible for giving the user consumable ip services for -users.

-

They are composed of a package where it is provided, at least, the following -elements:

-
-
    -
  • One icon for administration interface representation. Icon is png file of -16x16.
  • -
  • A Full tree of classes, derived from interfaces (descrived below)
  • -
  • Registration of the class inside UDS at package’s __init__.
  • -
-
-

All packages included inside uds.services will automatically be imported, but -the service providers (root of service trees) needs to register as valid -providers, and the best place to do that is at the authenticator’s package __init__.

-

the Full tree of classes needed by the service modules are:

-
-
    -
  • Provider: This is the root tree of any service. It represents an agrupation -of services under the same root. As sample, a service provider can be an -Open nebula server, an VC, or whataver is a common root for a number of services.
  • -
  • Service: This is the representation of what a service will give to an user. -As such, this is not what the user will consume, but this is more the definition -of what the user will consume. Before assigning a service to an user, the admin -will need to declare a “Deployed Service”, that is a definition, using this service -an a number of other modules, of what the user will consume. Inside this service -we need to provide the information needed for deploying an user consumable item, -such as if it needs to be “prepared”, if it supports cache, if it must be assigned -to an user “manually”, and all the custom data that the user deployments and publications -will need.
  • -
  • Publication. Some services, before being assigned to users, needs some kind of -preparation. This process of preparation is called here “publication”. The service -itself will declare if it needs a publication and, if needed, who is responsible of -that. Services with needed publication will use this kind of class to provide -such preparation.
  • -
  • User Deployment. This is what will provide the final user consumable service. -The user deployment is the last responsible for, using the provided service -and provided publication (if needed), to create the elements that the user will -consume.
  • -
-
-

The best way to understand what you need to create your own services, -is to look at modules samples

- -
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/api/modules/auths/Authenticator.html b/server/documentation/_build/html/api/modules/auths/Authenticator.html deleted file mode 100644 index b9eae349..00000000 --- a/server/documentation/_build/html/api/modules/auths/Authenticator.html +++ /dev/null @@ -1,761 +0,0 @@ - - - - - - - - Authenticator Interface — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Authenticator Modules

-

Next topic

-

UDS Modules Samples

-

This Page

- - - -
-
- -
-
-
-
- -
-

Authenticator Interface¶

-

The authenticator class is in fact an interface. UDS authenticators must derive -from this, and must provide the logic so UDS can manage the users and groups that -an authenticator provides.

-
-
    -
-
-
-
-class uds.core.auths.Authenticator(dbAuth, environment, values)¶
-

This class represents the base interface to implement authenticators.

-

An authenticator is responsible for managing user and groups of a kind -inside UDS. As so, it must provide a number of method and mechanics to -allow UDS to manage users and groups using that kind of authenticator.

-

Some samples of authenticators are LDAP, Internal Database, SAML, CAS, ...

-

As always, if you override __init__, do not forget to invoke base __init__ as this:

-
super(self.__class__, self).__init__(self, dbAuth, environment, values)
-
-
-

This is a MUST, so internal structured gets filled correctly, so don’t forget it!.

-

The preferred method of doing initialization is to provide the initialize(), -and do not override __init__ method. This (initialize) will be invoked after -all internal initialization.

-

There are basically two kind of authenticators, that are “Externals” and -“Internals”.

-

Internal authenticators are those where and administrator has created manually -the user at admin interface. The users are not created from an external source, -so if an user do not exist at UDS database, it will not be valid. -In other words, if you have an authenticator where you must create users, -you can modify them, you must assign passwords manually, and group membership -also must be assigned manually, the authenticator is not an externalSource.

-

As you can notice, almost avery authenticator except internal db will be -external source, so, by default, attribute that indicates that is an external -source is set to True.

-

In fact, internal source authenticator is intended to allow UDS to identify -if the users come from internal DB (just the case of local authenticator), -or the users come from other sources. Also, this allos UDS to know when to -“update” group membership information for an user whenever it logs in.

-

External authenticator are in fact all authenticators except local database, -so we have defined isExternalSource as True by default, that will be most -cases.

- --- - - - -
Note:All attributes that are “_” here means that they will be -translated when provided to administration interface, so remember -to mark them in your own authenticators as “_” using -ugettext_noop. We have aliased it here to “_” so it’s -easier to understand.
-
-
-class Group(dbGroup)¶
-

A group is simply a database group associated with its authenticator instance

-

It’s only constructor expect a database group as parameter.

-
-
-dbGroup()¶
-

Returns the database group associated with this

-
- -
-
-manager()¶
-

Returns the database authenticator associated with this group

-
- -
- -
-
-class Authenticator.User(dbUser)¶
-

An user represents a database user, associated with its authenticator (instance) -and its groups.

-
-
-dbUser()¶
-

Returns the database user

-
- -
-
-groups()¶
-

Returns the valid groups for this user. -To do this, it will validate groups throuht authenticator instance using -uds.core.auths.Authenticator.getGroups() method.

- --- - - - -
Note:Once obtained valid groups, it caches them until object removal.
-
- -
-
-manager()¶
-

Returns the authenticator instance

-
- -
- -
-
-Authenticator.authCallback(parameters, gm)¶
-

There is a view inside UDS, an url, that will redirect the petition -to this callback.

-

If someone gets authenticated via this callback, the method will return -an “username” must be return. This username will be used to:

-
-
    -
  • Add user to UDS
  • -
  • Get user groups.
  • -
-
-

So, if this callback is called, also get the membership to groups of the user, and keep them. -This method will have to keep track of those until UDS request that groups -using getGroups. (This is easy, using storage() provided with the environment (env())

-

If this returns None, or empty, the authentication will be considered “invalid” -and an error will be shown.

-
-
Args:
-
parameters: all GET and POST received parameters -gm: Groups manager, you MUST check group membership using this gm
-
Return:
-
An username if validation check is successfull, None if not
-
-

You can also return an exception here and, if you don’t wont to check the user login, -you can raise :py:class:uds.core.auths.Exceptions.Redirect to redirect user to somewhere. -In this case, no user checking will be done. This is usefull to use this url to provide -other functionality appart of login, (such as logout)

- --- - - - -
Note:Keeping user information about group membership inside storage is highly recommended. -There will be calls to getGroups one an again, and also to getRealName, not just -at login, but at future (from admin interface, at user editing for example)
-
- -
-
-Authenticator.authenticate(username, credentials, groupsManager)¶
-

This method must be overriden, and is responsible for authenticating -users.

-

We can have to different situations here:

-
-
    -
  • The authenticator is external source, what means that users may -be unknown to system before callig this
  • -
  • The authenticator isn’t external source, what means that users have -been manually added to system and are known before this call. -This will only happen at Internal DB Authenticator.
  • -
-
-

We receive the username, the credentials used (normally password, but can -be a public key or something related to pk) and a group manager.

-

The group manager is responsible for letting know the authenticator which -groups we currently has active.

-
-
Args:
-
username: User name to authenticate -credentilas: Credentials for this user, (password, pki, or whatever needs to be used). (string) -groupManager: Group manager to modify with groups to which this users belongs to.
-
Returns:
-
True if authentication success, False if don’t.
-
-

See uds.core.auths.GroupsManager

- --- - - - -
Note:

This method must check not only that the user has valid credentials, but also -check the valid groups from groupsManager. -If this method returns false, of method getValidGroups of the groupsManager -passed into this method has no elements, the user will be considered invalid. -So remember to check validity of groups this user belongs to (inside the authenticator, -not inside UDS) using groupsManager.validate(group to which this users belongs to).

-

This is done in this way, because UDS has only a subset of groups for this user, and -we let the authenticator decide inside wich groups of UDS this users is included.

-
-
- -
-
-Authenticator.callbackUrl()¶
-

Helper method to return callback url for self (authenticator).

-

This method will allow us to know where to do redirection in case -we need to use callback for authentication

-
- -
-
-classmethod Authenticator.canCheckUserPassword()¶
-

Helper method to query if a class can do a login using credentials

-
- -
-
-Authenticator.createGroup(groupData)¶
-

This method is used when creating a new group to allow the authenticator:

-
-
    -
  • Check that the name inside groupData is fine
  • -
  • Fill other (not name, if you don’t know what are you doing) usrData dictionary values.
  • -
-
-

This will be invoked from admin interface, when admin wants to create a new group.

-

modified groupData will be used to store values at database.

-
-
Args:
-
-
groupData: Contains data received from user directly, that is a dictionary
-
with at least: name, comments and state. (State.ACTIVE, State.INACTIVE) -This is an in/out parameter, so you can modify, for example, -comments
-
-
-
Returns:
-

Raises an exception if things didn’t went fine, -return value is ignored, but modified groupData is used if this does not -raises an exception.

-

Take care with whatever you modify here, you can even modify provided -name (group name) to a new one!

-
-
-
- -
-
-Authenticator.createUser(usrData)¶
-

This method is used when creating an user to allow the authenticator:

-
-
    -
  • Check that the name inside usrData is fine
  • -
  • Fill other (not name, if you don’t know what are you doing) usrData dictionary values.
  • -
-
-

This will be invoked from admin interface, when admin wants to create a new user

-

modified usrData will be used to store values at database.

-
-
Args:
-
-
usrData: Contains data received from user directly, that is a dictionary
-
with at least: name, real_name, comments, state & password. -This is an in/out parameter, so you can modify, for example, -realName
-
-
-
Returns:
-

Raises an exception if things didn’t went fine, -return value is ignored, but modified usrData is used if this does not -raises an exception.

-

Take care with whatever you modify here, you can even modify provided -name (login name!) to a new one!

-
-
- --- - - - -
Note:If you have an SSO where you can’t create an user from admin interface, -raise an exception here indicating that the creation can’t be done. -Default implementation simply raises “AuthenticatorException” and -says that user can’t be created manually
-
- -
-
-Authenticator.dbAuthenticator()¶
-

Helper method to access the Authenticator database object

-
- -
-
-Authenticator.getForAuth(username)¶
-

Process the username for this authenticator and returns it. -This transformation is used for transports only, not for transforming -anything at login time. Transports that will need the username, will invoke -this method. -For example, an authenticator can add '@domain‘ so transport use the complete -'user@domain‘ instead of ‘user’.

-

Right now, all authenticators keep this value “as is”, i mean, it simply -returns the unprocessed username

-
- -
-
-Authenticator.getGroups(username, groupsManager)¶
-

Looks for the real groups to which the specified user belongs.

-

You MUST override this method, UDS will call it whenever it needs to refresh an user group membership.

-

The expected behavior of this method is to mark valid groups in the uds.core.auths.GroupsManager provided, normally -calling its uds.core.auths.GroupsManager.validate() method with groups names provided by the authenticator itself -(for example, LDAP, AD, ...)

-
- -
-
-Authenticator.getHtml(request)¶
-

If you override this method, and returns something different of None, -UDS will consider your authenticator as “Owner draw”, that is, that it -will not use the standard form for user authentication.

-
-
Args:
-
Request is the DJango request received for generating this html, -with included user ip at request.ip.
-
-

We have here a few things that we should know for creating our own -html for authenticator:

-
-
    -
  • We use jQuery, so your javascript can use it
  • -
  • The id of the username input field is id_user
  • -
  • The id of the password input field is id_password
  • -
  • The id of the login form is loginform
  • -
  • The id of the “back to login” link is backToLogin
  • -
-
-

This is what happens when an authenticator that has getHtml method is -selected in the front end (from the combo shown):

-
-
    -
  • The div with id login is hidden.
  • -
  • The div with id nonStandard is shown
  • -
  • Using Ajax, the html provided by this method is requested for -the authenticator
  • -
  • The returned html is rendered inside nonStandardLogin div.
  • -
  • The nonStandard div is shown.
  • -
-
-

nonStandard div has two inner divs, nonStandardLogin and -divBackToLogin. If there is no standard auths, divBackToLogin is -erased.

-

With this, and :py:meth:.authCallback method, we can add SSO engines -to UDS with no much problems.

-
- -
-
-Authenticator.getInfo(parameters)¶
-

This method is invoked whenever the authinfo url is invoked, with the name of the authenticator -If this is implemented, information returned by this will be shown via web.

- --- - - - -
Note:You can return here a single element or a list (or tuple), where first element will be content itself, -and second will be the content type (i.e. “text/plain”).
-
- -
-
-Authenticator.getRealName(username)¶
-

Tries to get the real name of an user

-

Default implementation returns just the same user name that is passed in.

-
- -
-
-Authenticator.groupType¶
-

alias of Group

-
- -
-
-Authenticator.infoUrl()¶
-

Helper method to return info url for this authenticator

-
- -
-
-Authenticator.initialize(values)¶
-

This method will be invoked from __init__ constructor. -This is provided so you don’t have to provide your own __init__ method, -and invoke base methods. -This will get invoked when all initialization stuff is done

-
-
Args:
-
Values: If values is not none, this object is being initialized -from administration interface, and not unmarshal will be done. -If it’s None, this is initialized internally, and unmarshal will -be called after this.
-
-

Default implementation does nothing

-
- -
-
-Authenticator.internalAuthenticate(username, credentials, groupsManager)¶
-

This method is provided so “plugins” (For example, a custom dispatcher), can test -the username/credentials in an alternative way.

-

For example, ip authenticator generates, inside the custom html, a 1 time password -that will be used to authenticate the ip. If we create a custom dispatcher and we want -to auth the user without the html part being displayed, we have a big problem.

-

Using this method, the authenticator has the oportunitiy to, (for example, in case of -IP auth), ignore “credentials”

-
-
Args:
-
username: User name to authenticate -credentilas: Credentials for this user, (password, pki, or whatever needs to be used). (string) -groupManager: Group manager to modify with groups to which this users belongs to.
-
Returns:
-
True if authentication success, False if don’t. -By default, internalAuthenticate simply invokes authenticate, but this method -is here so you can provide your own method if needed
-
-

See uds.core.auths.GroupsManager

- --- - - - -
Note:

This method must check not only that the user has valid credentials, but also -check the valid groups from groupsManager. -If this method returns false, of method getValidGroups of the groupsManager -passed into this method has no elements, the user will be considered invalid. -So remember to check validity of groups this user belongs to (inside the authenticator, -not inside UDS) using groupsManager.validate(group to which this users belongs to).

-

This is done in this way, because UDS has only a subset of groups for this user, and -we let the authenticator decide inside wich groups of UDS this users is included.

-
-
- -
-
-classmethod Authenticator.isCustom()¶
-

Helper to query if a class is custom (implements getHtml method)

-
- -
-
-Authenticator.logout(username)¶
-

Invoked whenever an user logs out.

-

Notice that authenticators that provides getHtml method are considered “custom”, and -these authenticators will never be used to allow an user to access administration interface -(they will be filtered out)

-

By default, this method does nothing.

-

Args:

-
-
username: Name of the user that logged out
-

Returns:

-
-
None if nothing has to be done by UDS. An URL (absolute or relative), if it has to redirect -the user to somewhere.
- --- - - - -
Note:This method will be invoked also for administration log out (it it’s done), but return -result will be passed to administration interface, that will invoke the URL but nothing -will be shown to the user. -Also, notice that this method will only be invoked “implicity”, this means that will be -invoked if user requests “log out”, but maybe it will never be invoked.
-
- -
-
-Authenticator.modifyGroup(groupData)¶
-

This method is used when modifying group to allow the authenticator:

-
-
    -
  • Check that the name inside groupData is fine
  • -
  • Fill other (not name, if you don’t know what are you doing) usrData dictionary values.
  • -
-
-

This will be invoked from admin interface, when admin wants to create a new group.

-

modified groupData will be used to store values at database.

-
-
Args:
-
-
groupData: Contains data received from user directly, that is a dictionary
-
with at least: name, comments and state. (State.ACTIVE, State.INACTIVE) -This is an in/out parameter, so you can modify, for example, -comments
-
-
-
Returns:
-
Raises an exception if things didn’t went fine, -return value is ignored, but modified groupData is used if this does not -raises an exception.
-
-

Note: ‘name’ output parameter will be ignored

-
- -
-
-Authenticator.modifyUser(usrData)¶
-

This method is used when modifying an user to allow the authenticator:

-
-
    -
  • Check that the name inside usrData is fine
  • -
  • Fill other (not name, if you don’t know what are you doing) usrData dictionary values.
  • -
-
-
-
Args:
-
-
usrData: Contains data received from user directly, that is a dictionary
-
with at least: name, real_name, comments, state & password. -This is an in/out parameter, so you can modify, for example, -realName
-
-
-
Returns:
-

Raises an exception if things didn’t went fine, -return value is ignored, but modified usrData is used if this does not -raises an exception.

-

Take care with whatever you modify here, you can even modify provided -name (login name!) to a new one!

-
-
- --- - - - -
Note:By default, this will do nothing, as we can only modify “accesory” internal -data of users.
-
- -
-
-Authenticator.recreateGroups(user)¶
-

Helper method, not needed to be overriden. -It simply checks if the source is external and if so, recreates -the user groups for storing them at database.

-

user param is a database user object

-
- -
-
-Authenticator.removeGroup(groupname)¶
-

Remove user is used whenever from the administration interface, or from other -internal workers, an group needs to be removed.

-

This is a notification method, whenever an group gets removed from UDS, this -will get called.

-

You can do here whatever you want, but you are not requested to do anything -at your authenticators.

-

If this method raises an exception, the group will not be removed from UDS

-
- -
-
-Authenticator.removeUser(username)¶
-

Remove user is used whenever from the administration interface, or from other -internal workers, an user needs to be removed.

-

This is a notification method, whenever an user gets removed from UDS, this -will get called.

-

You can do here whatever you want, but you are not requested to do anything -at your authenticators.

-

If this method raises an exception, the user will not be removed from UDS

-
- -
-
-Authenticator.searchGroups(pattern)¶
-

Returns an array of groups that match the supplied pattern -If none found, returns empty array. Items returned are BaseGroups (or derived) -If you override this method, the admin interface will allow the use of -“search” at group form. If not overriden, the search will not be allowed.

-

Must return array of dictionaries that must contains ‘id’ and ‘name’ -example: [ {‘id’: ‘user1’, ‘name’: ‘Nombre 1’} ]

-

Default implementation returns empty array, but is never used because if -not overriden, search of groups will not be allowed.

-
- -
-
-Authenticator.searchUsers(pattern)¶
-

If you provide this method, the user will be allowed to search users, -that is, the search button at administration interface, at user form, -will be enabled.

-

Returns an array of users that match the supplied pattern -If none found, returns empty array.

-

Must return is an array of dictionaries that must contains ‘id’ and ‘name’ -example: [ {‘id’: ‘user1’, ‘name’: ‘Nombre 1’} ]

-
-
Args:
-
pattern: Pattern to search for (simple pattern, string)
-
Returns
-
a list of found users for the pattern specified
-
-
- -
-
-Authenticator.transformUsername(username)¶
-

On login, this method get called so we can “transform” provided user name.

-
-
Args:
-
username: Username to transform
-
Returns
-
Transformed user name
-
- --- - - - -
Note:You don’t need to implement this method if your authenticator (as most authenticators does), does not -transforms username.
-
- -
-
-Authenticator.userType¶
-

alias of User

-
- -
- -
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/api/modules/services/Exceptions.html b/server/documentation/_build/html/api/modules/services/Exceptions.html deleted file mode 100644 index 4a2f77d2..00000000 --- a/server/documentation/_build/html/api/modules/services/Exceptions.html +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - - - Service Exceptions — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

UserDeployment interface

-

Next topic

-

Authenticator Modules

-

This Page

- - - -
-
- -
-
-
-
- -
-

Service Exceptions¶

-
-
    -
-
-
-
-exception uds.core.services.Exceptions.CancelException[source]¶
-

Reflects that a “cancel” operation can’t be done for some reason

-
- -
-
-exception uds.core.services.Exceptions.DeploymentException[source]¶
-

Reflects that a deployment of a service (at cache, or assigned to user) can’t be done for causes we don’t know in advance

-
- -
-
-exception uds.core.services.Exceptions.InvalidServiceException[source]¶
-

Invalid service specified. The service is not ready

-
- -
-
-exception uds.core.services.Exceptions.MaxServicesReachedException[source]¶
-

Number of maximum services has been reached, and no more services -can be created for users.

-
- -
-
-exception uds.core.services.Exceptions.OperationException[source]¶
-

Reflects that the operation requested can’t be acomplished, i.e. remove an snapshot without snapshot reference, cancel non running operation, etc...

-
- -
-
-exception uds.core.services.Exceptions.PublishException[source]¶
-

Reflects thate the publication can’t be done for causes we don’t know in advance

-
- -
-
-exception uds.core.services.Exceptions.UnsupportedException[source]¶
-

Reflects that we request an operation that is not supported, i.e. Cancel a publication with snapshots

-
- -
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/api/modules/services/Provider.html b/server/documentation/_build/html/api/modules/services/Provider.html deleted file mode 100644 index 8e35c47b..00000000 --- a/server/documentation/_build/html/api/modules/services/Provider.html +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - - Provider interface — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Service Modules

-

Next topic

-

Service interface

-

This Page

- - - -
-
- -
-
-
-
- -
-

Provider interface¶

-

The provider class is the root class of the module. It keeps the common information -needed by all services provided by this “provider”.

-

Think about a provider as the class that will declare all stuff neded by core and -child services to provide and administrator user a way to create services to be -consumed by users.

-

One good example is a Virtualization server. Here we keep information about that -server (ip address, protocol, ....) and services provided by that “provider” will -make use of that information to make the administrator not provide it once an again -for every service we put on that virtualization server.

-
-
    -
-
-

For a detailed example of a service provider, you can see the provided -provider sample

-
-
-class uds.core.services.ServiceProvider(environment, values=None)¶
-

Base Service Provider Class.

-

All classes that will represent a service provider will need to be derived -from this class.

-

The preferred way of using this class is by its alias name, provided -at uds.core.services module, ServiceProvider.

-

This is a very basic class, intended to be the root class of services. -This means that services are childs of this class, declared at “offers” attribute.

-

As you derive from this class, if you provide __init__ in your own class, -remember to call ALWAYS at base class __init__ as this:

-
-
super(...., self).__init__(environment, values)
-

The preferred method of provide initialization is to provide the initialize(), -and do not overrie __init__ method. This (initialize) will be invoked after -all internal initialization.

-

This is a MUST, so internal structured gets filled correctly, so don’t forget it!.

-

Normally objects of classes deriving from this one, will be serialized, called, -deserialized. This means that all that you want to ensure that is keeped inside -the class must be serialized and unserialized, because there is no warantee that -the object will get two methods invoked without haven’t been removed from memory -and loaded again. One thing to have into account on this are Form Fields, that -default implementation marshals and unmashals them, so if your case is that you -only need data that is keeped at form fields, marshal and unmarshal and in fact -not needed.

-
-
-classmethod getServiceByType(typeName)¶
-

Tries to locate a child service which type corresponds with the -one provided. -Returns None if can’t find one.

- --- - - - -
Note:The type that this method looks for is not the class, but -the typeType that Service has.
-
- -
-
-classmethod getServicesTypes()¶
-

Returns what type of services this provider offers

-
- -
-
-initialize(values)¶
-

This method will be invoked from __init__ constructor. -This is provided so you don’t have to provide your own __init__ method, -and invoke base methods. -This will get invoked when all initialization stuff is done

-
-
Args:
-
Values: If values is not none, this object is being initialized -from administration interface, and not unmarshal will be done. -If it’s None, this is initialized internally, and unmarshal will -be called after this.
-
-

Default implementation does nothing

-
- -
- -
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/api/modules/services/Publication.html b/server/documentation/_build/html/api/modules/services/Publication.html deleted file mode 100644 index 84f0fb3e..00000000 --- a/server/documentation/_build/html/api/modules/services/Publication.html +++ /dev/null @@ -1,348 +0,0 @@ - - - - - - - - Publication interface — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Service interface

-

Next topic

-

UserDeployment interface

-

This Page

- - - -
-
- -
-
-
-
- -
-

Publication interface¶

-

The publication class is in fact an interface. It represents, in those case that -a service needs the preparation, the logic for that preparation.

-

So the publication class is responsible of doing whatever is needed to get the -deployed service (that is the compound of a service, an os manager, transports -and authenticators) ready for deploying user consumables.

-

Note that not all services needs to implement this class, only in those case -where that service declares that a publication is needed.

-

As functional sample of a publication, imagine that we want to assing KVM COW -machines to users. The publication class can make a clone of the base machine -(that the service itself has taken note of which one is), and then the COWs will -be created from this cloned machine.

-
-
    -
-
-

For a detailed example of a service provider, you can see the provided -publication sample

-
-
-class uds.core.services.Publication(environment, **kwargs)¶
-

This class is in fact an interface, and defines the logic of a publication -for a Service.

-

A publication is the preparation of the needs of a service before it can -be provided to users. One good sample of this is, in case of virtual machines, -to copy a machine to provide COWS of this copy to users.

-

As always, do not forget to invoke base class __init__ if you override it as this:

-
super(self.__class__, self).__init__(environment, **kwargs)
-
-
-

This is a MUST, so internal structured gets filled correctly, so don’t forget it!.

-

The preferred method is not to override init, but provide the initialize(), -that will be invoked just after all internal initialization is completed.

-

Normally objects of classes deriving from this one, will be serialized, called, -deserialized. This means that all that you want to ensure that is keeped inside -the class must be serialized and unserialized, because there is no warantee that -the object will get two methods invoked without haven’t been remoded from memory -and loaded again, this means, IMPLEMENT marshal and unmarshal with all attributes -that you want to keep.

-
-
-cancel()¶
-

This is a task method. As that, the expected return values are -State values RUNNING, FINISHED or ERROR.

-

This method is invoked whenever the core needs a cancelation of current -operation. This will happen if we are, for example, preparing the -service for users, but the administration request to stop doing this.

-

This method MUST be provided, even if you do nothing here (in that case, -simply return State.FINISHED). Default implementation will raise an -exception if it gets called

- --- - - - -
Note:All task methods, like this one, are expected to handle -all exceptions, and never raise an exception from these methods -to the core. Take that into account and handle exceptions inside -this method.
-
- -
-
-checkState()¶
-

This is a task method. As that, the expected return values are -State values RUNNING, FINISHED or ERROR.

-

This method will be invoked whenever a publication is started, but it -do not finish in 1 step.

-

The idea behind this is simple, we can initiate an operation of publishing, -that will be done at :py:meth:.publish method.

-

If this method returns that the operation has been initiated, but not finished -(State.RUNNING), the core will keep calling this method until checkState -returns State.FINISHED (or State.error).

-

You MUST always provide this method if you expect the publication no to be -done in 1 step (meaning this that if publish can return State.RUNNING, this -will get called)

- --- - - - -
Note:All task methods, like this one, are expected to handle -all exceptions, and never raise an exception from these methods -to the core. Take that into account and handle exceptions inside -this method.
-
- -
-
-destroy()¶
-

This is a task method. As that, the expected return values are -State values RUNNING, FINISHED or ERROR.

-

Invoked for destroying a deployed service -Do whatever needed here, as deleting associated data if needed -(i.e. a copy of the machine, snapshots, etc...)

-

This method MUST be provided, even if you do nothing here (in that case, -simply return State.FINISHED). Default implementation will raise an -exception if it gets called

- --- - - - -
Note:All task methods, like this one, are expected to handle -all exceptions, and never raise an exception from these methods -to the core. Take that into account and handle exceptions inside -this method.
-
- -
-
-dsName()¶
-

Utility method to access the declared deployed service name.

-

This name is set by core, using the administrator provided data -at administration interface.

-
- -
-
-finish()¶
-

Invoked when Publication manager noticed that the publication has finished. -This give us the opportunity of cleaning up things (as stored vars, etc..) -Returned value, if any, is ignored

-

Default implementation does nothing. You can leave default method if you -are going to do nothing.

-
- -
-
-initialize()¶
-

This method will be invoked from __init__ constructor. -This is provided so you don’t have to provide your own __init__ method, -and invoke base class __init__. -This will get invoked when all initialization stuff is done, so -you can here access service, osManager, ...

-
- -
-
-osManager()¶
-

Utility method to access os manager for this publication.

-

Returns

-
-
Parent service instance object (not database object) -The returned value can be None if no Os manager is needed by -the service owner of this publication.
-
- -
-
-publish()¶
-

This method is invoked whenever the administrator requests a new publication.

-

The method is not invoked directly (i mean, that the administration request -do no makes a call to this method), but a DelayedTask is saved witch will -initiate all publication stuff (and, of course, call this method).

-

You MUST implement it, so the publication do really something. -All publications can be synchronous or asynchronous.

-

The main difference between both is that first do whatever needed, (the -action must be fast enough to do not block core), returning State.FINISHED.

-

The second (asynchronous) are publications that could block the core, so -it have to be done in more than one step.

-
-
An example publication could be a copy of a virtual machine, where:
-
    -
  • First we invoke the copy operation to virtualization provider
  • -
  • Second, we kept needed values inside instance so we can serialize -them whenever requested
  • -
  • Returns an State.RUNNING, indicating the core that the publication -has started but has to finish sometime later. (We do no check -again the state and keep waiting here, because we will block the -core untill this operation is finished).
  • -
-
-
- --- - - - - - -
Note:This method MUST be provided, an exception is raised if not.
Note:All task methods, like this one, are expected to handle -all exceptions, and never raise an exception from these methods -to the core. Take that into account and handle exceptions inside -this method.
-
- -
-
-reasonOfError()¶
-

If a publication produces an error, here we must return the reason why -it happened. This will be called just after publish or checkPublishingState -if they return State.ERROR

-

The returned value, an string, will be used always by administration interface, -meaning this that the translation environment will be ready, and that you -can use ugettext to return a version that can be translated to administration -interface language.

-
- -
-
-revision()¶
-

Utility method to access the revision of this publication -This is a numeric value, and is set by core

-
- -
-
-service()¶
-

Utility method to access parent service of this publication

-

Returns

-
-
Parent service instance object (not database object)
-
- -
- -
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/api/modules/services/Service.html b/server/documentation/_build/html/api/modules/services/Service.html deleted file mode 100644 index 4f289b7c..00000000 --- a/server/documentation/_build/html/api/modules/services/Service.html +++ /dev/null @@ -1,219 +0,0 @@ - - - - - - - - Service interface — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Provider interface

-

Next topic

-

Publication interface

-

This Page

- - - -
-
- -
-
-
-
- -
-

Service interface¶

-

The service class is in fact an interface. It represents the base for all user -deployments (that is, consumable user services) that will be provided.

-

As such, the service is responsible for keeping the information that, at deployments, -will be neded by provided user consumable services.

-

A good sample of a service can be a KVM machine that will be copied COW and that COWs -will be assigned to users. In that case, we will collect which machine will be copied, -where it is to be copied, an a few more params that the user deployments will need.

-
-
    -
-
-

For a detailed example of a service provider, you can see the provided -service sample

-
-
-class uds.core.services.Service(environment, parent, values=None)¶
-

This class is in fact an interface, and represents a service, that is the -definition of an offering for consumers (users).

-

Class derived from this one declares the behavior of the service, as well -as custom parameter that will be needed to provide final consumable elements -to users.

-

The behavior attributes must be declared always, although they have default -values, this can change in a future and declaring all needed is a good way -to avoid future problems. Of course, if you declare that do no do something -(i.e. do not uses cache), you will not have to declare related attributes -(i.e. cacheTooltip, usesCache_L2 and cacheTooltip_L2)

-

As you derive from this class, if you provide __init__ in your own class, -remember to call ALWAYS at base class __init__ as this:

-
-
super(self.__class__, self).__init__(dbAuth, environment, values)
-

This is a MUST (if you override __init__), so internal structured gets -filled correctly, so don’t forget it!.

-

The preferred method of provide initialization is to provide the initialize(), -and do not override __init__ method. This (initialize) will be invoked after -all internal initialization, so there will be available parent, environment and storage.

-

Normally objects of classes deriving from this one, will be serialized, called, -deserialized. This means that all that you want to ensure that is kept inside -the class must be serialized and unserialized, because there is no warrantee that -the object will get two methods invoked without haven’t been removed from memory -and loaded again. One thing to have into account on this are Form Fields, that -default implementation marshals and unmashals them, so if your case is that you -only need data that is keeped at form fields, marshal and unmarshal and in fact -not needed.

-
-
-initialize(values)¶
-

This method will be invoked from __init__ constructor. -This is provided so you don’t have to provide your own __init__ method, -and invoke base methods. -This will get invoked when all initialization stuff is done

-
-
Args:
-
Values: If values is not none, this object is being initialized -from administration interface, and not unmarshal will be done. -If it’s None, this is initialized internally, and unmarshal will -be called after this.
-
-

Default implementation does nothing

-
- -
-
-macGenerator()¶
-

Utility method to access provided macs generator (inside environment)

-

Returns the environment unique mac addresses generator

-
- -
-
-nameGenerator()¶
-

Utility method to access provided names generator (inside environment)

-

Returns the environment unique name generator

-
- -
-
-parent()¶
-

Utility method to access parent provider for this service

-

Returns

-
-
Parent provider instance object (not database object)
-
- -
-
-requestServicesForAssignation(**kwargs)¶
-

override this if mustAssignManualy is True -@params kwargs: Named arguments -@return an array with the services that we can assign (they must be of type deployedType) -We will access the returned array in “name” basis. This means that the service will be assigned by “name”, so be care that every single service -returned are not repeated... :-)

-
- -
- -
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/api/modules/services/UserDeployment.html b/server/documentation/_build/html/api/modules/services/UserDeployment.html deleted file mode 100644 index 9f21213b..00000000 --- a/server/documentation/_build/html/api/modules/services/UserDeployment.html +++ /dev/null @@ -1,638 +0,0 @@ - - - - - - - - UserDeployment interface — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Publication interface

-

Next topic

-

Service Exceptions

-

This Page

- - - -
-
- -
-
-
-
- -
-

UserDeployment interface¶

-

The user deployment class is in fact an interface. It represents the final consumable -that will be assigned to an user, and, as such, it must provide some mechanisms to -allow core to manage those consumables.

-

A good sample of an user deployment can be a KVM Virtual Machine, cloned COW from -another, and assigned to an user.

-
-
    -
-
-

For detailed examples of a couple of user deployments, you can see the provided -service sample and -service sample

-
-
-class uds.core.services.UserDeployment(environment, **kwargs)¶
-

Interface for deployed services.

-

This class provides the needed logic for implementing an “consumable user service”, -that are the elements that the user will interact with.

-

A good way to understand this class is to look at the sample services provided -with the documentation.

-

As with all modules interfaces, if you override __init__ method, -do not forget to invoke this class __init__ method as this:

-
super(self.__class__, self).__init__(environment, **kwargs)
-
-
-

This is a MUST (if you override __init___), so internal structured gets filled correctly, so don’t forget it!.

-

The preferred way of initializing, is to provide initialize(), that -will be invoked just after all initialization stuff is done at __init__.

-

Normally objects of classes deriving from this one, will be serialized, called, -deserialized. This means that all that you want to ensure that is keeped inside -the class must be serialized and unserialized, because there is no warantee that -the object will get two methods invoked without haven’t been remoded from memory -and loaded again, this means, IMPLEMENT marshal and unmarshal with all attributes -that you want to keep.

-

Things to know about this class:

-
-
    -
  • Once a deployment is done, it will never be called again for same instance -object

    -
  • -
  • The method getUniqueId will be invoked after call to deploys and check. -You can change it on the fly, but remember that uniqueId is the “keyword” -used inside services to communicate with os managers (os manager will -receive an instance of UserDeployment, and this will be located via that -uniqueId)

    -

    Uniques ids can be repeated at database level, to let it come at a later -deployment stage, but if two services has same uniqueid at a time, -os manager will simply not work.

    -
  • -
  • suggestedTime is always accessed through instance objects, and used after -deployForCache, deployForUser and moveToCache it these methods returns -RUNNING

    -
  • -
  • Checks (if a deployment has finished, or the cache movement is finished) -are always done using checkState(). It is secuential, i mean, will only -be called when a deployment,a cache movement or a cancel operation is -running

    -
  • -
  • If the service that supports this deployeds do not use L2 cache, the -moveCache method will never be invoked

    -
  • -
  • The L1 cache should be a fast access cache (i.e. running service but -not assigned to an user), while L2 cache should be non consuming or -almost-non-consuming service. This means that if we cannont make an -slower an less resources consumable form for a service, this should -not have an L2 cache (slower is not a must, -but probably it will be slower to recover from L2 cache than from L1, -but faster than creating a new service) -Ofc, if a service has an “Instant” creation, it don’t needs cache...

    -
  • -
  • We do not expect any exception from these methods, but if there is an -error, the method can return “ERROR”. To show the reason of error, the -method reasonOfError can be called multiple times, including -serializations in middle, so remember to include reason of error in serializations

    -
  • -
-
-
-
-assignToUser(user)¶
-

This method is invoked whenever a cache item gets assigned to an user. -This is not a task method right now, simply a notification. This means -that L1 cache items must be directly usable (except for the readyness part) -by users in a single step operation.

-

Note that there will be an setReady call before letting the user consume -this user deployment, so this is more informational (so, if you keep at -what cache level is this instance, you can update it) than anything else.

-

This is not a task method. All level 1 cache items can be dircetly -assigned to an user with no more work needed, but, if something is needed, -here you can do whatever you need.

-

user is a Database user object.

-
- -
-
-cancel()¶
-

This is a task method. As that, the excepted return values are -State values RUNNING, FINISHED or ERROR.

-

Cancel represents a canceling of the current running operation, and -can be invoked directly by an administration or by the clean up -of the deployed service (indirectly).

-

When administrator requests it, the cancel is “delayed” and not -invoked directly.

- --- - - - -
Note:All task methods, like this one, are expected to handle -all exceptions, and never raise an exception from these methods -to the core. Take that into account and handle exceptions inside -this method.
-
- -
-
-checkState()¶
-

This is a task method. As that, the expected return values are -State values RUNNING, FINISHED or ERROR.

-

If some of the initiating action tasks returns State.RUNNING. this method -will get called until it returns State.FINISH or State.ERROR.

-

In other words, whenever a multi step operation is initiated, this method -will get the responsability to check that the operation has finished or -failed. If the operation continues, but haven’t finished yet, it must -return State.RUNNING. If has finished must return State.FINISH and if it -has some kind of error, State.ERROR and also store somewhere the info -that will be requested using :py:meth:.reasonOfError

- --- - - - - - -
Note:override ALWAYS this method, or an exception will be raised
Note:All task methods, like this one, are expected to handle -all exceptions, and never raise an exception from these methods -to the core. Take that into account and handle exceptions inside -this method.
-
- -
-
-dbservice()¶
-

Utility method to access database object for the object this represents.

-

Returns:

-
-
Database object that got unserialized to obtain this object.
-
- -
-
-deployForCache(cacheLevel)¶
-

Deploys a user deployment as cache.

-

This is a task method. As that, the expected return values are -State values RUNNING, FINISHED or ERROR.

-

The objective of this method is providing a cache copy of an user consumable, -and will be invoked whenever the core need to create a new copy for cache -of the service this UserDeployment manages.

-

Things to take care with this method are:

-
-
    -
  • cacheLevel can be L1 or L2 (class constants)
  • -
  • If a deploy for cache is asked for a L1 cache, the generated -element is expected to be all-done for user consume. L1 cache items -will get directly assigned to users whenever needed, and are expected -to be fast. (You always have setReady method to do anything else needed -to assign the cache element to an user, but generally L1 cached items -must be ready to use.
  • -
  • An L2 cache is expected to be an cached element that is “almost ready”. -The main idea behind L2 is to keep some elements almost usable by users -but in an state that they do not consume (or consumes much less) resources. -If your L2 cache consumes the same that L1 cache, L2 cache is in fact not -needed.
  • -
  • This works as :py:meth:.deployForUser, meaning that you can take a look -also to that method for more info
  • -
-
- --- - - - - - -
Note:If your service uses caching, this method MUST be provided. If it -do not uses cache, this method will never get called, so you can -skip it implementation
Note:All task methods, like this one, are expected to handle -all exceptions, and never raise an exception from these methods -to the core. Take that into account and handle exceptions inside -this method.
-
- -
-
-deployForUser(user)¶
-

Deploys an service instance for an user.

-

This is a task method. As that, the excepted return values are -State values RUNNING, FINISHED or ERROR.

-

The user parameter is not realy neded, but provided. It indicates the -Database User Object (see py:mod:uds.modules) to which this deployed -user service will be assigned to.

-

This method will get called whenever a new deployed service for an user -is needed. This will give this class the oportunity to create -a service that is assigned to an user.

-

The way of using this method is as follows:

-

If the service gets created in “one step”, that is, before the return -of this method, the consumable service for the user gets created, it -will return “State.FINISH”. -If the service needs more steps (as in this case), we will return -“State.RUNNING”, and if it has an error, it wil return “State.ERROR” and -store an error string so administration interface can show it.

-

We do not use user for anything, as in most cases will be.

- --- - - - - - -
Note:override ALWAYS this method, or an exception will be raised
Note:All task methods, like this one, are expected to handle -all exceptions, and never raise an exception from these methods -to the core. Take that into account and handle exceptions inside -this method.
-
- -
-
-destroy()¶
-

This is a task method. As that, the excepted return values are -State values RUNNING, FINISHED or ERROR.

-

This method gives the oportunity to remove associated data (virtual machine, -...) for the user consumable this instance represents.

-

If return value is State.RUNNING, :py:meth:.checkState will be used to -check if the destroy operation has finished.

- --- - - - -
Note:All task methods, like this one, are expected to handle -all exceptions, and never raise an exception from these methods -to the core. Take that into account and handle exceptions inside -this method.
-
- -
-
-doLog(level, message)¶
-

Logs a message with requested level associated with this service

-
- -
-
-finish()¶
-

Invoked when the core notices that the deployment of a service has finished. -(No matter whether it is for cache or for an user)

-

This gives the opportunity to make something at that moment.

-

Default implementation does nothing at all.

- --- - - - -
Note:You can also make these operations at checkState, this is really -not needed, but can be provided (default implementation of base class does -nothing)
-
- -
-
-getIp()¶
-

All services are “IP” services, so this method is a MUST

-

Returns:

-
-
The needed ip to let the user connect to the his deployed service. -This ip will be managed by transports, without IP there is no connection
-
- -
-
-getName()¶
-

Override this to return a name to display under some circustances

-

Returns:

-
-
name, default implementation returns unique id
-
- -
-
-getUniqueId()¶
-

Obtains an unique id for this deployed service, you MUST override this

-

Returns:

-
-
An unique identifier for this object, that is an string and must be -unique.
-
- -
-
-initialize()¶
-

This method will be invoked from __init__ constructor. -This is provided so you don’t have to provide your own __init__ method, -and invoke base class __init__. -This will get invoked when all initialization stuff is done, so -you can here access publication, service, osManager, ...

-
- -
-
-macGenerator()¶
-

Utility method to access provided macs generator (inside environment)

-

Returns the environment unique mac addresses generator

-
- -
-
-moveToCache(newLevel)¶
-

This method is invoked whenever the core needs to move from the current -cache level to a new cache level an user deployment.

-

This is a task method. As that, the expected return values are -State values RUNNING, FINISHED or ERROR.

-

We only provide newLevel, because there is only two cache levels, so if -newLevel is L1, the actual is L2, and if it is L2, the actual is L1.

-

Actually there is no possibility to move assigned services again back to -cache. If some service needs that kind of functionallity, this must be -provided at service level (for example, when doing publishing creating -a number of services that will be used, released and reused by users).

-

Also, user deployments that are at cache level 2 will never get directly -assigned to user. First, it will pass to L1 and then it will get assigned.

-

A good sample of a real implementation of this is moving a virtual machine -from a “suspended” state to “running” state to assign it to an user.

- --- - - - -
Note:All task methods, like this one, are expected to handle -all exceptions, and never raise an exception from these methods -to the core. Take that into account and handle exceptions inside -this method.
-
- -
-
-nameGenerator()¶
-

Utility method to access provided names generator (inside environment)

-

Returns the environment unique name generator

-
- -
-
-notifyReadyFromOsManager(data)¶
-

This is a task method. As that, the excepted return values are -State values RUNNING, FINISHED or ERROR.

-

This method provides a mechanism to let os managers notify readyness -to deployed services.

-

Args:

-
-
Data: Data sent by os manager. -Data is os manager dependant, so check if this data is known by you -(normally, it will be None, but is os manager dependad as i say)
-

This is a task-initiating method, so if there is something to do, -just return State.RUNNING. If not, return State.FINISHED. In case of -error, return State.ERROR and be ready to provide error message when

-

if State.RUNNING is returned, the :py:meth:.checkState method will be -used to check when this process has finished.

- --- - - - -
Note:All task methods, like this one, are expected to handle -all exceptions, and never raise an exception from these methods -to the core. Take that into account and handle exceptions inside -this method.
-
- -
-
-osmanager()¶
-

Utility method to access os manager. This doesn’t need to be overriden.

-

Returns:

-
-
os manager for this user deployment, or None if this deployment has -no os manager.
-
- -
-
-publication()¶
-

Utility method to access publication. This doesn’t need to be overriden.

-

Returns:

-
-
publication for this user deployment, or None if this deployment has -no publication at all.
-
- -
-
-reasonOfError()¶
-

Returns the reason of the error.

-

Remember that the class is responsible of returning this whenever asked -for it, and it will be asked everytime it’s needed to be shown to the -user (when the administation asks for it).

- --- - - - -
Note:Remember that you can use ugettext to translate this error to -user language whenever it is possible. (This one will get invoked -directly from admin interface and, as so, will have translation -environment correctly set up.
-
- -
-
-service()¶
-

Utility method to access parent service. This doesn’t need to be override.

-

Normaly user deployments will need parent service to provide the -consumable to the user.

-

Returns:

-
-
Parent service of this User Deployment
-
- -
-
-setIp(ip)¶
-

This is an utility method, invoked by some os manager to notify what they thinks is the ip for this service. -If you assign the service IP by your own methods, do not override this

-
- -
-
-setReady()¶
-

This is a task method. As that, the excepted return values are -State values RUNNING, FINISHED or ERROR.

-

The method is invoked whenever a machine is provided to an user, right -before presenting it (via transport rendering) to the user.

-

This method exist for this kind of situations (i will explain it with a -sample)

-

Imagine a Service tree (Provider, Service, ...) for virtual machines. -This machines will get created by the UserDeployment implementation, but, -at some time, the machine can be put at in an state (suspend, shut down) -that will make the transport impossible to connect with it.

-

This method, in this case, will check the state of the machine, and if -it is “ready”, that is, powered on and accessible, it will return -“State.FINISHED”. If the machine is not accessible (has been erased, for -example), it will return “State.ERROR” and store a reason of error so UDS -can ask for it and present this information to the Administrator.

-

If the machine powered off, or suspended, or any other state that is not -directly usable but can be put in an usable state, it will return -“State.RUNNING”, and core will use checkState to see when the operation -has finished.

- --- - - - -
Note:All task methods, like this one, are expected to handle -all exceptions, and never raise an exception from these methods -to the core. Take that into account and handle exceptions inside -this method.
-
- -
-
-userLoggedIn(username)¶
-

This method must be available so os managers can invoke it whenever -an user get logged into a service.

-

Default implementation does nothing, so if you are going to do nothing, -you don’t need to implement it.

-

The responsibility of notifying it is of os manager actor, and it’s -directly invoked by os managers (right now, linux os manager and windows -os manager)

-

The user provided is just an string, that is provided by actors.

-
- -
-
-userLoggedOut(username)¶
-

This method must be available so os managers can invoke it whenever -an user get logged out if a service.

-

Default implementation does nothing, so if you are going to do nothing, -you don’t need to implement it.

-

The responability of notifying it is of os manager actor, and it’s -directly invoked by os managers (right now, linux os manager and windows -os manager)

-

The user provided is just an string, that is provided by actor.

-
- -
- -
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/development/architecture.html b/server/documentation/_build/html/development/architecture.html deleted file mode 100644 index 6a4d94fd..00000000 --- a/server/documentation/_build/html/development/architecture.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - - - UDS’s architecture — UDS 1.0 documentation - - - - - - - - - - - - - - - -
-
-

Table Of Contents

- - -

Previous topic

-

Installing UDS

-

Next topic

-

UDS’s core API

-

This Page

- - - -
-
- -
-
-
-
- -
-

UDS’s architecture¶

-

This section covers the current UDS Arquiceture & diagrams.

-

UDS is built on the Django web framework, which itself is -built on Python, thus MyTARDIS follows the architectural model -of Django.

-
-

Component Architecture¶

-

This diagram shows the major components of UDS.

-
    -
  • -
    Core components
    -
    -
    -
    -
  • -
  • -
    RDBMS
    -

    UDS is currently being developed/testing on Mysql 5 Database. -May other databases will work also, but no one else has been tested.

    -
    -
    -
  • -
-
-
-

Functional Architecture¶

-

UDS is build using Django as base support for Web acess and Database access.

-

Over this, UDS uses the following diagram:

-

DIAGRAM

-
-
Core
-
Basic core funcionality.
-
-
-
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/development/contributing.html b/server/documentation/_build/html/development/contributing.html deleted file mode 100644 index c30526b4..00000000 --- a/server/documentation/_build/html/development/contributing.html +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - Contributing to UDS — UDS 1.0 documentation - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Sample Authenticator

-

Next topic

-

UDS Repository

-

This Page

- - - -
-
- -
-
-
-
- -
-

Contributing to UDS¶

-
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/development/repository.html b/server/documentation/_build/html/development/repository.html deleted file mode 100644 index c3af3a68..00000000 --- a/server/documentation/_build/html/development/repository.html +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - UDS Repository — UDS 1.0 documentation - - - - - - - - - - - - - - -
-
-

Previous topic

-

Contributing to UDS

-

This Page

- - - -
-
- -
-
-
-
- -
-

UDS Repository¶

-
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/development/samples/auths/Authenticator.html b/server/documentation/_build/html/development/samples/auths/Authenticator.html deleted file mode 100644 index 79234281..00000000 --- a/server/documentation/_build/html/development/samples/auths/Authenticator.html +++ /dev/null @@ -1,742 +0,0 @@ - - - - - - - - Sample Authenticator — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Sample User Deployment Two

-

Next topic

-

Contributing to UDS

-

This Page

- - - -
-
- -
-
-
-
- -
-

Sample Authenticator¶

-

The authenticator is the responsible of providing the needed mechanisms to UDS for -user authentication.

-

As thatm this must provide a number of methods, that will allow UDS to manage -things the way it needs to. (Access users, groups, check credentials, etc...)

-

Here you can Download sample

-
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2012 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification, 
-# are permitted provided that the following conditions are met:
-#
-#    * Redistributions of source code must retain the above copyright notice, 
-#      this list of conditions and the following disclaimer.
-#    * Redistributions in binary form must reproduce the above copyright notice, 
-#      this list of conditions and the following disclaimer in the documentation 
-#      and/or other materials provided with the distribution.
-#    * Neither the name of Virtual Cable S.L. nor the names of its contributors 
-#      may be used to endorse or promote products derived from this software 
-#      without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''
-.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-from django.utils.translation import ugettext_noop as translatable
-from uds.core.ui.UserInterface import gui
-from uds.core import auths
-
-import logging
-
-logger = logging.getLogger(__name__)
-
-class SampleAuth(auths.Authenticator):
-    '''
-    This class represents a sample authenticator.
-    
-    As this, it will provide:
-       * The authenticator functionality 
-          * 3 Groups, "Mortals", "Gods" and "Daemons", just random group names selected.. :-),
-            plus groups that we enter at Authenticator form, from admin interface.
-          * Search of groups (inside the 3 groups used in this sample plus entered)
-          * Search for people (will return the search string + 000...999 as usernames)
-       * The Required form description for administration interface, so admins can create
-         new authenticators of this kind. 
-       
-    In this sample, we will provide a simple standard auth, with owner drawn
-    login form that will simply show users that has been created and allow web user
-    to select one of them.
-       
-    For this class to get visible at administration client as a authenticator type,
-    we MUST register it at package __init__
-
-    :note: At class level, the translations must be simply marked as so
-    using ugettext_noop. This is done in this way because we will translate 
-    the string when it is sent to the administration client.
-    '''
-    
-    #: Name of type, used at administration interface to identify this 
-    #: authenticator (i.e. LDAP, SAML, ...)
-    #: This string will be translated when provided to admin interface
-    #: using ugettext, so you can mark it as "translatable" at derived classes (using ugettext_noop)
-    #: if you want so it can be translated.
-    typeName = translatable('Sample Authenticator')
-    
-    #: Name of type used by Managers to identify this type of service
-    #: We could have used here the Class name, but we decided that the 
-    #: module implementator will be the one that will provide a name that
-    #: will relation the class (type) and that name.
-    typeType = 'SampleAuthenticator'
-    
-    #: Description shown at administration level for this authenticator.
-    #: This string will be translated when provided to admin interface
-    #: using ugettext, so you can mark it as "translatable" at derived classes (using ugettext_noop)
-    #: if you want so it can be translated.
-    typeDescription = translatable('Sample dummy authenticator')
-    
-    
-    #: Icon file, used to represent this authenticator at administration interface
-    #: This file should be at same folder as this class is, except if you provide
-    #: your own :py:meth:uds.core.BaseModule.BaseModule.icon method.
-    iconFile = 'auth.png'
-    
-    #: Mark this authenticator as that the users comes from outside the UDS
-    #: database, that are most authenticator (except Internal DB)
-    #: True is the default value, so we do not need it in fact 
-    # isExternalSource = True 
-    
-    #: If we need to enter the password for this user when creating a new
-    #: user at administration interface. Used basically by internal authenticator.
-    #: False is the default value, so this is not needed in fact
-    #: needsPassword = False
-    
-    #: Label for username field, shown at administration interface user form.
-    userNameLabel = translatable('Fake User')
-    
-    # Label for group field, shown at administration interface user form.
-    groupNameLabel = translatable('Fake Group')
-    
-    #: Definition of this type of authenticator form
-    #: We will define a simple form where we will use a simple
-    #: list editor to allow entering a few group names
-    
-    groups = gui.EditableList(label=translatable('Groups'), values = ['Gods', 'Daemons', 'Mortals'])
-    
-    def initialize(self, values):
-        '''
-        Simply check if we have
-        at least one group in the list
-        '''
-        
-        # To avoid problems, we only check data if values are passed
-        # If values are not passed in, form data will only be available after
-        # unserialization, and at this point all will be default values
-        # so self.groups.value will be []
-        if values is not None and len(self.groups.value) < 2:
-            raise auths.Authenticator.ValidationException(translatable('We need more that two items!'))
-        
-    def searchUsers(self, pattern):
-        '''
-        Here we will receive a pattern for searching users.
-        
-        This method is invoked from interface, so an administrator can search users.
-        
-        If we do not provide this method, the authenticator will not provide search
-        facility for users. In our case, we will simply return a list of users
-        (array of dictionaries with ids and names) with the pattern plus 1..10 
-        '''
-        return [ { 'id' : '{0}-{1}'.format(pattern, a), 'name' : '{0} number {1}'.format(pattern, a) } for a in range(1, 10)]
-            
-    def searchGroups(self, pattern):
-        '''
-        Here we we will receive a patter for searching groups.
-        
-        In this sample, we will try to locate elements that where entered at
-        sample authenticator form (when created), and return the ones that
-        contains the pattern indicated.
-        '''
-        pattern = pattern.lower()
-        res = []
-        for g in self.groups.value:
-            if g.lower().find(pattern) != -1:
-                res.append({'id' : g, 'name' : ''})
-        return res
-    
-    def authenticate(self, username, credentials, groupsManager):
-        '''
-        This method is invoked by UDS whenever it needs an user to be authenticated.
-        It is used from web interface, but also from administration interface to
-        check credentials and access of user.
-        
-        The tricky part of this method is the groupsManager, but it's easy to
-        understand what is used it for.
-        
-        Imagine some authenticator, for example, an LDAP. It has its users, it has
-        its groups, and it has it relations (which user belongs to which group).
-        
-        Now think about UDS. UDS know nothing about this, it only knows what
-        the administator has entered at admin interface (groups mainly, but he can
-        create users also).
-        
-        UDS knows about this groups, but we need to relation those with the ones
-        know by the authenticator. 
-        
-        To do this, we have created a simple mechanism, where the authenticator
-        receives a groupsManager, that knows all groups known by UDS, and has
-        the method so the authenticator can say, for the username being validated,
-        to which uds groups it belongs to.
-        
-        This is done using the :py:meth:uds.core.auths.GroupsManager.GroupsManager.validate
-        method of the provided groups manager.
-        
-        At return, UDS will do two things:
-           * If there is no group inside the groupsManager mareked as valid, it will
-             denied access.
-           * If there is some groups marked as valid, it will refresh the known
-             UDS relations (this means that the database will be refresehd so the user
-             has valid groups).
-             
-        This also means that the group membership is only checked at user login (well,
-        in fact its also checked when an administrator tries to modify an user)
-        
-        So, authenticate must not also validate the user credentials, but also
-        indicate the group membership of this user inside UDS. 
-        
-        :note: groupsManager is an in/out parameter
-        '''
-        if username != credentials: # All users with same username and password are allowed
-            return False
-    
-        # Now the tricky part. We will make this user belong to groups that contains at leat
-        # two letters equals to the groups names known by UDS
-        # For this, we will ask the groups manager for the groups names, and will check that and,
-        # if the user match this criteria, will mark that group as valid
-        for g in groupsManager.getGroupsNames():
-            if len(set(g.lower()).intersection(username.lower())) >= 2:
-                groupsManager.validate(g)
-        
-        return True
-
-    def getGroups(self, username, groupsManager):
-        '''
-        As with authenticator part related to groupsManager, this
-        method will fill the groups to which the specified username belongs to.
-        
-        We have to fill up groupsManager from two different places, so it's not
-        a bad idea to make a method that get the "real" authenticator groups and
-        them simply call to :py:meth:uds.core.auths.GroupsManager.GroupsManager.validate
-        
-        In our case, we simply repeat the process that we also do at authenticate
-        '''
-        for g in groupsManager.getGroupsNames():
-            if len(set(g.lower()).intersection(username.lower())) >= 2:
-                groupsManager.validate(g)
-
-    def getHtml(self, request):
-        '''
-        If we override this method from the base one, we are telling UDS
-        that we want to draw our own authenticator.
-        
-        This way, we can do whataver we want here (for example redirect to a site
-        for a single sign on) generation our ouwn html (and javascript ofc).
-        
-        '''
-        # Here there is a sample, commented out
-        # In this sample, we will make a list of valid users, and when clicked,
-        # it will fill up original form with username and same password, and submit it.
-        #res = ''
-        #for u in self.dbAuthenticator().users.all():
-        #    res += '<a class="myNames" id="{0}" href="">{0}</a><br/>'.format(u.name)
-        #    
-        #res += '<script type="text/javascript">$(".myNames").click(function() { '
-        #res += '$("#id_user").val(this.id); $("#id_password").val(this.id); $("#loginform").submit(); return false;});</script>'
-        #return res
-        
-        # I know, this is a bit ugly, but this is just a sample :-)
-        
-        res = '<p>Login name: <input id="logname" type="text"/></p>'
-        res +='<p><a href="" onclick="window.location.replace(\'' + self.callbackUrl() + '?user='
-        res += '\' + $(\'#logname\').val()); return false;">Login</a></p>'
-        return res
-        
-    
-    def authCallback(self, parameters):
-        '''
-        We provide this as a sample of callback for an user.
-        We will accept all petitions that has "user" parameter
-        
-        This method will get invoked by url redirections, probably by an SSO.
-        
-        The idea behind this is that we can provide:
-            * Simple user/password authentications
-            * Own authentications (not UDS, authenticator "owned"), but with no redirections
-            * Own authentications via redirections (as most SSO will do)
-            
-        Here, we will receive the parameters for this
-        '''
-        user = parameters.get('user', None)
-        
-        return user
-
-    def createUser(self, usrData):
-        '''
-        This method provides a "check oportunity" to authenticators for users created
-        manually at administration interface.
-        
-        If we do not provide this method, the administration interface will not allow
-        to create new users "by hand", i mean, the "new" options from menus will dissapear.
-        
-        usrData is a dictionary that contains the input parameters from user, 
-        with at least name, realName, comments, state & password.
-        
-        We can modify this parameters, we can modify ALL, but name is not recommended to 
-        modify it unles you know what you are doing.
-        
-        Here, we will set the state to "Inactive" and realName to the same as username, but twice :-)
-        '''
-        from uds.core.util.State import State
-        usrData['realName'] = usrData['name'] + ' ' + usrData['name']
-        usrData['state'] = State.INACTIVE
-        
-    def modifyUser(self, usrData):
-        '''
-        This method provides a "check opportunity" to authenticator for users modified
-        at administration interface.
-        
-        If we do not provide this method, nothing will happen (default one does nothing, but
-        it's valid).
-        
-        usrData is a dictionary that contains the input parameters from user, 
-        with at least name, realName, comments, state & password.
-        
-        We can modify this parameters, we can modify ALL, but name is not recommended to 
-        modify it unless you know what you are doing.
-        
-        Here, we will simply update the realName of the user, and (we have to take care
-        this this kind of things) modify the userName to a new one, the original plus '-1'
-        '''
-        usrData['realName'] = usrData['name'] + ' ' + usrData['name']
-        usrData['name'] = usrData['name'] + '-1'
-
-
-
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/development/samples/samples.html b/server/documentation/_build/html/development/samples/samples.html deleted file mode 100644 index fe9a2d86..00000000 --- a/server/documentation/_build/html/development/samples/samples.html +++ /dev/null @@ -1,216 +0,0 @@ - - - - - - - - UDS Modules Samples — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Table Of Contents

- - -

Previous topic

-

Authenticator Interface

-

Next topic

-

Needs for a service package

-

This Page

- - - -
-
- -
-
-
-
- -
-

UDS Modules Samples¶

-

In this section we cover basic samples of the different kind of mudules supported -by UDS.

-

UDS is designed in a modular way, meaning this that it has a core that allows -a number of modules to get plugged inside the whole system.

-

This modules are:

-
-
    -
  • Services, including all stuff around them.
  • -
  • Transports
  • -
  • OS Managers
  • -
  • Authenticators
  • -
-
-

This secion will try to give sample of every module, what it must do and how this -must be done.

-
-

Service Sample¶

-

A service is composed of several classes. This classes depends on how the service works.

-

This are:

-
-
    -
  • Provider, that is simply the “root” where services -descent, so we can configure just one part of the service parameters and rest -of them at service level.

    -

    One sample of provider is a virtualization server, such as oVirt, Open Nebula, or -others like it. We can keep info about server at provider level, and info about -what we need in an specific service at service level.

    -
  • -
  • Service, that is a service definition, that must be deployed at a later stage -to offer something to the users.

    -

    Following our previous sample, if provider was an oVirt server, a service can -be a Virtual Machine cloned COW.

    -
  • -
  • Publication, This class is optional. If service declares that needs a -publication for deployment of user instance, this class implements exactly -that, the publication for that service. Publications are in fact a way of -allowing services to prepare something in a stage prior to creating the -user consumable services.

    -

    Following our previous sample, if provider was an oVirt Server and the service -was a Virtual Machine cloned for Cow, the poblication can be a full clone of -the service machine for making COWS from this one.

    -
  • -
  • DeployedService, This class is the user consumed service itself. After a -service is created, it must be deployed, and deploy will mean that there will -be “instances” of that service (User Deployments) that will be consumed by -users.

    -

    Following our previous sample, if the publication was a full copy machine, -an deployed service can be a machine in COW format using as base that -machine.

    -
  • -
-
-

From theese, the only not really needed is Publication. Publication will only be -needed whenever a service needs a “preparation” before creating the user consumable -deployed services. For a service to be usable, we will need the full tree, meaning -this that we will provide all controllers (Provider, service or services, publication -or publications, deployed service or deployed services.).

-

All class belonging to a service must be grouped under the same package, and we -well need to register this package for the system to recognize it as service.

-

For this, we must register the Provider, that has references to rest of items.

-

Provider declares which services it provides. Services declares which publication -and deployed service it needs. Provider can declare multiples services it offers, -but services has at most one publication and exatly one deployed service.

-

So, by registering the Provider, we register the whole tree provided by de package.

-

Here you can find samples of every class needed for creating a new package of -services.

- -
-
-

Authenticator Sample¶

-

An authenticator is composed of a single class, derived from uds.core.auths.Authenticator.

-

Here you can find a sample of an authenticator.

- -
-
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/development/samples/services/DeployedServiceOne.html b/server/documentation/_build/html/development/samples/services/DeployedServiceOne.html deleted file mode 100644 index 57c5f0ee..00000000 --- a/server/documentation/_build/html/development/samples/services/DeployedServiceOne.html +++ /dev/null @@ -1,877 +0,0 @@ - - - - - - - - Sample User Deployment One — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Sample publication

-

Next topic

-

Sample User Deployment Two

-

This Page

- - - -
-
- -
-
-
-
- -
-

Sample User Deployment One¶

-

User deployments are the class that are responsible for creating the ultimate consumable -user service, that is, for managing that whenever the core requests a new service for -an user, this classes will take responsibility to provide it.

-

Here we cover SampleUserDeploymentOne that is for SampleServiceOne, do not needs to be -published and do not uses cache.

-

You can easily follow the code to see what it does, and what you have to do if you -want to provide a new one.

-

Download sample

-
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2012 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification, 
-# are permitted provided that the following conditions are met:
-#
-#    * Redistributions of source code must retain the above copyright notice, 
-#      this list of conditions and the following disclaimer.
-#    * Redistributions in binary form must reproduce the above copyright notice, 
-#      this list of conditions and the following disclaimer in the documentation 
-#      and/or other materials provided with the distribution.
-#    * Neither the name of Virtual Cable S.L. nor the names of its contributors 
-#      may be used to endorse or promote products derived from this software 
-#      without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''
-.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-
-from uds.core.services import UserDeployment
-from uds.core.util.State import State
-import logging
-
-logger = logging.getLogger(__name__)
-
-class SampleUserDeploymentOne(UserDeployment):
-    '''
-    This class generates the user consumable elements of the service tree.
-    
-    After creating at administration interface an Deployed Service, UDS will
-    create consumable services for users using UserDeployment class as
-    provider of this elements.
-    
-    
-    At class instantiation, this will receive an environment with"generator",
-    that are classes that provides a way to generate unique items.
-    
-    The generators provided right now are 'mac' and 'name'. To get more info
-    about this, look at py:class:`uds.core.util.UniqueMacGenerator.UniqueNameGenerator`
-    and py:class:`uds.core.util.UniqueNameGenerator.UniqueNameGenerator`
-    
-    This first sample do not uses cache. To see one with cache, see
-    SampleUserDeploymentTwo. The main difference are the "...Cache".." methods,
-    that here are not needed.
-    
-    As sample also of environment storage usage, wi will use here the provider
-    storage to keep all our needed info, leaving marshal and unmarshal (needed
-    by Serializble classes, like this) empty (that is, returns '' first and does
-    nothing the second one)
-    
-    Also Remember, if you don't include this class as the deployedType of the
-    SampleServiceOne, or whenever you trie to access a service of SampleServiceOne,
-    you will get an excetion that says that you havent included the deployedType. 
-    '''
-    
-    #: Recheck every five seconds by default (for task methods)
-    suggestedTime = 5
-
-    # Serializable needed methods        
-    def marshal(self):
-        '''
-        Does nothing right here, we will use envoronment storage in this sample
-        '''
-        return ''
-    
-    def unmarshal(self, str_):
-        '''
-        Does nothing here also, all data are keeped at environment storage
-        '''
-        pass
-    
-
-    def getName(self):
-        '''
-        We override this to return a name to display. Default inplementation 
-        (in base class), returns getUniqueIde() value
-        This name will help user to identify elements, and is only used
-        at administration interface.
-        
-        We will use here the environment name provided generator to generate
-        a name for this element.
-        
-        The namaGenerator need two params, the base name and a length for a 
-        numeric incremental part for generating unique names. This are unique for
-        all UDS names generations, that is, UDS will not generate this name again
-        until this name is freed, or object is removed, what makes its environment
-        to also get removed, that makes all uniques ids (names and macs right now)
-        to also get released.
-        
-        Every time get method of a generator gets called, the generator creates
-        a new unique name, so we keep the first generated name cached and don't
-        generate more names. (Generator are simple utility classes)
-        '''
-        name = self.storage().readData('name')
-        if name is None: 
-            name = self.nameGenerator().get( self.service().getBaseName() 
-                            + '-' + self.service().getColour(), 3 )
-            # Store value for persistence
-            self.storage().saveData('name', name)
-             
-        return name
-    
-    def setIp(self, ip):
-        '''
-        In our case, there is no OS manager associated with this, so this method
-        will never get called, but we put here as sample.
-        
-        Whenever an os manager actor notifies the broker the state of the service
-        (mainly machines), the implementation of that os manager can (an probably will)
-        need to notify the IP of the deployed service. Remember that UDS treats with
-        IP services, so will probable needed in every service that you will create.
-        :note: This IP is the IP of the "consumed service", so the transport can
-               access it.
-        '''
-        self.storage().saveData('ip', str(ip))
-    
-    def getUniqueId(self):
-        '''
-        Return and unique identifier for this service.
-        In our case, we will generate a mac name, that can be also as sample
-        of 'mac' generator use, and probably will get used something like this
-        at some services.
-        
-        The get method of a mac generator takes one param, that is the mac range
-        to use to get an unused mac.
-        '''
-        mac = self.storage().readData('mac')
-        if mac is None:
-            mac =  self.macGenerator().get( '00:00:00:00:00:00-00:FF:FF:FF:FF:FF' )
-            self.storage().saveData('mac', mac)
-        return mac
-    
-    def getIp(self):
-        '''
-        We need to implement this method, so we can return the IP for transports
-        use. If no IP is known for this service, this must return None
-        
-        If our sample do not returns an IP, IP transport will never work with
-        this service. Remember in real cases to return a valid IP address if
-        the service is accesible and you alredy know that (for example, because
-        the IP has been assigend via setIp by an os manager) or because
-        you get it for some other method.  
-        
-        Storage returns None if key is not stored.
-        
-        :note: Keeping the IP address is responsibility of the User Deployment.
-               Every time the core needs to provide the service to the user, or
-               show the IP to the administrator, this method will get called
-               
-        '''
-        ip = self.storage().readData('ip')
-        if ip is None:
-            ip = '192.168.0.34' # Sample IP for testing purposses only
-        return ip
-
-    def setReady(self):
-        '''
-        This is a task method. As that, the expected return values are
-        State values RUNNING, FINISHED or ERROR.
-        
-        The method is invoked whenever a machine is provided to an user, right
-        before presenting it (via transport rendering) to the user.
-        
-        This method exist for this kind of situations (i will explain it with a 
-        sample)
-        
-        Imagine a Service tree (Provider, Service, ...) for virtual machines.
-        This machines will get created by the UserDeployment implementation, but,
-        at some time, the machine can be put at in an state (suspend, shut down)
-        that will make the transport impossible to connect with it.
-        
-        This method, in this case, will check the state of the machine, and if
-        it is "ready", that is, powered on and accesible, it will return 
-        "State.FINISHED". If the machine is not accesible (has ben erased, for
-        example), it will return "State.ERROR" and store a reason of error so UDS
-        can ask for it and present this information to the Administrator.
-        
-        If the machine powered off, or suspended, or any other state that is not
-        directly usable but can be put in an usable state, it will return
-        "State.RUNNING", and core will use checkState to see when the operation
-        has finished.
-        
-        I hope this sample is enough to explain the use of this method..
-        '''
-        
-        # In our case, the service is always ready
-        return State.FINISHED
-        
-    def deployForUser(self, user):
-        '''
-        Deploys an service instance for an user.
-
-        This is a task method. As that, the excepted return values are
-        State values RUNNING, FINISHED or ERROR.
-        
-        The user parameter is not realy neded, but provided. It indicates the
-        Database User Object (see py:mod:`uds.modules`) to which this deployed
-        user service will be assigned to.
-        
-        This method will get called whenever a new deployed service for an user
-        is needed. This will give this class the oportunity to create
-        a service that is assigned to an user.
-        
-        The way of using this method is as follows:
-        
-        If the service gets created in "one step", that is, before the return
-        of this method, the consumable service for the user gets created, it
-        will return "State.FINISH".
-        If the service needs more steps (as in this case), we will return 
-        "State.RUNNING", and if it has an error, it wil return "State.ERROR" and
-        store an error string so administration interface can show it.
-        
-        We do not use user for anything, as in most cases will be.
-        '''
-        import random
-
-        self.storage().saveData('count', '0')
-        
-        # random fail
-        if random.randint(0, 9) == 9:
-            self.storage().saveData('error', 'Random error at deployForUser :-)')
-            return State.ERROR
-        
-        return State.RUNNING
-    
-    
-    def checkState(self):
-        '''
-        Our deployForUser method will initiate the consumable service deployment, 
-        but will not finish it.
-        
-        So in our sample, we will only check if a number reaches 5, and if so
-        return that we have finished, else we will return that we are working
-        on it.
-        
-        One deployForUser returns State.RUNNING, this task will get called until
-        checkState returns State.FINISHED.
-        
-        Also, we will make the publication fail one of every 10 calls to this
-        method.
-        
-        Note: Destroying, canceling and deploying for cache also makes use of 
-        this method, so you must keep the info of that you are checking if you
-        need it. 
-        In our case, destroy is 1-step action so this will no get called while
-        destroying, and cancel will simply invoke destroy
-        '''
-        import random
-        
-        count = int(self.storage().readData('count')) + 1
-        # Count is always a valid value, because this method will never get
-        # called before deployForUser, deployForCache, destroy or cancel.
-        # In our sample, we only use checkState in case of deployForUser,
-        # so at first call count will be 0.
-        if count >= 5:
-            return State.FINISHED
-        
-        # random fail
-        if random.randint(0, 9) == 9:
-            self.storage().saveData('error', 'Random error at checkState :-)')
-            return State.ERROR
-        
-        self.storage().saveData('count', str(count))
-        return State.RUNNING
-    
-    def finish(self):
-        '''
-        Invoked when the core notices that the deployment of a service has finished.
-        (No matter wether it is for cache or for an user)
-        
-        This gives the oportunity to make something at that moment.
-        :note: You can also make these operations at checkState, this is really
-        not needed, but can be provided (default implementation of base class does
-        nothing) 
-        '''
-        # Note that this is not really needed, is just a sample of storage use
-        self.storage().remove('count')
-        
-    def assignToUser(self, user):
-        '''
-        This method is invoked whenever a cache item gets assigned to an user.
-        This gives the User Deployment an oportunity to do whatever actions
-        are required so the service puts at a correct state for using by a service.
-        
-        In our sample, the service is always ready, so this does nothing.
-        
-        This is not a task method. All level 1 cache items can be diretly
-        assigned to an user with no more work needed, but, if something is needed,
-        here you can do whatever you need
-        '''
-        pass
-    
-    def userLoggedIn(self, user):
-        '''
-        This method must be available so os managers can invoke it whenever
-        an user get logged into a service.
-        
-        Default implementation does nothing, so if you are going to do nothing,
-        you don't need to implement it.
-        
-        The responability of notifying it is of os manager actor, and it's 
-        directly invoked by os managers (right now, linux os manager and windows
-        os manager)
-        
-        The user provided is just an string, that is provided by actor.
-        '''
-        # We store the value at storage, but never get used, just an example
-        self.storage().saveData('user', user)
-        
-    def userLoggedOut(self, user):
-        '''
-        This method must be available so os managers can invoke it whenever
-        an user get logged out if a service.
-        
-        Default implementation does nothing, so if you are going to do nothing,
-        you don't need to implement it.
-        
-        The responability of notifying it is of os manager actor, and it's 
-        directly invoked by os managers (right now, linux os manager and windows
-        os manager)
-        
-        The user provided is just an string, that is provided by actor.
-        '''
-        # We do nothing more that remove the user
-        self.storage().remove('user')
-    
-    def reasonOfError(self):
-        '''
-        Returns the reason of the error.
-        
-        Remember that the class is responsible of returning this whenever asked
-        for it, and it will be asked everytime it's needed to be shown to the
-        user (when the administation asks for it).
-        '''
-        return self.storage().readData('error') or 'No error'
-    
-    def destroy(self):
-        '''
-        This is a task method. As that, the excepted return values are
-        State values RUNNING, FINISHED or ERROR.
-        
-        Invoked for destroying a deployed service
-        Do whatever needed here, as deleting associated data if needed (i.e. a copy of the machine, snapshots, etc...)
-        @return: State.FINISHED if no more checks/steps for deployment are needed, State.RUNNING if more steps are needed (steps checked using checkState)
-        ''' 
-        return State.FINISHED
-
-    def cancel(self):
-        '''
-        This is a task method. As that, the excepted return values are
-        State values RUNNING, FINISHED or ERROR.
-        
-        This can be invoked directly by an administration or by the clean up
-        of the deployed service (indirectly).
-        When administrator requests it, the cancel is "delayed" and not
-        invoked directly.
-        '''
-        return State.FINISHED
-        
-
-
-
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/development/samples/services/DeployedServiceTwo.html b/server/documentation/_build/html/development/samples/services/DeployedServiceTwo.html deleted file mode 100644 index 0632d489..00000000 --- a/server/documentation/_build/html/development/samples/services/DeployedServiceTwo.html +++ /dev/null @@ -1,1069 +0,0 @@ - - - - - - - - Sample User Deployment Two — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Sample User Deployment One

-

Next topic

-

Sample Authenticator

-

This Page

- - - -
-
- -
-
-
-
- -
-

Sample User Deployment Two¶

-

User deployments are the class that are responsible for creating the ultimate consumable -user service, that is, for managing that whenever the core requests a new service for -an user, this classes will take responsibility to provide it.

-

Here we cover SampleUserDeploymentTwo that is for SampleServiceTwo, needs to be -published and has L1 and L2 cache items.

-

You can easily follow the code to see what it does, and what you have to do if you -want to provide a new one.

-

Download sample

-
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
-414
-415
-416
-417
-418
-419
-420
-421
-422
-423
-424
-425
-426
-427
-428
-429
-430
-431
-432
-433
-434
-435
-436
-437
-438
-439
-440
-441
-442
-443
-444
-445
-446
-447
-448
-449
-450
-451
-452
-453
-454
-455
-456
-457
-458
-459
-460
-461
-462
-463
-464
-465
-466
-467
-468
-469
# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2012 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification, 
-# are permitted provided that the following conditions are met:
-#
-#    * Redistributions of source code must retain the above copyright notice, 
-#      this list of conditions and the following disclaimer.
-#    * Redistributions in binary form must reproduce the above copyright notice, 
-#      this list of conditions and the following disclaimer in the documentation 
-#      and/or other materials provided with the distribution.
-#    * Neither the name of Virtual Cable S.L. nor the names of its contributors 
-#      may be used to endorse or promote products derived from this software 
-#      without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''
-.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-
-from uds.core.services import UserDeployment
-from uds.core.util.State import State
-import logging
-
-logger = logging.getLogger(__name__)
-
-class SampleUserDeploymentTwo(UserDeployment):
-    '''
-    This class generates the user consumable elements of the service tree.
-    
-    This is almost the same as SampleUserDeploymentOne, but differs that this one
-    uses the publication to get data from it, in a very basic way.
-    
-    After creating at administration interface an Deployed Service, UDS will
-    create consumable services for users using UserDeployment class as
-    provider of this elements.
-    
-    At class instantiation, this will receive an environment with"generator",
-    that are classes that provides a way to generate unique items.
-    
-    The generators provided right now are 'mac' and 'name'. To get more info
-    about this, look at py:class:`uds.core.util.UniqueMacGenerator.UniqueNameGenerator`
-    and py:class:`uds.core.util.UniqueNameGenerator.UniqueNameGenerator`
-    
-    As sample also of environment storage usage, wi will use here the provider
-    storage to keep all our needed info, leaving marshal and unmarshal (needed
-    by Serializable classes, like this) empty (that is, returns '' first and does
-    nothing the second one)
-    
-    Also Remember, if you don't include this class as the deployedType of the
-    SampleServiceTwo, or whenever you try to access a service of SampleServiceTwo,
-    you will get an exception that says that you haven't included the deployedType. 
-    '''
-    
-    #: Recheck every five seconds by default (for task methods)
-    suggestedTime = 2
-
-    def initialize(self):
-        '''
-        Initialize default attributes values here. We can do whatever we like,
-        but for this sample this is just right...
-        '''
-        self._name = ''
-        self._ip = ''
-        self._mac = ''
-        self._error = ''
-        self._count = 0
-        
-    # Serializable needed methods        
-    def marshal(self):
-        '''
-        Marshal own data, in this sample we will marshal internal needed
-        attributes.
-        
-        In this case, the data will be store with the database record. To
-        minimize database storage usage, we will "zip" data before returning it.
-        Anyway, we should keep this data as low as possible, we also have an
-        storage for loading larger data.
-        
-        :note: It's a good idea when providing marshalers, to store a 'version'
-               beside the values, so we can, at a later stage, treat with old
-               data for current modules.
-        '''
-        data = '\t'.join(['v1', self._name, self._ip, self._mac, self._error,
-                          str(self._count)])
-        return data.encode('zip')
-    
-    def unmarshal(self, str_):
-        '''
-        We unmarshal the content. 
-        '''
-        data = str_.decode('zip').split('\t')
-        # Data Version check
-        # If we include some new data at some point in a future, we can
-        # add "default" values at v1 check, and load new values at 'v2' check.
-        if data[0] == 'v1':
-            self._name, self._ip, self._mac, self._error, count = data[1:]
-            self._count = int(count)
-
-    def getName(self):
-        '''
-        We override this to return a name to display. Default implementation 
-        (in base class), returns getUniqueIde() value
-        This name will help user to identify elements, and is only used
-        at administration interface.
-        
-        We will use here the environment name provided generator to generate
-        a name for this element.
-        
-        The namaGenerator need two params, the base name and a length for a 
-        numeric incremental part for generating unique names. This are unique for
-        all UDS names generations, that is, UDS will not generate this name again
-        until this name is freed, or object is removed, what makes its environment
-        to also get removed, that makes all unique ids (names and macs right now)
-        to also get released.
-        
-        Every time get method of a generator gets called, the generator creates
-        a new unique name, so we keep the first generated name cached and don't
-        generate more names. (Generator are simple utility classes)
-        '''
-        if self._name == '':
-            self._name = self.nameGenerator().get( self.publication().getBaseName(), 
-                                                   3 )
-        # self._name will be stored when object is marshaled
-        return self._name
-    
-    def setIp(self, ip):
-        '''
-        In our case, there is no OS manager associated with this, so this method
-        will never get called, but we put here as sample.
-        
-        Whenever an os manager actor notifies the broker the state of the service
-        (mainly machines), the implementation of that os manager can (an probably will)
-        need to notify the IP of the deployed service. Remember that UDS treats with
-        IP services, so will probable needed in every service that you will create.
-        :note: This IP is the IP of the "consumed service", so the transport can
-               access it.
-        '''
-        self._ip = ip
-    
-    def getUniqueId(self):
-        '''
-        Return and unique identifier for this service.
-        In our case, we will generate a mac name, that can be also as sample
-        of 'mac' generator use, and probably will get used something like this
-        at some services.
-        
-        The get method of a mac generator takes one param, that is the mac range
-        to use to get an unused mac.
-        
-        The mac generated is not used by anyone, it will not depend on
-        the range, the generator will take care that this mac is unique
-        and in the range provided, or it will return None. The ranges
-        are wide enough to ensure that we always will get a mac address
-        in this case, but if this is not your case, take into account that
-        None is a possible return value, and in that case, you should return an
-        invalid id right now. Every time a task method is invoked, the core
-        will try to update the value of the unique id using this method, so
-        that id can change with time. (In fact, it's not unique at database level,
-        it's unique in the sense that you must return an unique id that can, for
-        example, be used by os managers to identify this element).
-               
-        :note: Normally, getting out of macs in the mac pool is a bad thing... :-)
-        '''
-        if self._mac == '':
-            self._mac =  self.macGenerator().get( '00:00:00:00:00:00-00:FF:FF:FF:FF:FF' )
-        return self._mac
-    
-    def getIp(self):
-        '''
-        We need to implement this method, so we can return the IP for transports
-        use. If no IP is known for this service, this must return None
-        
-        If our sample do not returns an IP, IP transport will never work with
-        this service. Remember in real cases to return a valid IP address if
-        the service is accesible and you alredy know that (for example, because
-        the IP has been assigend via setIp by an os manager) or because
-        you get it for some other method.  
-        
-        Storage returns None if key is not stored.
-        
-        :note: Keeping the IP address is responsibility of the User Deployment.
-               Every time the core needs to provide the service to the user, or
-               show the IP to the administrator, this method will get called
-               
-        '''
-        if self._ip == '':
-            return '192.168.0.34' # Sample IP for testing purposes only
-        return self._ip
-
-    def setReady(self):
-        '''
-        This is a task method. As that, the excepted return values are
-        State values RUNNING, FINISHED or ERROR.
-        
-        The method is invoked whenever a machine is provided to an user, right
-        before presenting it (via transport rendering) to the user.
-        
-        This method exist for this kind of situations (i will explain it with a 
-        sample)
-        
-        Imagine a Service tree (Provider, Service, ...) for virtual machines.
-        This machines will get created by the UserDeployment implementation, but,
-        at some time, the machine can be put at in an state (suspend, shut down)
-        that will make the transport impossible to connect with it.
-        
-        This method, in this case, will check the state of the machine, and if
-        it is "ready", that is, powered on and accessible, it will return 
-        "State.FINISHED". If the machine is not accessible (has been erased, for
-        example), it will return "State.ERROR" and store a reason of error so UDS
-        can ask for it and present this information to the Administrator.
-        
-        If the machine powered off, or suspended, or any other state that is not
-        directly usable but can be put in an usable state, it will return
-        "State.RUNNING", and core will use checkState to see when the operation
-        has finished.
-        
-        I hope this sample is enough to explain the use of this method..
-        '''
-        
-        # In our case, the service is always ready
-        return State.FINISHED
-        
-    def deployForUser(self, user):
-        '''
-        Deploys an service instance for an user.
-
-        This is a task method. As that, the excepted return values are
-        State values RUNNING, FINISHED or ERROR.
-        
-        The user parameter is not realy neded, but provided. It indicates the
-        Database User Object (see py:mod:`uds.modules`) to which this deployed
-        user service will be assigned to.
-        
-        This method will get called whenever a new deployed service for an user
-        is needed. This will give this class the oportunity to create
-        a service that is assigned to an user.
-        
-        The way of using this method is as follows:
-        
-        If the service gets created in "one step", that is, before the return
-        of this method, the consumable service for the user gets created, it
-        will return "State.FINISH".
-        If the service needs more steps (as in this case), we will return 
-        "State.RUNNING", and if it has an error, it wil return "State.ERROR" and
-        store an error string so administration interface can show it.
-        
-        We do not use user for anything, as in most cases will be.
-        '''
-        import random
-
-        self._count = 0
-        
-        # random fail
-        if random.randint(0, 9) == 9:
-            # Note that we can mark this string as translatable, and return
-            # it translated at reasonOfError method
-            self._error = 'Random error at deployForUser :-)'
-            return State.ERROR
-        
-        return State.RUNNING
-    
-    def deployForCache(self, cacheLevel):
-        '''
-        Deploys a user deployment as cache.
-
-        This is a task method. As that, the expected return values are
-        State values RUNNING, FINISHED or ERROR.
-        
-        In our sample, this will do exactly the same as deploy for user,
-        except that it will never will give an error.
-        
-        See deployForUser for a description of what this method should do.
-        
-        :note: deployForCache is invoked whenever a new cache element is needed
-               for an specific user deployment. It will also indicate for what
-               cache level (L1, L2) is the deployment
-        '''
-        self._count = 0
-        return State.RUNNING
-
-    def moveToCache(self, newLevel):
-        '''
-        This method is invoked whenever the core needs to move from the current
-        cache level to a new cache level an user deployment.
-        
-        This is a task method. As that, the expected return values are
-        State values RUNNING, FINISHED or ERROR.
-        
-        We only provide newLevel, because there is only two cache levels, so if
-        newLevel is L1, the actual is L2, and if it is L2, the actual is L1.
-        
-        Actually there is no possibility to move assigned services again back to
-        cache. If some service needs that kind of functionallity, this must be
-        provided at service level (for example, when doing publishing creating
-        a number of services that will be used, released and reused by users).
-        
-        Also, user deployments that are at cache level 2 will never get directly
-        assigned to user. First, it will pass to L1 and then it will get assigned.
-        
-        A good sample of a real implementation of this is moving a virtual machine
-        from a "suspended" state to  "running" state to assign it to an user.
-        
-        In this sample, there is L2 cache also, but moving from L1 to L2 and
-        from L2 to L1 is doing really nothing, so this method will do nothing.
-        
-        In a real scenario, we will, for example, suspend or resume virtual machine
-        and, return State.RUNNING and at checkState check if this task is completed.
-        '''
-        pass
-    
-    def checkState(self):
-        '''
-        Our deployForUser method will initiate the consumable service deployment, 
-        but will not finish it.
-        
-        So in our sample, we will only check if a number reaches 5, and if so
-        return that we have finished, else we will return that we are working
-        on it.
-        
-        One deployForUser returns State.RUNNING, this task will get called until
-        checkState returns State.FINISHED.
-        
-        Also, we will make the user deployment fail one of every 10 calls to this
-        method.
-        
-        Note: Destroying, canceling and deploying for cache also makes use of 
-        this method, so you must keep the info of that you are checking if you
-        need it. 
-        
-        In our case, destroy is 1-step action so this will no get called while
-        destroying, and cancel will simply invoke destroy. Cache deployment is
-        exactly as user deployment, except that the core will not assign it to
-        anyone, and cache moving operations is 
-        '''
-        import random
-        
-        self._count += 1
-        # Count is always a valid value, because this method will never get
-        # called before deployForUser, deployForCache, destroy or cancel.
-        # In our sample, we only use checkState in case of deployForUser,
-        # so at first call count will be 0.
-        if self._count >= 5:
-            return State.FINISHED
-        
-        # random fail
-        if random.randint(0, 9) == 9:
-            self._error = 'Random error at checkState :-)'
-            return State.ERROR
-        
-        return State.RUNNING
-    
-    def finish(self):
-        '''
-        Invoked when the core notices that the deployment of a service has finished.
-        (No matter whether it is for cache or for an user)
-        
-        This gives the opportunity to make something at that moment.
-        
-        :note: You can also make these operations at checkState, this is really
-        not needed, but can be provided (default implementation of base class does
-        nothing) 
-        '''
-        # We set count to 0, not needed but for sample purposes
-        self._count = 0
-        
-    def assignToUser(self, user):
-        '''
-        This method is invoked whenever a cache item gets assigned to an user.
-        This is not a task method right now, simply a notification. This means
-        that L1 cache items must be directly usable (except for the readyness part)
-        by users in a single step operation.
-        
-        Note that there will be an setReady call before letting the user consume
-        this user deployment, so this is more informational (so, if you keep at
-        what cache level is this instance, you can update it) than anything else.
-        
-        This is not a task method. All level 1 cache items can be dircetly
-        assigned to an user with no more work needed, but, if something is needed,
-        here you can do whatever you need.
-        
-        user is a Database user object.
-        '''
-        logger.debug('Assigned to user {0}'.format(user))
-    
-    def userLoggedIn(self, user):
-        '''
-        This method must be available so os managers can invoke it whenever
-        an user get logged into a service.
-        
-        Default implementation does nothing, so if you are going to do nothing,
-        you don't need to implement it.
-        
-        The responsibility of notifying it is of os manager actor, and it's 
-        directly invoked by os managers (right now, linux os manager and windows
-        os manager)
-        
-        The user provided is just an string, that is provided by actors.
-        '''
-        # We store the value at storage, but never get used, just an example
-        self.storage().saveData('user', user)
-        
-    def userLoggedOut(self, user):
-        '''
-        This method must be available so os managers can invoke it whenever
-        an user get logged out if a service.
-        
-        Default implementation does nothing, so if you are going to do nothing,
-        you don't need to implement it.
-        
-        The responability of notifying it is of os manager actor, and it's 
-        directly invoked by os managers (right now, linux os manager and windows
-        os manager)
-        
-        The user provided is just an string, that is provided by actor.
-        '''
-        # We do nothing more that remove the user
-        self.storage().remove('user')
-    
-    def reasonOfError(self):
-        '''
-        Returns the reason of the error.
-        
-        Remember that the class is responsible of returning this whenever asked
-        for it, and it will be asked everytime it's needed to be shown to the
-        user (when the administation asks for it).
-        
-        :note: Remember that you can use ugettext to translate this error to
-               user language whenever it is possible. (This one will get invoked
-               directly from admin interface and, as so, will have translation
-               environment correctly set up.
-        '''
-        return self._error
-    
-    def destroy(self):
-        '''
-        This is a task method. As that, the excepted return values are
-        State values RUNNING, FINISHED or ERROR.
-        
-        Invoked for destroying a deployed service
-        Do whatever needed here, as deleting associated data if needed (i.e. a copy of the machine, snapshots, etc...)
-        @return: State.FINISHED if no more checks/steps for deployment are needed, State.RUNNING if more steps are needed (steps checked using checkState)
-        ''' 
-        return State.FINISHED
-
-    def cancel(self):
-        '''
-        This is a task method. As that, the excepted return values are
-        State values RUNNING, FINISHED or ERROR.
-        
-        This can be invoked directly by an administration or by the clean up
-        of the deployed service (indirectly).
-        When administrator requests it, the cancel is "delayed" and not
-        invoked directly.
-        '''
-        return State.FINISHED
-
-
-
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/development/samples/services/Provider.html b/server/documentation/_build/html/development/samples/services/Provider.html deleted file mode 100644 index 220c6cf5..00000000 --- a/server/documentation/_build/html/development/samples/services/Provider.html +++ /dev/null @@ -1,523 +0,0 @@ - - - - - - - - Sample Service Provider — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Needs for a service package

-

Next topic

-

Sample service

-

This Page

- - - -
-
- -
-
-
-
- -
-

Sample Service Provider¶

-

The service provider is the top of the tree of services needed clases. -It main function is to provide a base for services, where this services contains -a common parent that is, for example, a server, a range of IPs, etc...

-

This sample covers a simple service provider, explains also a bit about FormFields -and shows what tasks must be done by a service provider.

-

You can easily follow the code to see what it does, and what you have to do if you -want to provide a new one.

-

Download sample

-
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2012 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification, 
-# are permitted provided that the following conditions are met:
-#
-#    * Redistributions of source code must retain the above copyright notice, 
-#      this list of conditions and the following disclaimer.
-#    * Redistributions in binary form must reproduce the above copyright notice, 
-#      this list of conditions and the following disclaimer in the documentation 
-#      and/or other materials provided with the distribution.
-#    * Neither the name of Virtual Cable S.L. nor the names of its contributors 
-#      may be used to endorse or promote products derived from this software 
-#      without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''
-Created on Jun 22, 2012
-
-.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-
-from django.utils.translation import ugettext_noop as translatable, ugettext as _
-from uds.core.services import ServiceProvider
-from SampleService import ServiceOne, ServiceTwo
-from uds.core.ui import gui
-
-import logging
-
-logger = logging.getLogger(__name__)
-
-
-class Provider(ServiceProvider):
-    '''
-    This class represents the sample services provider
-    
-    In this class we provide:
-       * The Provider functionality
-       * The basic configuration parameters for the provider
-       * The form fields needed by administrators to configure this provider
-       
-       :note: At class level, the translation must be simply marked as so
-       using ugettext_noop. This is so cause we will translate the string when
-       sent to the administration client.
-       
-    For this class to get visible at administration client as a provider type,
-    we MUST register it at package __init__.
-    
-    '''
-    #: What kind of services we offer, this are classes inherited from Service
-    offers = [ServiceOne, ServiceTwo]
-    #: Name to show the administrator. This string will be translated BEFORE
-    #: sending it to administration interface, so don't forget to
-    #: mark it as translatable (using ugettext_noop)
-    typeName = translatable('Sample Provider') 
-    #: Type used internally to identify this provider
-    typeType = 'SampleProvider'
-    #: Description shown at administration interface for this provider
-    typeDescription = translatable('Sample (and dummy) service provider')
-    #: Icon file used as icon for this provider. This string will be translated 
-    #: BEFORE sending it to administration interface, so don't forget to
-    #: mark it as translatable (using ugettext_noop)
-    iconFile = 'provider.png'
-    
-    # now comes the form fields
-    # There is always two fields that are requested to the admin, that are:
-    # Service Name, that is a name that the admin uses to name this provider
-    # Description, that is a short description that the admin gives to this provider
-    # Now we are going to add a few fields that we need to use this provider
-    # Remember that these are "dummy" fields, that in fact are not required
-    # but used for sample purposes
-    # If we don't indicate an order, the output order of fields will be
-    # "random"
-    
-    #: Remote host. Here core will translate label and tooltip, remember to
-    #: mark them as translatable using ugettext_noop.
-    remoteHost = gui.TextField(oder=1,
-                     length = 64,  
-                     label = translatable('Remote host'),
-                     tooltip = translatable('This fields contains a remote host'),
-                     required = True,
-                 )
-    #: Name of your pet (sample, not really needed :-) )
-    petName = gui.TextField(order=2,
-                  length = 32,  
-                  label = translatable('Your pet\'s name'),
-                  tooltip = translatable('If you like, write the name of your pet'),
-                  requred = False,
-                  defvalue = 'Tux' #: This will not get translated
-              )
-    #: Age of Methuselah (matusalén in spanish)
-    #: in Spain there is a well-known to say that something is very old, 
-    #: "Tiene mas años que matusalén"(is older than Methuselah)
-    methAge = gui.NumericField(order = 3,
-                  length = 4, # That is, max allowed value is 9999  
-                  label = translatable('Age of Methuselah'),
-                  tooltip = translatable('If you know it, please, tell me!!!'),
-                  required = True, #: Numeric fields have always a value, so this not really needed
-                  defvalue = '4500'
-              )
-     
-    #: Is Methuselah istill alive?
-    methAlive = gui.CheckBoxField(order = 4,
-                    label = translatable('Is Methuselah still alive?'),
-                    tooltip = translatable('If you fail, this will not get saved :-)'),
-                    required = True, #: Also means nothing. Check boxes has always a value
-                    defvalue = gui.TRUE #: By default, at new item, check this
-                ) 
-    
-    # There is more fields type, but not here the best place to cover it
-    def initialize(self, values = None):
-        '''
-        We will use the "autosave" feature for form fields, that is more than
-        enought for most providers. (We simply need to store data provided by user
-        and, maybe, initialize some kind of connection with this values).
-        
-        Normally provider values are rally used at sevice level, cause we never
-        instantiate nothing except a service from a provider.
-        '''
-        
-        # If you say meth is alive, you are wrong!!! (i guess..)
-        # values are only passed from administration client. Internals 
-        # instantiations are always empty.
-        if values is not None and self.methAlive.isTrue():
-            raise ServiceProvider.ValidationException(_('Methuselah is not alive!!! :-)'))
-
-    # Marshal and unmarshal are defaults ones, also enought
-    
-    # As we use "autosave" fields feature, dictValues is also provided by
-    # base class so we don't have to mess with all those things...
-    
-    @staticmethod
-    def test(env, data):
-        '''
-        Create your test method here so the admin can push the "check" button
-        and this gets executed.
-        Args:
-            env: environment passed for testing (temporal environment passed)
-            
-            data: data passed for testing (data obtained from the form 
-            definition)
-            
-        Returns: 
-            Array of two elements, first is True of False, depending on test 
-            (True is all right, false is error),
-            second is an String with error, preferably internacionalizated..
-        
-        In this case, wi well do nothing more that use the provider params
-        
-        Note also that this is an static method, that will be invoked using
-        the admin user provided data via administration client, and a temporary
-        environment that will be erased after invoking this method
-        '''
-        try:
-            # We instantiate the provider, but this may fail...
-            instance = Provider(env, data)
-            logger.debug('Methuselah has {0} years and is {1} :-)'
-                         .format(instance.methAge.value, instance.methAlive.value))
-        except ServiceProvider.ValidationException as e:
-            # If we say that meth is alive, instantiation will 
-            return [False, str(e)]
-        except Exception as e:
-            logger.exception("Exception caugth!!!")
-            return [False, str(e)]
-        return [True, _('Nothing tested, but all went fine..')]
-
-    # Congratulations!!!, the needed part of your first simple provider is done!
-    # Now you can go to administration panel, and check it
-    #
-    # From now onwards, we implement our own methods, that will be used by, 
-    # for example, services derived from this provider
-    def host(self):
-        '''
-        Sample method, in fact in this we just return 
-        the value of host field, that is an string
-        '''
-        return self.remoteHost.value
-    
-    
-    def methYears(self):
-        '''
-        Another sample return, it will in fact return the Methuselah years
-        '''
-
-
-
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/development/samples/services/Publication.html b/server/documentation/_build/html/development/samples/services/Publication.html deleted file mode 100644 index 5cee96b0..00000000 --- a/server/documentation/_build/html/development/samples/services/Publication.html +++ /dev/null @@ -1,678 +0,0 @@ - - - - - - - - Sample publication — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Sample service

-

Next topic

-

Sample User Deployment One

-

This Page

- - - -
-
- -
-
-
-
- -
-

Sample publication¶

-

A publication is a class responsible for making a service defined available to be -consumed by users.

-

Not all services needs publications as you have already seen if you are following -the samples. Publications are only needed for services that needs some kind of -preparation, as, for example, with Virtual Machines, clone the base virtual machine -so we can create COW copies from this clone. This kind of behavior needs a preparation -step, that is efectively to clone the virtual base, and that will be the task of a -publication for that kind of services.

-

You can easily follow the code to see what it does, and what you have to do if you -want to provide a new one.

-

Download sample

-
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2012 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification, 
-# are permitted provided that the following conditions are met:
-#
-#    * Redistributions of source code must retain the above copyright notice, 
-#      this list of conditions and the following disclaimer.
-#    * Redistributions in binary form must reproduce the above copyright notice, 
-#      this list of conditions and the following disclaimer in the documentation 
-#      and/or other materials provided with the distribution.
-#    * Neither the name of Virtual Cable S.L. nor the names of its contributors 
-#      may be used to endorse or promote products derived from this software 
-#      without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''
-.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-
-from django.utils.translation import ugettext as _
-from uds.core.services import Publication
-from uds.core.util.State import State
-from datetime import datetime
-import logging
-
-logger = logging.getLogger(__name__)
-
-class SamplePublication(Publication):
-    '''
-    This class shows how a publication is developed.
-    
-    In order to a publication to work correctly, we must provide at least the
-    following methods:
-        * Of course, the __init__
-        * :py:meth:`.publish` 
-        * :py:meth:`.checkState`
-        * :py:meth:`.finish`
-        
-    Also, of course, methods from :py:class:`uds.core.Serializable.Serializable`
-    
-    
-    Publication do not have an configuration interface, all data contained
-    inside an instance of a Publication must be serialized if you want them between
-    method calls.
-    
-    It's not waranteed that the class will not be serialized/deserialized
-    between methods calls, so, first of all, implement the marshal and umnarshal
-    mehods needed by all serializable classes.
-    
-    Also a thing to note is that operations requested to Publications must be
-    *as fast as posible*. The operations executes in a separated thread,
-    and so it cant take a bit more time to execute, but it's recommended that
-    the operations executes as fast as posible, and, if it will take a long time,
-    split operation so we can keep track of state.
-    
-    This means that, if we have "slow" operations, we must
-    
-    We first of all declares an estimation of how long a publication will take.
-    This value is instance based, so if we override it in our class, the suggested
-    time could change.
-    
-    The class attribute that indicates this suggested time is "suggestedTime", and
-    it's expressed in seconds, (i.e. "suggestedTime = 10") 
-    '''
-    
-    suggestedTime = 5 #: Suggested recheck time if publication is unfinished in seconds
-    
-    def initialize(self):
-        '''
-        This method will be invoked by default __init__ of base class, so it gives
-        us the oportunity to initialize whataver we need here. 
-        
-        In our case, we setup a few attributes..
-        '''
-        
-        # We do not check anything at marshal method, so we ensure that
-        # default values are correctly handled by marshal.
-        self._name = 'test'
-        self._reason = '' # No error, no reason for it
-        self._number = 1
-        
-    def marshal(self):
-        '''
-        returns data from an instance of Sample Publication serialized
-        '''
-        return '\t'.join( [self._name, self._reason, str(self._number)] )
-    
-    def unmarshal(self, data):
-        '''
-        deserializes the data and loads it inside instance.
-        '''
-        logger.debug('Data: {0}'.format(data))
-        vals = data.split('\t')
-        logger.debug('Values: {0}'.format(vals))
-        self._name = vals[0]
-        self._reason = vals[1]
-        self._number = int(vals[2])
-    
-    
-    def publish(self):
-        '''
-        This method is invoked whenever the administrator requests a new publication.
-        
-        The method is not invoked directly (i mean, that the administration request
-        do no makes a call to this method), but a DelayedTask is saved witch will
-        initiate all publication stuff (and, of course, call this method).
-        
-        You MUST implement it, so the publication do really something.
-        All publications can be synchronous or asynchronous.
-        
-        The main difference between both is that first do whatever needed, (the
-        action must be fast enough to do not block core), returning State.FINISHED.
-        
-        The second (asynchronous) are publications that could block the core, so
-        it have to be done in more than one step.
-        
-        An example publication could be a copy of a virtual machine, where:
-            * First we invoke the copy operation to virtualization provider
-            * Second, we kept needed values inside instance so we can serialize
-              them whenever requested
-            * Returns an State.RUNNING, indicating the core that the publication
-              has started but has to finish sometime later. (We do no check
-              again the state and keep waiting here, because we will block the
-              core untill this operation is finished).
-        
-        In our example wi will simple assign a name, and set number to 5. We 
-        will use this number later, to make a "delay" at check if the publication
-        has finished. (see method checkState)
-        
-        We also will make this publication an "stepped one", that is, it will not
-        finish at publish call but a later checkState call
-        
-        Take care with instantiating threads from here. Whenever a publish returns
-        "State.RUNNING", the core will recheck it later, but not using this instance
-        and maybe that even do not use this server. 
-        
-        If you want to use threadings or somethin likt it, use DelayedTasks and
-        do not block it. You also musht provide the mechanism to allow those
-        DelayedTask to communicate with the publication.
-        
-        One sample could be, for example, to copy a bunch of files, but we know
-        that this copy can take a long time and don't want it to take make it
-        all here, but in a separate task. Now, do you remember that "environment"
-        that is unique for every instance?, well, we can create a delayed task,
-        and pass that environment (owned by this intance) as a mechanism for
-        informing when the task is finished. (We insert at delayed tasks queue 
-        an instance, not a class itself, so we can instantiate a class and
-        store it at delayed task queue.
-        
-        Also note that, in that case, this class can also acomplish that by simply
-        using the suggestedTime attribute and the checkState method in most cases.
-        '''
-        self._number = 5
-        self._reason = ''
-        return State.RUNNING
-    
-    def checkState(self):
-        '''
-        Our publish method will initiate publication, but will not finish it.
-        So in our sample, wi will only check if _number reaches 0, and if so
-        return that we have finished, else we will return that we are working
-        on it.
-        
-        One publish returns State.RUNNING, this task will get called untill
-        checkState returns State.FINISHED.
-        
-        Also, wi will make the publication fail one of every 10 calls to this
-        method.
-        
-        Note: Destroying an publication also makes use of this method, so you 
-        must keep the info of that you are checking (publishing or destroying...)
-        In our case, destroy is 1-step action so this will no get called while
-        destroying...
-        '''
-        import random
-        self._number -= 1
-        # Serialization will take care of storing self._number
-        
-        # One of every 10 calls 
-        if random.randint(0, 9) == 9:
-            self._reason = _('Random integer was 9!!! :-)')
-            return State.ERROR
-         
-        if self._number <= 0:
-            return State.FINISHED
-        else:
-            return State.RUNNING
-           
-    
-    def finish(self):
-        '''
-        Invoked when Publication manager noticed that the publication has finished. 
-        This give us the oportunity of cleaning up things (as stored vars, etc..), 
-        or initialize variables that will be needed in a later phase (by deployed
-        services)
-        
-        Returned value, if any, is ignored
-        '''
-        import string
-        import random
-        # Make simply a random string
-        self._name = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(10))
-    
-    def reasonOfError(self):
-        '''
-        If a publication produces an error, here we must notify the reason why 
-        it happened. This will be called just after publish or checkState 
-        if they return State.ERROR
-        
-        Returns an string, in our case, set at checkState        
-        '''
-        return self._reason
-
-    def destroy(self):
-        '''
-        This is called once a publication is no more needed.
-        
-        This method do whatever needed to clean up things, such as
-        removing created "external" data (environment gets cleaned by core),
-        etc.. 
-        
-        The retunred value is the same as when publishing, State.RUNNING,
-        State.FINISHED or State.ERROR.
-        ''' 
-        self._name = '' 
-        self._reason = '' # In fact, this is not needed, but cleaning up things... :-)
-        
-        # We do not do anything else to destroy this instance of publication
-        return State.FINISHED
-        
-
-    def cancel(self):
-        '''
-        Invoked for canceling the current operation.
-        This can be invoked directly by an administration or by the clean up
-        of the deployed service (indirectly).
-        When administrator requests it, the cancel is "delayed" and not
-        invoked directly.
-        
-        Also, take into account that cancel is the initiation of, maybe, a 
-        multiple-step action, so it returns, as publish and destroy does.
-        
-        In our case, cancel simply invokes "destroy", that cleans up
-        things and returns that the action has finished in 1 step.
-        '''
-        return self.destroy()
-
-    # Here ends the publication needed methods.
-    # Methods provided below are specific for this publication
-    # and will be used by user deployments that uses this kind of publication
-
-    def getBaseName(self):
-        '''
-        This sample method (just for this sample publication), provides
-        the name generater for this publication. This is just a sample, and 
-        this will do the work
-        '''
-        return self._name
-
-
-
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/development/samples/services/Service.html b/server/documentation/_build/html/development/samples/services/Service.html deleted file mode 100644 index 239afb55..00000000 --- a/server/documentation/_build/html/development/samples/services/Service.html +++ /dev/null @@ -1,599 +0,0 @@ - - - - - - - - Sample service — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

Sample Service Provider

-

Next topic

-

Sample publication

-

This Page

- - - -
-
- -
-
-
-
- -
-

Sample service¶

-

Here we cover two services. ServiceOne, that do not needs publication and -ServiceTwo, that needs publication.

-

This sample should be enought to guide you through the creation of a new service.

-

Download sample

-
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
# -*- coding: utf-8 -*-
-
-#
-# Copyright (c) 2012 Virtual Cable S.L.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification, 
-# are permitted provided that the following conditions are met:
-#
-#    * Redistributions of source code must retain the above copyright notice, 
-#      this list of conditions and the following disclaimer.
-#    * Redistributions in binary form must reproduce the above copyright notice, 
-#      this list of conditions and the following disclaimer in the documentation 
-#      and/or other materials provided with the distribution.
-#    * Neither the name of Virtual Cable S.L. nor the names of its contributors 
-#      may be used to endorse or promote products derived from this software 
-#      without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''
-.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
-'''
-
-from django.utils.translation import ugettext_noop as translatable, ugettext as _
-from uds.core.services import Service
-from SamplePublication import SamplePublication
-from SampleUserDeploymentOne import SampleUserDeploymentOne
-from SampleUserDeploymentTwo import SampleUserDeploymentTwo
-
-from uds.core.ui import gui
-
-import logging
-
-logger = logging.getLogger(__name__)
-
-class ServiceOne(Service):
-    '''
-    Basic service, the first part (variables) include the description of the service.
-    
-    Remember to fill all variables needed, but at least you must define:
-        * typeName
-        * typeType
-        * typeDescription
-        * iconFile (defaults to service.png)
-        * publicationType, type of publication in case it needs publication. 
-          If this is not provided, core will assume that the service do not 
-          needs publishing.
-        * deployedType, type of deployed user service. Do not forget this!!!
-        
-    The rest of them can be ommited, but its recommended that you fill all
-    declarations shown in this sample (that in fact, are all)
-    
-    This description informs the core what this service really provides,
-    and how this is done. Look at description of class variables for more
-    information.
-    
-    '''
-    #: Name to show the administrator. This string will be translated BEFORE
-    #: sending it to administration interface, so don't forget to
-    #: mark it as translatable (using ugettext_noop)
-    typeName = translatable('Sample Service One') 
-    #: Type used internally to identify this provider
-    typeType = 'SampleService1'
-    #: Description shown at administration interface for this provider
-    typeDescription = translatable('Sample (and dummy) service ONE')
-    #: Icon file used as icon for this provider. This string will be translated 
-    #: BEFORE sending it to administration interface, so don't forget to
-    #: mark it as translatable (using ugettext_noop)
-    iconFile = 'service.png'
-    
-    # Functional related data
-    
-    #: If the service provides more than 1 "deployed user" (-1 = no limit, 
-    #: 0 = ???? (do not use it!!!), N = max number to deploy
-    maxDeployed = -1
-    #: If we need to generate "cache" for this service, so users can access the 
-    #: provided services faster. Is usesCache is True, you will need also 
-    #: set publicationType, do take care about that!
-    usesCache = False 
-    #: Tooltip shown to user when this item is pointed at admin interface, none 
-    #: because we don't use it
-    cacheTooltip = translatable('None')
-    #: If we need to generate a "Level 2" cache for this service (i.e., L1 
-    #: could be running machines and L2 suspended machines) 
-    usesCache_L2 = False 
-    #: Tooltip shown to user when this item is pointed at admin interface, None 
-    #: also because we don't use it
-    cacheTooltip_L2 = translatable('None') 
-      
-    #: If the service needs a s.o. manager (managers are related to agents 
-    #: provided by services itselfs, i.e. virtual machines with actors)
-    needsManager = False 
-    #: If true, the system can't do an automatic assignation of a deployed user 
-    #: service from this service
-    mustAssignManually = False 
-
-    #: Types of publications (preparated data for deploys) 
-    #: In our case, we do no need a publication, so this is None
-    publicationType = None
-    #: Types of deploys (services in cache and/or assigned to users)
-    deployedType = SampleUserDeploymentOne
-    
-    # Now the form part, this service will have only two "dummy" fields
-    # If we don't indicate an order, the output order of fields will be
-    # "random"
-    
-    colour = gui.ChoiceField(order = 1,
-                 label = translatable('Colour'),
-                 tooltip = translatable('Colour of the field'),
-                 # In this case, the choice can have none value selected by default
-                 required = True, 
-                 values = [ gui.choiceItem('red', 'Red'),
-                     gui.choiceItem('green', 'Green'),
-                     gui.choiceItem('blue', 'Blue'),
-                     gui.choiceItem('nonsense', 'Blagenta')
-                 ],
-                 defvalue = '1' # Default value is the ID of the choicefield
-             )
-    
-    passw = gui.PasswordField(order = 2,
-                label = translatable('Password'),
-                tooltip = translatable('Password for testing purposes'),
-                required = True,
-                defvalue = '1234' #: Default password are nonsense?? :-)
-            )
-
-    baseName = gui.TextField(order = 3,
-                          label = translatable('Services names'),
-                          tooltip = translatable('Base name for this user services'),
-                          # In this case, the choice can have none value selected by default
-                          required = True, 
-                          defvalue = '' # Default value is the ID of the choicefield
-             )
-    
-    def initialize(self, values):
-        '''
-        We check here form values to see if they are valid.
-        
-        Note that we check them throught FROM variables, that already has been
-        initialized by __init__ method of base class, before invoking this.
-        '''
-        
-        # We don't need to check anything, bat because this is a sample, we do
-        # As in provider, we receive values only at new Service creation,
-        # so we only need to validate params if values is not None
-        if values is not None:
-            if self.colour.value == 'nonsense':
-                raise Service.ValidationException('The selected colour is invalid!!!')
-        
-        
-    # Services itself are non testeable right now, so we don't even have
-    # to provide one!!!
-        
-
-    # Congratulations!!!, the needed part of your first simple service is done!
-    # Now you can go to administration panel, and check it
-    #
-    # From now onwards, we implement our own methods, that will be used by, 
-    # for example, services derived from this provider
-    
-    def getColour(self):
-        '''
-        Simply returns colour, for deployed user services.
-        
-        Remember that choiceField.value returns the id part of the ChoiceItem
-        '''
-        return self.colour.value
-    
-    def getPassw(self):
-        '''
-        Simply returns passwd, for deloyed user services
-        '''
-        return self.passw.value
-    
-    def getBaseName(self):
-        '''
-        '''
-        return self.baseName.value
-    
-     
-
-class ServiceTwo(Service):
-    '''
-    Just a second service, no comments here (almost same that ServiceOne
-    '''
-    typeName = translatable('Sample Service Two') 
-    typeType = 'SampleService2'
-    typeDescription = translatable('Sample (and dummy) service ONE+ONE')
-    iconFile = 'provider.png' #: We reuse provider icon here :-)
-    
-    # Functional related data
-    maxDeployed = 5
-    usesCache = True
-    cacheTooltip = translatable('L1 cache for dummy elements')
-    usesCache_L2 = True
-    cacheTooltip_L2 = translatable('L2 cache for dummy elements')
-      
-    needsManager = False
-    mustAssignManually = False
-
-    #: Types of publications. In this case, we will include a publication
-    #: type for this one  
-    #: Note that this is a MUST if you indicate that needPublication
-    publicationType = SamplePublication
-    #: Types of deploys (services in cache and/or assigned to users)
-    deployedType = SampleUserDeploymentTwo
-    
-    
-    # Gui, we will use here the EditableList field
-    names = gui.EditableList(label=translatable('List of names'))
-    
-    def __init__(self, environment, parent, values = None):
-        '''
-        We here can get a HUGE list from client.
-        Right now, this is treated same as other fields, in a near
-        future we will se how to handle this better
-        '''
-        super(ServiceTwo, self).__init__(environment, parent, values)
-        
-        # No checks here
-        
-    def getNames(self):
-        '''
-        For using at deployed services, really nothing
-        '''
-        return self.names.value
-
-
-
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/development/samples/services/whatisneeded.html b/server/documentation/_build/html/development/samples/services/whatisneeded.html deleted file mode 100644 index 77018227..00000000 --- a/server/documentation/_build/html/development/samples/services/whatisneeded.html +++ /dev/null @@ -1,236 +0,0 @@ - - - - - - - - Needs for a service package — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
-

Previous topic

-

UDS Modules Samples

-

Next topic

-

Sample Service Provider

-

This Page

- - - -
-
- -
-
-
-
- -
-

Needs for a service package¶

-

For a new package of services, you will need:

-
-
    -
  • One package (python package), of course :-).

    -
  • -
  • One icon for the provider, in png format an 16x16 size. Colours is left -to your election. This icon will be informed at Provider class.

    -
  • -
  • One icon for every service that the provider will expose. Same as provider -icons. These icons will be informed at Service class. Every single class -must provide its own icon.

    -
  • -
  • Registering the provider. For the samples show here, this will be at -__init__ of the package.

    -

    The contents of the sample package __init__ file is:

    -
     1
    - 2
    - 3
    - 4
    - 5
    - 6
    - 7
    - 8
    - 9
    -10
    -11
    -12
    -13
    -14
    -15
    -16
    -17
    -18
    -19
    -20
    -21
    -22
    -23
    -24
    -25
    -26
    -27
    -28
    -29
    -30
    -31
    -32
    -33
    -34
    -35
    -36
    -37
    -38
    -39
    -40
    -41
    -42
    -43
    # -*- coding: utf-8 -*-
    -
    -#
    -# Copyright (c) 2012 Virtual Cable S.L.
    -# All rights reserved.
    -#
    -# Redistribution and use in source and binary forms, with or without modification, 
    -# are permitted provided that the following conditions are met:
    -#
    -#    * Redistributions of source code must retain the above copyright notice, 
    -#      this list of conditions and the following disclaimer.
    -#    * Redistributions in binary form must reproduce the above copyright notice, 
    -#      this list of conditions and the following disclaimer in the documentation 
    -#      and/or other materials provided with the distribution.
    -#    * Neither the name of Virtual Cable S.L. nor the names of its contributors 
    -#      may be used to endorse or promote products derived from this software 
    -#      without specific prior written permission.
    -#
    -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
    -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
    -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
    -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 
    -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
    -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
    -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
    -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -
    -'''
    -Sample Service module.
    -
    -This package simply shows how a new service can be implemented. 
    -
    -
    -The first thing to do in every package that is a module is register the 
    -class that is responsible of providing the module with the system.
    -
    -For this, we must simply import the class at __init__, UDS will take care
    -of the rest
    -'''
    -
    -from SampleProvider import Provider 
    -
    -
    -

    Download sample

    -
  • -
  • Put the package under the apropiate uds package. In the case of -services, this is under “uds.core”.

    -

    Core will look for all packages under “uds.services” and import them at -initialization of the server, so every package under this will get their -__init__ called, where we register the provider.

    -
  • -
  • Follow the samples provided here as base

    -
  • -
-
-
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/genindex.html b/server/documentation/_build/html/genindex.html deleted file mode 100644 index a8c7e317..00000000 --- a/server/documentation/_build/html/genindex.html +++ /dev/null @@ -1,1309 +0,0 @@ - - - - - - - - - Index — UDS 1.0 documentation - - - - - - - - - - - - - -
-
- - - - - -
-
- -
-
-
-
- - -

Index

- -
- A - | B - | C - | D - | E - | F - | G - | I - | L - | M - | N - | O - | P - | R - | S - | T - | U - | V - -
-

A

- - - -
- -
activePublication() (uds.models.DeployedService method) -
- - -
all() (uds.models.Authenticator static method) -
- - -
assignedUserServices() (uds.models.DeployedService method) -
- - -
assignToUser() (uds.core.services.UserDeployment method) -
- -
- -
(uds.models.UserService method) -
- -
- -
authCallback() (uds.core.auths.Authenticator method) -
- -
- -
authenticate() (uds.core.auths.Authenticator method) -
- - -
Authenticator (class in uds.core.auths) -
- -
- -
(class in uds.models) -
- -
- -
Authenticator.Group (class in uds.core.auths) -
- - -
Authenticator.User (class in uds.core.auths) -
- -
- -

B

- - -
- -
beforeDelete() (uds.models.Authenticator static method) -
- -
- -
(uds.models.DeployedService static method) -
- - -
(uds.models.DeployedServicePublication static method) -
- - -
(uds.models.Group static method) -
- - -
(uds.models.Provider static method) -
- - -
(uds.models.Scheduler static method) -
- - -
(uds.models.Service static method) -
- - -
(uds.models.Transport static method) -
- - -
(uds.models.User static method) -
- - -
(uds.models.UserService static method) -
- -
-
- -

C

- - - -
- -
Cache (class in uds.models) -
- - -
cache() (uds.core.Environmentable method) -
- - -
cachedUserServices() (uds.models.DeployedService method) -
- - -
callbackUrl() (uds.core.auths.Authenticator method) -
- - -
cancel() (uds.core.services.Publication method) -
- -
- -
(uds.core.services.UserDeployment method) -
- - -
(uds.models.DeployedServicePublication method) -
- - -
(uds.models.UserService method) -
- -
- -
CancelException -
- - -
canCheckUserPassword() (uds.core.auths.Authenticator class method) -
- -
- -
check() (uds.core.Module method) -
- - -
checkState() (uds.core.services.Publication method) -
- -
- -
(uds.core.services.UserDeployment method) -
- -
- -
cleanUp() (uds.models.Cache static method) -
- - -
Config (class in uds.models) -
- - -
create() (uds.models.Network static method) -
- - -
createGroup() (uds.core.auths.Authenticator method) -
- - -
createUser() (uds.core.auths.Authenticator method) -
- -
- -

D

- - - -
- -
dbAuthenticator() (uds.core.auths.Authenticator method) -
- - -
dbGroup() (uds.core.auths.Authenticator.Group method) -
- - -
dbservice() (uds.core.services.UserDeployment method) -
- - -
dbUser() (uds.core.auths.Authenticator.User method) -
- - -
defValue (uds.core.ui.UserInterface.gui.InputField attribute) -
- - -
DelayedTask (class in uds.models) -
- - -
DeployedService (class in uds.models) -
- - -
DeployedServicePublication (class in uds.models) -
- -
- -
deployForCache() (uds.core.services.UserDeployment method) -
- - -
deployForUser() (uds.core.services.UserDeployment method) -
- - -
DeploymentException -
- - -
description() (uds.core.Module class method) -
- - -
destroy() (uds.core.Module method) -
- -
- -
(uds.core.services.Publication method) -
- - -
(uds.core.services.UserDeployment method) -
- -
- -
doLog() (uds.core.services.UserDeployment method) -
- - -
dsName() (uds.core.services.Publication method) -
- -
- -

E

- - - -
- -
env() (uds.core.Environmentable method) -
- - -
Environmentable (class in uds.core) -
- -
- -
erroneousUserServices() (uds.models.DeployedService method) -
- -
- -

F

- - -
- -
finish() (uds.core.services.Publication method) -
- -
- -
(uds.core.services.UserDeployment method) -
- -
-
- -

G

- - - -
- -
getConnectionSource() (uds.models.UserService method) -
- - -
getDeployedServicesForGroups() (uds.models.DeployedService static method) -
- - -
getEnvironment() (uds.models.Authenticator method) -
- -
- -
(uds.models.DeployedService method) -
- - -
(uds.models.DeployedServicePublication method) -
- - -
(uds.models.Provider method) -
- - -
(uds.models.Scheduler method) -
- - -
(uds.models.Service method) -
- - -
(uds.models.Transport method) -
- - -
(uds.models.UserService method) -
- -
- -
getForAuth() (uds.core.auths.Authenticator method) -
- - -
getGroups() (uds.core.auths.Authenticator method) -
- - -
getHtml() (uds.core.auths.Authenticator method) -
- - -
getInfo() (uds.core.auths.Authenticator method) -
- - -
getInstance() (uds.models.Authenticator method) -
- -
- -
(uds.models.DeployedServicePublication method) -
- - -
(uds.models.Provider method) -
- - -
(uds.models.Scheduler method) -
- - -
(uds.models.Service method) -
- - -
(uds.models.Transport method) -
- - -
(uds.models.UserService method) -
- -
- -
getIp() (uds.core.services.UserDeployment method) -
- - -
getManager() (uds.models.Group method) -
- -
- -
(uds.models.User method) -
- -
- -
getName() (uds.core.services.UserDeployment method) -
- -
- -
(uds.models.UserService method) -
- -
- -
getOrCreateUser() (uds.models.Authenticator method) -
- - -
getRealName() (uds.core.auths.Authenticator method) -
- - -
getServiceByType() (uds.core.services.ServiceProvider class method) -
- - -
getServicesTypes() (uds.core.services.ServiceProvider class method) -
- - -
getType() (uds.models.Authenticator method) -
- -
- -
(uds.models.Service method) -
- - -
(uds.models.Transport method) -
- -
- -
getUniqueId() (uds.core.services.UserDeployment method) -
- -
- -
(uds.models.UserService method) -
- -
-
- -
getUserAssignedServices() (uds.models.UserService static method) -
- - -
getUsernameForAuth() (uds.models.User method) -
- - -
Group (class in uds.models) -
- - -
groups() (uds.core.auths.Authenticator.User method) -
- - -
groupType (uds.core.auths.Authenticator attribute) -
- - -
gui (class in uds.core.ui.UserInterface) -
- - -
gui.CheckBoxField (class in uds.core.ui.UserInterface) -
- - -
gui.ChoiceField (class in uds.core.ui.UserInterface) -
- - -
gui.EditableList (class in uds.core.ui.UserInterface) -
- - -
gui.HiddenField (class in uds.core.ui.UserInterface) -
- - -
gui.InputField (class in uds.core.ui.UserInterface) -
- - -
gui.MultiChoiceField (class in uds.core.ui.UserInterface) -
- - -
gui.NumericField (class in uds.core.ui.UserInterface) -
- - -
gui.PasswordField (class in uds.core.ui.UserInterface) -
- - -
gui.TextField (class in uds.core.ui.UserInterface) -
- - -
guiDescription() (uds.core.ui.UserInterface.gui.InputField method) -
- -
- -
(uds.core.ui.UserInterface.UserInterface class method) -
- -
-
- -

I

- - - -
- -
icon() (uds.core.Module class method) -
- - -
idGenerators() (uds.core.Environmentable method) -
- - -
infoUrl() (uds.core.auths.Authenticator method) -
- - -
initGui() (uds.core.ui.UserInterface.UserInterface method) -
- - -
initialize() (uds.core.auths.Authenticator method) -
- -
- -
(uds.core.services.Publication method) -
- - -
(uds.core.services.Service method) -
- - -
(uds.core.services.ServiceProvider method) -
- - -
(uds.core.services.UserDeployment method) -
- -
- -
internalAuthenticate() (uds.core.auths.Authenticator method) -
- - -
InvalidServiceException -
- - -
isCustom() (uds.core.auths.Authenticator class method) -
- - -
isDirty() (uds.core.Module method) -
- -
- -
isPreparing() (uds.models.UserService method) -
- - -
isReady() (uds.models.UserService method) -
- - -
isRestrained() (uds.models.DeployedService method) -
- - -
isStaff() (uds.models.User method) -
- - -
isTrue() (uds.core.ui.UserInterface.gui.CheckBoxField method) -
- - -
isType() (uds.core.ui.UserInterface.gui.InputField method) -
- - -
isUsable() (uds.models.UserService method) -
- - -
isValidUser() (uds.models.Authenticator method) -
- -
- -

L

- - -
- -
logout() (uds.core.auths.Authenticator method) -
- -
- -
(uds.models.User method) -
- -
-
- -

M

- - - -
- -
macGenerator() (uds.core.services.Service method) -
- -
- -
(uds.core.services.UserDeployment method) -
- -
- -
manager() (uds.core.auths.Authenticator.Group method) -
- -
- -
(uds.core.auths.Authenticator.User method) -
- -
- -
markOldUserServicesAsRemovables() (uds.models.DeployedService method) -
- - -
marshal() (uds.core.Module method) -
- -
- -
(uds.core.Serializable method) -
- -
- -
MaxServicesReachedException -
- - -
modifyGroup() (uds.core.auths.Authenticator method) -
- -
- -
modifyUser() (uds.core.auths.Authenticator method) -
- - -
Module (class in uds.core) -
- - -
Module.ValidationException -
- - -
moveToCache() (uds.core.services.UserDeployment method) -
- - -
moveToLevel() (uds.models.UserService method) -
- -
- -

N

- - - -
- -
name() (uds.core.Module class method) -
- - -
nameGenerator() (uds.core.services.Service method) -
- -
- -
(uds.core.services.UserDeployment method) -
- -
- -
netEnd (uds.models.Network attribute) -
- - -
netStart (uds.models.Network attribute) -
- -
- -
Network (class in uds.models) -
- - -
networksFor() (uds.models.Network static method) -
- - -
notifyReadyFromOsManager() (uds.core.services.UserDeployment method) -
- - -
num() (uds.core.ui.UserInterface.gui.NumericField method) -
- -
- -

O

- - - -
- -
OperationException -
- - -
osManager() (uds.core.services.Publication method) -
- -
- -
osmanager() (uds.core.services.UserDeployment method) -
- -
- -

P

- - - -
- -
parent() (uds.core.services.Service method) -
- - -
prefs() (uds.models.User method) -
- - -
processUserPassword() (uds.models.DeployedService method) -
- -
- -
(uds.models.UserService method) -
- -
- -
Provider (class in uds.models) -
- -
- -
Publication (class in uds.core.services) -
- - -
publication() (uds.core.services.UserDeployment method) -
- - -
publish() (uds.core.services.Publication method) -
- -
- -
(uds.models.DeployedService method) -
- -
- -
PublishException -
- -
- -

R

- - - -
- -
reasonOfError() (uds.core.services.Publication method) -
- -
- -
(uds.core.services.UserDeployment method) -
- -
- -
recoverValue() (uds.models.DeployedService method) -
- -
- -
(uds.models.UserService method) -
- -
- -
recreateGroups() (uds.core.auths.Authenticator method) -
- - -
remove() (uds.models.DeployedService method) -
- -
- -
(uds.models.UserService method) -
- -
- -
removed() (uds.models.DeployedService method) -
- -
- -
removeGroup() (uds.core.auths.Authenticator method) -
- - -
removeOrCancel() (uds.models.UserService method) -
- - -
removeUser() (uds.core.auths.Authenticator method) -
- - -
requestServicesForAssignation() (uds.core.services.Service method) -
- - -
revision() (uds.core.services.Publication method) -
- -
- -

S

- - - -
- -
Scheduler (class in uds.models) -
- - -
searchGroups() (uds.core.auths.Authenticator method) -
- - -
searchUsers() (uds.core.auths.Authenticator method) -
- - -
Serializable (class in uds.core) -
- - -
serialize() (uds.core.Serializable method) -
- - -
serializeForm() (uds.core.ui.UserInterface.UserInterface method) -
- - -
Service (class in uds.core.services) -
- -
- -
(class in uds.models) -
- -
- -
service() (uds.core.services.Publication method) -
- -
- -
(uds.core.services.UserDeployment method) -
- -
- -
ServiceProvider (class in uds.core.services) -
- - -
setConnectionSource() (uds.models.UserService method) -
- - -
setDefValue() (uds.core.ui.UserInterface.gui.InputField method) -
- -
- -
setEnv() (uds.core.Environmentable method) -
- - -
setInUse() (uds.models.UserService method) -
- - -
setIp() (uds.core.services.UserDeployment method) -
- - -
setOsState() (uds.models.UserService method) -
- - -
setReady() (uds.core.services.UserDeployment method) -
- - -
setState() (uds.models.DeployedService method) -
- -
- -
(uds.models.DeployedServicePublication method) -
- - -
(uds.models.UserService method) -
- -
- -
setValues() (uds.core.ui.UserInterface.gui.ChoiceField method) -
- -
- -
(uds.core.ui.UserInterface.gui.MultiChoiceField method) -
- -
- -
Storage (class in uds.models) -
- - -
storage() (uds.core.Environmentable method) -
- - -
storeValue() (uds.models.DeployedService method) -
- -
- -
(uds.models.UserService method) -
- -
-
- -

T

- - - -
- -
test() (uds.core.Module static method) -
- - -
transformsUserOrPasswordForService() (uds.models.UserService method) -
- - -
transformUsername() (uds.core.auths.Authenticator method) -
- -
- -
Transport (class in uds.models) -
- - -
type() (uds.core.Module class method) -
- -
- -

U

- - - -
- -
uds.core (module) -
- - -
uds.core.auths (module) -
- - -
uds.core.services (module), [1], [2], [3] -
- - -
uds.core.services.Exceptions (module) -
- - -
uds.core.ui.UserInterface (module), [1] -
- - -
uds.models (module), [1], [2], [3] -
- - -
UniqueId (class in uds.models) -
- - -
unmarshal() (uds.core.Module method) -
- -
- -
(uds.core.Serializable method) -
- -
- -
unpublish() (uds.models.DeployedService method) -
- -
- -
(uds.models.DeployedServicePublication method) -
- -
- -
unserialize() (uds.core.Serializable method) -
- - -
unserializeForm() (uds.core.ui.UserInterface.UserInterface method) -
- - -
UnsupportedException -
- -
- -
update() (uds.models.Network method) -
- - -
updateData() (uds.models.DeployedServicePublication method) -
- -
- -
(uds.models.UserService method) -
- -
- -
updateLastAccess() (uds.models.User method) -
- - -
User (class in uds.models) -
- - -
UserDeployment (class in uds.core.services) -
- - -
UserInterface (class in uds.core.ui.UserInterface) -
- - -
userLoggedIn() (uds.core.services.UserDeployment method) -
- - -
userLoggedOut() (uds.core.services.UserDeployment method) -
- - -
UserPreference (class in uds.models) -
- - -
UserService (class in uds.models) -
- - -
userType (uds.core.auths.Authenticator attribute) -
- -
- -

V

- - - -
- -
validateUser() (uds.models.DeployedService method) -
- - -
validForIp() (uds.models.Transport method) -
- -
- -
value (uds.core.ui.UserInterface.gui.InputField attribute) -
- - -
valuesDict() (uds.core.ui.UserInterface.UserInterface method) -
- -
- - - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/index.html b/server/documentation/_build/html/index.html deleted file mode 100644 index cbdb5309..00000000 --- a/server/documentation/_build/html/index.html +++ /dev/null @@ -1,259 +0,0 @@ - - - - - - - - UDS’s documentation — UDS 1.0 documentation - - - - - - - - - - - - - - -
-
-

Table Of Contents

- - -

Next topic

-

UDS at a glance

-

This Page

- - - -
-
- -
-
-
-
- -
-

UDS’s documentation¶

-

This documentation is provided so we can understand (hopefully) UDS, its internals, -and everything about it.

-

Right now the documentation is not too ritch, but we are working on it so it will -get the needed level for this kind of project.

-
-

First Steps¶

- -
-
-
- -
-

UDS Open source project¶

- -
-
-
-
-

Acknowledgements¶

-

We want to thaks all the people that has contributed to de project, an also -other Open Source project used to improve this one.

-

List of other software used to build UDS:

-
-
-

I hope to do nor forget anythinh here, if i do, please, report it so we can credit -to every project that UDS makes use of.

-
-
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/intro/install.html b/server/documentation/_build/html/intro/install.html deleted file mode 100644 index 7c152753..00000000 --- a/server/documentation/_build/html/intro/install.html +++ /dev/null @@ -1,168 +0,0 @@ - - - - - - - - Installing UDS — UDS 1.0 documentation - - - - - - - - - - - - - - - -
-
-

Previous topic

-

UDS at a glance

-

Next topic

-

UDS’s architecture

-

This Page

- - - -
-
- -
-
-
-
- -
-

Installing UDS¶

-

In order to run UDS, you will need:

-
-
    -
  • Django Server 1.4
  • -
  • South module for Django
  • -
  • Mysql libraries for python
  • -
  • Mysql Database
  • -
  • Ldap Libraries for python
  • -
  • Criptographic package for python
  • -
-
-

Default transports are compiled in binary form, and keeped inside UDS repository, -so you won’t need Java to put UDS to work.

-

Once you have all of this, you will have to follow these steps:

-
-
    -
  • Obtain UDS from repository, you can see how to do this from
  • -
-
-
-
repository access documentation
-
    -
  • Configure a database for use with UDS. To do this, simple create a database -inside your Mysql server, and a user with all permissions in this database.

    -
  • -
  • Configure UDS settings. -Inside “server” folder, you will find “settings.py”. This file contains the -configuration of UDS (if it runs in debug mode, ..). The most important part -here is the DATABASES section, where you will set up the database that UDS -will use. Simply change “host”, “port”, “udsername”, “password” and “name” -to match your database settings. -Here, we have to take care that, if we left UDS in debug mode, Django will keep -track of all petitions to UDS, so memory will grow constantly. Do not get scared -if you see that UDS starts to waste too much memory. Simply restart it or, if it’s -intended to be running for a while, set DEBUG variable to “False”. -Important sections are:

    -
  • -
  • Create initial database tables. -Inside UDS folder, where you downloaded it, you will see a “manage.py”. -This python application is the responsible for managing UDS, from database creation, -migrations, backend start & stop, web server (testing web server btw), ... -To create initial databases, we will do:

    -
    -

    python manage.py sync -python manage.py migrate

    -
    -

    Now we have all databases and everything that UDS needs for starting up ready... :-)

    -
  • -
-
-
-
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/intro/overview.html b/server/documentation/_build/html/intro/overview.html deleted file mode 100644 index 7450c800..00000000 --- a/server/documentation/_build/html/intro/overview.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - - UDS at a glance — UDS 1.0 documentation - - - - - - - - - - - - - - - -
-
-

Previous topic

-

UDS’s documentation

-

Next topic

-

Installing UDS

-

This Page

- - - -
-
- -
-
-
-
- -
-

UDS at a glance¶

-

UDS has been developed to make a single open source server that allows the access -to the growing ip services catalog.

-

For this, we have try to make a framework that allows the use of any ip service, -focusing initially at VDI because it’s the mayor need for the people we have -contacted initially .

-

Also, first version of UDS has been developed “fast” (very fast indeed), so now -we need to make a revision an adapt de code of the framework so it’s more -‘pythonic’. (Think that i start learning python one day like this, and less than -a week later i started this proyect). So think that, althouth UDS is fully -functional, has been tested and is stable enought for any production environment, -there is a lot of work to do.

-

As so, UDS not only provides default modules for a lot of things (virtualization -provider, authentication providers, protocols, ...), but also provides the core -itself to allow anyone who wants or needs something, incorporate it to the -catalog of UDS in an easy and fast way.

- -
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/objects.inv b/server/documentation/_build/html/objects.inv deleted file mode 100644 index a0fca5cfa3a18a05a6d25044099a1f692262ba92..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2556 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 SoH|1KJ>9Uhk^c`GJu1#_$@M`1 diff --git a/server/documentation/_build/html/py-modindex.html b/server/documentation/_build/html/py-modindex.html deleted file mode 100644 index d2469be1..00000000 --- a/server/documentation/_build/html/py-modindex.html +++ /dev/null @@ -1,140 +0,0 @@ - - - - - - - - Python Module Index — UDS 1.0 documentation - - - - - - - - - - - - - - - - -
-
- - -
-
- -
-
-
-
- - -

Python Module Index

- -
- u -
- - - - - - - - - - - - - - - - - - - - - - - - - -
 
- u
- uds -
    - uds.core -
    - uds.core.auths -
    - uds.core.services -
    - uds.core.services.Exceptions -
    - uds.core.ui.UserInterface -
    - uds.models -
- - -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/search.html b/server/documentation/_build/html/search.html deleted file mode 100644 index e7d29535..00000000 --- a/server/documentation/_build/html/search.html +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - - - Search — UDS 1.0 documentation - - - - - - - - - - - - - - - - - - - -
-
-
-
- -
-
-
-
- -

Search

-
- -

- Please activate JavaScript to enable the search - functionality. -

-
-

- From here you can search these documents. Enter your search - words into the box below and click "search". Note that the search - function will automatically search for all of the words. Pages - containing fewer words won't appear in the result list. -

-
- - - -
- -
- -
- -
-
-
-
-
- - - - \ No newline at end of file diff --git a/server/documentation/_build/html/searchindex.js b/server/documentation/_build/html/searchindex.js deleted file mode 100644 index 4b75f3ad..00000000 --- a/server/documentation/_build/html/searchindex.js +++ /dev/null @@ -1 +0,0 @@ -Search.setIndex({envversion:42,terms:{represent:[3,4,10],all:[0,1,3,4,5,6,7,8,9,10,11,12,14,18,19,20,21,23,27,28,29,30],code:[11,12,20,21,6,15,23,7,8,9],forget:[12,18,14,28,29,7,8,30],indirectli:[21,9,6,14],queri:28,global:25,resourcepool:4,especifi:[19,24,20],known:[11,21,14,28,7,9],multichoic:4,getdeployedservicesforgroup:20,current:[19,20,21,4,14,6,16,28,29],recovervalu:20,follow:[11,0,1,3,4,14,6,15,16,27,23,7,8,21,9,10],groupnamelabel:11,children:20,row:4,decid:[11,28],middl:14,depend:[0,20,21,14,27,7],choicefield:[4,8],readabl:0,specif:[11,19,25,20,21,4,6,27,23,7,8,9,24],send:[7,0,8],environment:[13,22],init:29,estim:6,checkboxfield:[4,7],spain:7,skip:14,aris:[11,21,6,23,7,8,9],neglig:[11,21,6,23,7,8,9],nets_posit:[19,24],suitabl:0,merchant:[11,21,6,23,7,8,9],userloggedout:[21,9,14],digit:[4,6],sourc:[11,23,0,20,21,4,6,17,7,8,9,28],everi:[12,0,19,18,4,20,6,27,23,21,9,30,24],string:[11,0,21,4,14,6,28,29,7,8,9,24],functionalti:5,without:[11,23,0,20,18,14,6,17,29,7,8,21,9,30,28],fals:[11,19,0,1,4,20,28,7,8,24],execut:[25,4,7,6],callig:28,macgener:[18,9,14,21],account:[0,18,4,14,6,29,21,30],envion:0,util:[11,25,14,0,20,18,4,5,6,29,7,8,21,9],mechan:[11,28,14,6],uniqueid:[25,14],got:14,veri:[21,7,30,15],join:[21,6],deploymentexcept:17,secuenti:14,backtologin:28,searchgroup:[11,28],tri:[11,28,30,20],administr:[11,0,3,4,14,6,21,28,29,7,8,18,9,30,10],level:[11,12,20,21,4,14,27,7,8,9],did:20,descend:[4,0],gui:[11,4,7,0,8],list:[11,12,19,28,21,4,20,6,23,7,8,9,24],upload:24,usernamelabel:11,"try":[11,21,27,7,15],jobsfactori:25,form:[13,0,22],div:28,refer:[27,17,25],prepar:[25,20,6,27,29,8,10],pleas:[12,7],ass:[29,0,20],impli:[11,21,6,23,7,8,9],sevic:7,slower:14,throught:8,storag:[19,25,0,20,18,5,28,21,9,24],setstat:20,setconnectionsourc:20,resourc:[4,14],direct:[11,21,4,6,23,7,8,9],sign:11,remotehost:7,everytim:[21,25,9,14],second:[0,20,21,6,28,29,7,8,9],design:[27,5,15],pass:[11,19,0,20,21,4,14,6,28,7,9,24],download:[11,1,21,6,23,7,8,9],port:[4,0,1],append:11,blue:8,seral:0,deleg:25,servic:[13,19,25,5],appear:4,validationexcept:[11,7,0,8],basemodul:[13,22],unfinish:6,section:[27,16,5,1],nee:4,invok:[11,19,0,20,18,4,14,6,28,29,7,8,21,9,30,24],choiceitem:8,anywai:[21,0],access:[11,19,25,0,1,18,4,14,15,16,28,29,8,21,9,20,24],delet:[19,0,20,21,29,9,24],host:[4,7,0,25,1],version:[21,29,0,15],namegener:[18,9,14,21],intersect:11,uniqueidgener:25,"new":[11,19,0,20,28,21,4,14,6,27,23,29,7,8,9,24],net:[12,24],needpubl:8,method:[11,19,0,20,18,4,14,6,28,29,7,8,21,9,30,24],funtion:4,whatev:[0,21,14,6,28,29,9],typedescript:[11,7,0,8],full:[27,10],deriv:[11,25,0,28,3,4,14,6,21,27,23,29,7,8,18,9,30,10],absolut:28,usag:[21,4,9],gener:[11,25,0,20,18,14,28,8,21,9],never:[19,0,21,14,28,29,7,9],here:[11,12,14,0,1,28,21,4,5,6,22,27,23,29,7,8,9,20,30,10],disclaim:[11,21,6,23,7,8,9],met:[11,21,6,23,7,8,9],transformsuserorpasswordforservic:20,procur:[11,21,6,23,7,8,9],logout:[19,28],web:[11,28,24,16,1],address:[18,14,21,9,30,24],averi:28,locat:[11,4,14,30,20],coincid:0,unpublish:20,modifi:[11,28,4,0,20],ignor:[28,4,0,6,29],valu:[11,19,25,0,20,18,4,14,6,28,29,7,8,21,9,30,24],wait:[19,29,6],box:[4,7],thatm:11,convert:0,produc:[29,6,20],sender:[19,25,24,20],respon:[21,9,14],thate:17,larger:21,nonstandardlogin:28,"_name":[21,6],membership:[11,28],prior:[11,21,6,27,23,7,8,9],base:[19,25,20,13,22,24],staticmethod:[4,7],overriden:[28,14,0],action:[21,29,9,6,14],whatav:[11,6,10],implement:[11,14,0,28,18,5,6,15,27,23,29,7,8,21,9,30],point:[11,21,8],initgui:[4,0],via:[11,25,0,21,4,14,28,7,9],useful:28,hieararchi:20,methuselah:7,extra:4,apach:16,modul:[13,19,5],wil:[21,9,14],prefer:[19,0,18,14,28,29,7,30],ask:[11,21,9,14,20],href:11,istil:7,creategroup:28,visibl:[11,7],instal:12,should:[11,0,21,14,28,8],dsp:20,recreategroup:28,select:[11,28,4,8],highli:28,invaliduserexcept:20,obfusc:0,from:[0,1,3,4,6,7,8,9,10,11,12,14,18,19,20,21,23,24,25,27,28,29,30],describ:[5,0,20],zip:[21,0],commun:[12,4,14,6],setosst:20,longer:25,delayedtask:[29,25,6],pref:19,regist:[11,19,25,3,27,23,7,10],two:[11,0,20,13,18,4,14,27,28,29,9,30],next:0,websit:5,descriv:10,id_password:[11,28],usertyp:28,call:[11,19,24,0,20,18,28,14,6,23,29,21,9,30,10],until:[21,14,6,28,29,9],recommend:[11,28,4,6,8],taken:[19,29,24,20],codifi:0,care:[11,0,1,18,14,6,23,8,21,20,28],type:[11,19,0,20,18,4,28,7,8,30,24],tell:[11,4,7],more:[11,25,14,0,20,18,4,5,6,15,17,29,7,8,21,9,10],passw:[4,8],hiden:0,publcat:20,successful:28,peopl:[11,12,15],under:[27,23,14,10],line:4,notic:[11,28,21,14,6,23,29,7,8,9],flag:20,deseralil:0,accept:11,particular:[11,21,6,23,7,8,9],unseri:[11,0,18,14,29,30],authenticatorexcept:28,cach:[19,24,14,0,20,18,28,5,25,17,8,21,9,10],dot:[11,21,6,7,8,9,24],must:[11,25,0,20,28,18,4,14,6,15,22,27,23,29,7,8,21,9,30,10],fly:14,vcfillmachinesfromresourc:4,graphic:12,word:[28,14],userservicemanag:20,alia:[28,30],setup:6,work:[12,25,0,1,21,14,6,15,16,27,9],uniqu:[25,14,20,18,5,6,21,9],internacion:0,itself:[25,20,6,15,16,27,28,29,8,10],can:[0,1,18,4,5,6,7,8,9,10,11,12,14,17,19,20,21,23,24,25,27,28,29,30],learn:15,those:[11,19,20,14,6,28,29,7],rework:12,purpos:[11,21,5,6,23,7,8,9],root:[27,30,10],def:[11,21,4,6,7,8,9],isdirti:0,overrid:[11,0,18,4,14,6,28,29,21,9],cancelexcept:17,give:[0,21,14,6,22,27,29,7,9,10],process:[11,0,4,14,28,10],mayb:[28,4,7,6,20],registr:[3,10],callbackurl:[11,28],indic:[11,0,21,4,14,6,28,29,7,8,9],requr:7,want:[11,12,0,18,4,14,6,15,28,29,7,21,9,30],publicationtyp:8,serial:[19,25,0,20,18,4,14,6,29,30,24],ritch:12,uncheck:4,alwai:[19,0,18,4,14,28,29,7,21,9,30,24],cours:[18,4,29,6,23],end:[28,6,24],thing:[11,28,18,14,6,15,23,29,7,21,30],anoth:[7,0,14],get:[11,12,14,0,19,1,28,18,4,5,6,27,23,29,7,8,21,9,20,30,24],publicationmanag:20,modifygroup:28,how:[12,1,4,6,27,23,8],purg:25,isstaff:19,env:[28,7,0],ugettext_noop:[11,28,7,8],instead:28,config:[25,0],serializeform:0,overwrit:0,updat:[11,19,20,21,14,28,24],movetolevel:20,delai:[21,25,9,6,14],product:[11,21,6,15,23,7,8,9],str_:[21,9,0],overridden:0,huge:8,mess:7,max:[4,7,8],clone:[27,29,14,6,20],after:[11,18,4,14,6,27,28,29,7,21,9,30],grouptyp:28,usabl:[20,21,4,14,27,9],reflect:17,befor:[19,24,0,20,21,14,27,28,29,7,8,9,10],wrong:[7,20],scratch:12,assigend:[21,9],deveplop:0,mai:[11,19,0,20,21,4,6,16,23,7,8,9,28],multipl:[27,4,14,6],datastor:4,comma:4,persinst:25,grow:[15,1],testeabl:8,somethin:6,"short":7,classmethod:[28,0,30],condit:[11,21,6,23,7,8,9],saml:[11,19,28],credenti:[11,28,20],correspond:[4,0,30],activepubl:20,caus:[11,23,21,4,6,17,7,8,9],getconnectioninfo:20,type_:4,preced:4,environ:[13,19,5],allow:[11,0,20,4,14,6,15,22,27,28,7],enter:11,xxx:[4,24],order:[19,25,0,1,4,6,15,7,8],mudul:27,least:[11,0,3,4,6,28,8,10],help:[21,4,9],endors:[11,21,6,23,7,8,9],over:[4,5,16],assing:20,becaus:[11,0,20,18,14,6,15,28,29,8,21,9,30],cook:12,own:[11,19,0,20,3,28,14,6,15,22,23,29,7,30,8,18,24,21,10],through:[5,14,8],tort:[11,21,6,23,7,8,9],left:[23,1],paramer:4,serviceproviderfactori:[19,24,20],nombr:28,mainli:[11,21,9,0],mayor:15,paramet:[11,19,0,18,4,14,27,28,7,21,9],write:7,getinst:[19,25,24,20],group:[11,19,27,28,20],vchelper:4,fit:[11,21,6,23,7,8,9],udsernam:1,polici:20,invalid:[0,28,21,20,17,8],criptograph:1,opportun:[11,21,29,14],cla:25,netend:24,catalog:15,platform:19,isreadi:20,com:[11,21,6,7,8,9],restrain:20,button:[28,4,7],dbauth:[18,28],savedata:[21,9],userprefer:19,last_access:19,main:[19,20,14,6,29,7,9,24],easier:[28,20],auhtent:19,them:[11,19,25,20,28,18,4,6,27,23,29,7,8,30,24],good:[11,18,14,6,23,29,7,8,21,9,30],"return":[11,19,25,0,20,18,4,14,6,28,29,7,8,21,9,30,24],vaild:25,thei:[25,0,3,4,14,6,22,28,29,8,18,10],handl:[29,25,14,6,8],choice2:4,sampleuserdeploymenton:[21,9,8],dai:15,auth:[11,3,27,28,19],sampleservicetwo:21,authmodul:4,framework:[15,16],lenth:4,automat:[3,8,10],compound:29,front:28,now:[11,12,14,0,1,21,5,6,15,28,7,8,9,20,24],setvalu:4,nor:[11,12,21,4,6,23,7,8,9],tooltip:[4,7,8],wont:28,choic:[4,6,8],groupsmanag:[11,28],somewher:[28,14],name:[11,19,25,0,1,28,18,4,14,6,23,29,7,8,21,9,20,30,24],anyth:[19,21,4,14,6,28,8,9],edit:[28,4],loginform:[11,28],didn:28,authent:[13,5],petnam:7,separ:[4,0,6],easili:[21,7,9,6],envoron:9,alreadi:[6,8],diagram:16,mode:[20,1],dbgroup:28,fulli:15,went:[28,7],complet:[21,29,28],deployedtyp:[18,9,8,21],mean:[11,25,18,14,6,27,28,29,7,21,30],subset:28,domain:[19,28],resum:21,idea:[11,21,29,14],ensur:[19,18,14,6,29,21,30],idgener:0,consum:[18,14,6,27,29,21,9,30,10],contributor:[11,21,6,23,7,8,9],redistribut:[11,21,6,23,7,8,9],purposs:9,"static":[19,25,0,20,7,24],connect:[0,20,21,4,14,7,9,24],filter:28,agrup:10,recogn:27,happen:[11,0,20,6,28,29],ommit:8,extract:[4,0],event:[11,21,6,23,7,8,9],special:[11,21,6,23,7,8,9],out:[11,19,0,28,21,14,6,23,7,8,9],variabl:[20,6,8,1],subnet:[19,24],shown:[11,21,4,14,28,7,8,9],network:[19,24],item:[11,25,20,21,4,14,27,28,7,8,9,10],profit:[11,21,6,23,7,8,9],isprepar:20,develop:[22,6,15,16],callbacknam:4,publish:[20,21,14,6,29,8,9],content:[28,21,4,0,23],typenam:[11,7,0,30,8],adapt:15,rel:28,warante:[29,14,6,30],modifyus:[11,28],instati:[0,20],correct:[9,0],red:8,multilin:4,marek:11,shut:[21,9,14],sampleuserdeploymenttwo:[21,9,8],insid:[11,19,14,0,1,3,4,5,6,27,28,29,20,18,30,10],advanc:17,migrat:1,contain:[11,19,25,0,1,4,20,6,28,7,24],situat:[21,28,9,14,20],guess:7,standard:[11,28,4],ajax:28,unsupportedexcept:17,que:7,theori:[11,21,6,23,7,8,9],dictionari:[11,19,4,0,28],element:[11,0,20,3,4,14,21,28,7,8,18,9,10],put:[20,21,4,14,23,1,9,30],relat:[13,5],havent:9,debug:[21,7,6,1],basi:18,diretli:9,kept:[18,29,6],wai:[11,19,24,20,28,3,4,14,6,15,27,23,7,30,8,18,9,21,10],environmnet:0,launch:20,could:[11,29,6,8,20],insert:[4,6],synchron:[29,6],acomplish:[17,6],keep:[25,1,18,4,14,6,27,28,29,20,21,9,30,24],recov:[14,0,20],refresehd:11,length:[21,4,7,9],notifyreadyfromosmanag:14,isn:28,outsid:11,mortal:11,retain:[11,21,6,23,7,8,9],assign:[19,0,20,28,18,4,14,6,17,8,21,9,10],south:[12,1],first:[25,0,20,21,14,6,23,29,7,8,9,28],origin:[11,4],softwar:[11,12,21,6,23,7,8,9],major:16,suspend:[21,9,14,8],notifi:[21,9,6,14,20],directli:[20,21,4,14,6,28,29,9],onc:[0,1,4,14,6,28,30],arrai:[11,0,20,18,4,28,7],blagenta:8,kvm:[18,29,14,20],system:[27,23,0,8,28],oportunitii:28,updatedata:20,namagener:[21,9],done:[11,19,14,0,20,18,28,5,6,27,17,29,7,8,30,24],fast:[29,14,0,6,15],spanish:7,owner:[11,28,29],stabl:15,open:[27,10],size:23,prioriti:19,avail:[11,18,4,14,6,21,9],differ:[11,25,21,4,6,27,28,29,9],"long":6,script:11,guidescript:[4,0],unknown:28,top:7,storevalu:20,sometim:[29,6],messag:14,validateus:20,lognam:11,too:[12,1],time:[19,5,0,20,21,4,14,6,28,9],termin:20,conveni:0,externalsourc:28,"final":[18,14,20,10],store:[19,25,0,20,21,4,14,6,28,29,7,9,24],inner:28,datastore1:4,datastore0:4,gethtml:[11,28,20],accesori:28,apropi:23,real_nam:[19,28],copi:[18,4,14,6,27,29,21,9],getorcreateus:19,specifi:[11,19,25,0,28,4,17,24],sync:1,part:[11,1,3,4,14,27,28,7,8,21,9],assigneduserservic:20,thak:12,number:[11,0,28,21,4,14,6,27,17,8,9,10],textfield:[4,7,8],exactli:[27,21],removeus:28,than:[25,20,21,4,14,6,15,29,7,8],png:[11,0,3,23,7,8,10],wide:21,kind:[11,12,25,21,4,14,6,27,28,7,9,10],paremet:4,ben:9,target:4,keyword:14,whenev:[11,21,14,6,27,28,29,9],provid:[19,0,20,13,3,4,5,22,28,24,10],remov:[19,25,20,18,14,6,17,21,9,30,28],posibl:[0,6,20],tree:[21,14,27,7,9,10],structur:[18,29,14,30,28],enought:[7,15,8],project:5,matter:[21,4,9,14],"__init__":[11,0,28,3,14,6,23,29,7,8,18,30,10],reus:[21,14,8],sens:21,str:[21,7,9,6],"g\u00f3mez":[11,21,6,7,8,9],remod:[29,14],minut:20,descriptio:0,recheck:[21,9,6],sai:[11,21,14,28,7,9],abov:[11,21,6,23,7,8,9],ugettext:[11,0,21,14,6,29,7,8],cancheckuserpassword:28,arg:[19,25,0,20,18,4,14,28,7,30,24],mind:4,ani:[11,19,24,25,21,4,14,6,15,23,29,7,8,9,10],administart:0,modulevc:4,packag:[11,13,3,27,7,10],circust:14,have:[11,25,0,1,18,4,14,6,15,28,29,7,8,21,9,20,30],tabl:[25,1],need:[11,19,24,14,0,20,13,3,4,5,6,21,27,28,29,7,8,18,9,30,10],seen:6,django:[11,12,25,19,1,5,6,16,28,7,8,20,24],option:[11,27,4,0,20],reali:[21,9,14],usrdata:[11,28],"_str":0,engin:28,recreat:28,callback:[11,28,4],check:[11,19,0,20,21,4,14,6,28,29,7,8,9,24],destroi:[19,0,20,21,14,6,29,9,24],self:[11,0,18,4,14,6,28,29,7,8,21,9,30],sampleauthent:11,basegroup:28,searchus:[11,28],also:[11,12,0,20,21,4,14,6,15,16,28,7,8,9],exposit:0,take:[11,0,1,21,4,14,6,23,29,8,9,20,28],advis:[11,21,6,23,7,8,9],green:8,properti:[4,24],hook:[19,24,20],singl:[11,19,0,20,28,18,4,14,15,27,23,21,24],funcion:16,even:[11,28,21,6,23,29,7,8,9],transformusernam:28,unless:11,incorpor:15,assigntous:[21,9,14,20],shall:[11,21,6,23,7,8,9],usernam:[11,19,28,14,20],getcolour:[9,8],previou:[27,0],reach:[17,25,9,6,21],what:[11,0,3,4,14,6,27,28,7,8,21,9,30,10],strict:[11,21,6,23,7,8,9],divbacktologin:28,most:[11,1,21,4,14,6,27,28,7,9],render:[21,9,14,28],charl:12,letter:11,deploi:[20,21,14,6,27,29,8,9,10],phase:6,iconfil:[11,7,0,8],"class":[0,3,4,5,6,7,8,9,10,11,14,18,19,20,21,23,24,25,27,28,29,30],cachetooltip_l2:[18,8],requir:[11,4,7,9,8],althouth:15,dolog:14,don:[0,20,18,4,14,6,17,29,7,8,21,9,30,28],isexternalsourc:[11,28],url:[11,28],clear:[19,24,20],later:[21,14,6,15,27,29],cover:[21,4,22,16,27,7,8,9],userloggedin:[21,9,14],doe:[11,18,4,14,6,28,29,7,21,9,30],inde:15,dummi:[11,19,7,8],deni:11,declar:[0,18,4,6,27,29,8,30,10],snapshot:[17,29,9,21],place:[11,3,7,10],clean:[20,21,14,6,29,9],databas:13,jsch:12,globalconfig:20,passwordfield:[4,8],fact:[11,25,0,18,14,6,27,28,29,7,8,21,30],translat:[11,0,21,4,14,6,28,29,7,8],istyp:4,think:[11,20,4,14,15,30],shot:25,serializ:[13,22],show:[11,21,4,14,6,16,23,7,8,9],adolfo:[11,21,6,7,8,9],random:[11,21,6,7,8,9],checkpublishingst:29,python:[19,20,1,15,16,23,24],unprocess:28,permiss:[11,1,21,6,23,7,8,9],quad:24,uniquemacgener:[21,9,20],pki:28,fine:[28,7,0],find:[11,27,30,1],transport:[13,19,25,5,20],staff:19,xml:[12,4],unmarsh:[0,18,14,6,28,29,7,21,9,30],onli:[11,19,0,20,18,4,14,6,15,27,28,29,7,8,21,9,30,24],slow:[6,20],witch:[29,6],modnam:19,copyright:[11,12,21,6,23,7,8,9],holder:[11,21,6,23,7,8,9],explain:[21,7,9,14],configur:[25,0,20,1,6,27,7],activ:[19,28,20],enough:[21,29,9,6,22],start:[29,24,6,15,1],internacionaliz:[7,0],maxdeploi:8,authinfo:28,busi:[11,21,6,23,7,8,9],dict:[0,20],combo:[28,4],mytardi:16,folder:[11,0,1],spice:24,local:28,control:27,hope:[12,9,21],info:[19,14,20,21,4,5,6,27,28,9,24],move:[21,14,20],unus:[21,9],patter:11,getuniqueid:[21,9,14,20],removeorcancel:20,express:[11,21,6,23,7,8,9],stop:[29,1],proyect:15,ssl:4,acces:[21,9,20],expres:4,rest:[27,23,0,8],"import":[11,1,3,4,6,23,7,8,21,9,10],report:12,liabl:[11,21,6,23,7,8,9],getip:[21,9,14],dictvalu:7,neither:[11,21,6,23,7,8,9],restart:1,dirti:0,inbase64:0,methag:7,bat:8,valuesdict:0,enabl:28,administ:[11,21,4,9,14],darkglass:12,getbasenam:[21,9,6,8],probabl:[11,0,20,21,4,14,9],suggestedtim:[21,9,6,14],"public":[25,20,13,4,22,17,28,10],typetyp:[11,7,0,30,8],twice:11,bad:[11,21,0],stuff:[18,4,14,6,27,28,29,30],common:[7,30,10],codec:0,umnarsh:6,"__init___":14,inputfield:4,movement:14,where:[11,1,28,3,4,20,6,27,23,29,7,18,10],appart:28,view:28,user:[11,19,0,20,13,3,4,14,29,27,17,28,18,24,30,10],altern:28,btw:1,set:[11,0,1,21,4,14,6,28,29,8,20],getvalidgroup:28,our:[11,21,6,27,28,7,8,9],job:25,still:7,markolduserservicesasremov:20,displai:[21,4,9,14,28],sso:[11,28],see:[0,1,18,14,6,15,28,29,7,8,21,9,20,30],num:4,sec:20,result:[28,19,4,0,24],respons:[11,0,1,3,28,14,6,21,23,29,20,18,9,10],fail:[21,7,9,6,14],ldap:[11,19,28,1],simpl:[11,0,1,21,4,6,28,29,7,8,9],deployedservic:[27,20],nonstandard:28,best:[3,7,10],deployedservicepubl:20,jqueri:[12,28],iplist:4,detect:12,kei:[21,28,9,0,20],correctli:[0,18,14,6,28,29,21,30],redirect:[11,28,20],down:[21,4,9,14],pattern:[11,28],someth:[19,0,18,14,6,15,27,28,29,7,21,9],nebula:[27,10],autosav:7,id_us:[11,28],behind:[11,29,14],won:1,groupnam:28,progress:0,efect:6,operationexcept:17,dissapear:11,mynam:11,tux:7,parent:[18,4,14,29,7,8],betwen:20,numer:[21,4,29,7,9,24],groupmanag:28,exampl:[11,19,25,0,20,18,4,14,6,28,29,7,8,21,9,30],javascript:[11,28],focus:15,incident:[11,21,6,23,7,8,9],len:11,getmachin:4,optional:0,problem:[11,18,28,20],getrealnam:28,both:[29,4,6,20],wsgi:16,hiddenfield:4,instant:14,easi:[11,28,4,0,15],cow:[27,18,29,14,6],cachetooltip:[18,8],admin:[11,19,21,4,14,28,7,8,10],howev:[11,21,6,23,7,8,9],menu:11,istru:[4,7],contract:[11,21,6,23,7,8,9],tempor:[7,0],etc:[11,19,25,20,21,6,17,29,7,9,24],capabl:0,instanc:[19,25,0,20,18,4,14,6,27,28,29,7,21,9,24],agent:8,ovirt:27,default_length:4,improv:12,login:[11,19,28],whole:27,load:[25,0,18,14,6,29,21,30],onward:[7,8],simpli:[11,0,1,21,4,14,6,15,27,23,29,7,8,9,20,28],isvalidus:19,instanti:[19,0,20,21,4,6,7,9,24],overview:12,internalauthent:28,realnam:[11,19,28],dispatch:28,"__class__":[18,29,14,28],modif:[11,21,4,6,23,7,8,9],rpc:[12,4],written:[11,21,6,23,7,8,9],exemplari:[11,21,6,23,7,8,9],reasonoferror:[21,29,9,6,14],suppli:28,cancel:[20,21,14,6,17,29,9],user2:4,guid:[15,8],assum:8,panel:[7,8],damag:[11,21,6,23,7,8,9],deployeduserservic:20,better:[8,20],ultim:[21,9],java:1,userservic:[19,20],coupl:14,nonsens:[0,8],addition:4,come:[11,28,7,0,14],user1:[28,4],oder:7,choice1:4,empti:[19,0,20,21,4,28,7,9,24],mark:[11,19,20,21,28,7,8],compon:22,trie:9,much:[28,4,14,1],besid:21,treat:[21,4,9,8],petit:[11,28,1],dependad:14,getgroupsnam:11,dkmon:[11,21,6,7,8,9],isrestrain:20,userdeploy:[13,4,20,22,10],clase:[7,4,5,0,25],removegroup:28,allo:28,cachelevel:[21,14,20],imag:0,persist:[25,5,0,9,20],worker:[13,5],search:[11,28],argument:18,deployforus:[21,9,14],understand:[11,12,20,3,14,15,28,10],osmanag:[29,14],child:[0,30,20],getmanag:19,rang:[11,21,7,9,6],spin:4,hidden:[28,4],present:[21,4,9,14],rdp:24,"case":[11,19,0,20,18,14,6,23,29,7,8,21,9,30,28],ugli:11,multi:[4,14],look:[28,3,14,23,8,21,9,30,10],networksfor:24,raw:0,replac:11,plain:28,setinus:20,plugin:[12,22,28],permit:[11,21,6,23,7,8,9],getservicebytyp:30,alter:4,trick:0,defin:[11,19,4,6,28,29,8],"while":[21,9,6,14,1],facil:11,none:[11,19,0,20,18,14,28,29,7,8,21,9,30,24],error:[0,20,21,14,6,28,29,7,9],updatelastaccess:19,invoc:4,document:[11,21,14,6,23,7,8,9],getuserassignedservic:20,increment:[21,4,9],helper:28,almost:[21,4,14,8,28],generat:6,setreadi:[21,9,14],site:11,setip:[21,9,14],attribut:[0,18,14,6,28,29,21,30],netrang:24,cant:6,kwarg:[19,25,20,18,14,29,24],eras:[21,7,9,14,28],ready:[21,14],limit:[11,21,5,6,23,7,8,9],revis:[29,15],formfield:7,sever:27,around:27,oper:[0,20,21,14,6,17,29,9],queue:6,acess:[0,16],numericfield:[4,7],let:[21,4,14,0,28],descent:27,minim:21,apear:4,suggest:6,make:[11,12,20,21,4,14,6,15,27,29,9,30],belong:[11,27,28,20],same:[11,19,0,28,21,4,14,6,27,23,8,10],data:[11,19,24,0,20,28,18,4,14,6,23,29,7,8,21,9,30,10],member:19,binari:[11,1,21,6,23,7,8,9],html:[11,28],interact:[4,14,0],split:[21,6],onclick:11,falseifnotexist:19,dbuser:28,shedul:25,userinterfac:[13,22],processuserpassword:20,week:15,ghui:4,http:16,hostnam:20,imagin:[11,21,29,9,14],logic:[3,29,14,28],compos:[27,3,10],someon:28,hand:11,ralli:7,remot:7,moment:[21,9,14],rais:[11,19,20,14,28,29,7,8,24],temporari:7,initi:[11,0,1,18,4,14,6,15,23,29,7,8,21,9,20,30,28],multichoicefield:4,mani:4,extern:[28,6],"a\u00f1o":7,netstart:24,chang:[0,20,18,14,6,21,1],sampleservic:7,built:16,memori:[18,29,14,30,1],ofc:[11,14],lower:11,task:[25,20,21,14,6,29,7,9],off:[21,9,14],invalidserviceexcept:[17,20],scenario:21,older:7,unserializeform:0,methyear:7,thu:16,randint:[21,9,6],well:[11,18,27,7,6],normali:14,inherit:[4,7],non:[17,14,8,19],virtual:[11,20,21,14,6,15,27,23,29,7,8,9,30],client:[11,7,0,8],invoqu:20,thi:[0,1,18,4,5,6,7,8,9,10,11,12,14,15,16,19,20,21,23,24,25,27,28,29,30],ouwn:11,iscustom:28,everyth:[12,1],loss:[11,21,6,23,7,8,9],gettyp:[19,24,20],usual:[19,4],explan:4,comment:[11,28,8],serviceon:[7,8],protocol:[30,15],getforauth:28,just:[11,25,0,20,21,14,6,27,28,29,7,8,9,24],less:[14,15],getconnectionsourc:20,modular:27,getusernameforauth:19,reserv:[11,21,6,23,7,8,9],groupdata:28,interrupt:[11,21,6,23,7,8,9],caugth:7,generatorid:0,erroneoususerservic:20,mehod:6,human:0,mysql:[16,1],elect:23,methal:7,thees:[27,0],yet:14,languag:[21,29,14],wether:9,note:[11,19,0,20,21,14,6,28,29,7,8,9,30,24],like:[0,21,14,15,27,29,7,9],struct:4,expos:23,field:[19,0,20,13,22,24],samplepubl:[6,8],serializbl:9,getinfo:28,drawback:0,param:[19,0,20,18,28,7,8,21,9],credentila:28,add:[19,28,7,21],setenv:0,purpus:[19,24,20],schedul:[13,5],reason:[21,14,6,17,29,9],input:[11,28,4],logger:[11,21,6,7,8,9],save:[29,25,7,6,20],getgroup:[11,28],match:[11,28,1],build:[12,16],real:[11,20,21,14,28,9],applic:1,sampleauth:11,which:[11,18,4,14,16,27,28,29,21,9,30],retunr:6,format:[11,0,21,6,27,23,7,24],read:[4,0,15],big:28,activepub:20,credit:12,futur:[18,28,21,8,20],spreadli:22,alias:28,five:[21,9],know:[11,20,21,14,6,17,7,9,28],background:[13,5],usescache_l2:[18,8],bit:[11,7,6],password:[11,20,4,1,28,8],associ:[19,0,20,21,14,28,29,9,24],identifi:[11,0,21,14,28,7,8,9],mod:[21,9,14],linux:[21,9,14],colour:[23,8],daemon:11,"_error":21,success:28,anyon:[21,22,15],manual:[11,28,20,10],integ:[4,6],noth:[11,0,20,18,14,28,29,7,8,21,9,30],isus:20,collect:18,dbservic:14,servicetwo:[7,8],likt:6,getservicestyp:30,bunch:[6,20],output:[28,4,7,8],record:[19,25,24,21,20],manag:[11,19,25,14,0,1,21,4,5,6,27,28,29,8,9,20],implemet:0,revers:0,nede:[18,9,14,30,21],who:[15,10],cabl:[11,21,6,23,7,8,9],throuht:28,dsname:29,fake:11,some:[11,19,20,21,28,14,6,15,17,7,9,10],back:[21,4,14,28],certain:25,thread:6,intern:[11,0,18,14,28,29,7,8,21,30],repeat:[11,18,14],sampl:[19,13,3,4,14,22,28,29,18,24,30,10],refresh:[11,28],envirn:20,indirect:[11,21,6,23,7,8,9],server:[19,1,4,20,6,15,27,23,7,30,10],librari:[12,1],distribut:[11,21,6,23,7,8,9],basic:[11,0,21,22,16,27,28,7,8,30],sampleserviceon:9,movetocach:[21,14],except:[19,0,20,13,22,28,24,10],pet:7,avoid:[11,18,20],deploy:[13,18,14,27,17,10],definit:[11,0,18,27,7,10],deployforcach:[21,9,14],"16x16":[3,23,10],passwd:8,substitut:[11,21,6,23,7,8,9],equal:11,leav:[21,29,9],serviceprovid:[7,30],leat:11,xxxxxx:4,rdbm:16,backend:1,reproduc:[11,21,6,23,7,8,9],hopefulli:[12,0],getnam:[21,9,14,8,20],freed:[21,9],machin:[0,20,18,4,14,6,27,29,8,21,9],plu:11,object:[19,25,0,20,18,4,14,28,29,21,9,30,24],run:[0,1,21,14,6,17,29,8,9],"matusal\u00e9n":7,power:[21,9,14],liabil:[11,21,6,23,7,8,9],unmash:[18,30],imposs:[21,9,14],obtain:[19,0,1,4,14,28,7,20,24],broker:[21,9],els:[21,9,6,14,16],mustassignmanu:8,vdi:15,step:[21,29,9,6,14],promot:[11,21,6,23,7,8,9],although:18,found:[19,28],"__name__":[11,21,6,7,8,9],post:28,servicemanag:25,"super":[18,14,28,29,8,30],between:[29,6,20],cannont:14,stage:[27,21,14],plug:27,about:[11,12,14,0,21,4,5,27,28,7,8,9,30],tien:7,actual:[21,14],meth:[11,14,6,28,29,7],valid:[11,19,24,0,20,3,4,25,28,8,21,9,10],anythinh:12,materi:[11,21,6,23,7,8,9],requestservicesforassign:18,label:[11,4,7,8],greater:4,in_us:20,secion:27,includ:[11,28,3,4,14,6,27,23,7,8,21,9,10],constructor:[19,0,20,18,4,14,28,29,30,24],dkmaster:[11,21,6,7,8,9],getpassw:8,valuat:4,marshal:[0,18,14,6,29,7,21,9,30],block:[19,29,6,20],compil:1,mac:[25,20,18,4,14,21,9],basenam:8,poblic:27,encod:[21,0],functional:[21,14],alredi:[21,9],getenviron:[19,25,24,20],warranti:[11,21,6,23,7,8,9],right:[11,12,14,0,20,21,28,5,6,23,7,8,9,24],sampleprovid:[23,7],been:[11,28,18,14,15,16,17,29,8,21,9,30,24],tricki:11,oportun:[11,0,21,14,6,9],old:[21,7],unmarshal:0,your:[11,1,3,28,14,15,23,29,7,30,8,18,21,10],click:11,implic:28,rdonli:4,val:[11,6],few:[11,18,7,6,28],uniquenamegener:[21,9,20],support:[4,14,16,27,17,10],cacheduserservic:20,defvalu:[4,7,8],transform:[19,28,0,20],submit:11,custom:[18,28,20,10],god:11,etcc:4,deloi:[8,20],window:[11,21,9,14],interfac:[0,13,3,4,22,10],editor:11,lot:15,needsmanag:8,"var":[29,0,6],constantli:1,"_reason":6,ipv4:24,fase:20,"function":[28,4,5,29,20],head:0,creation:[28,4,14,8,1],sampleservice2:8,sampleservice1:8,offer:[27,18,7,30,20],tupl:28,last:[19,20,10],criteria:11,jun:7,continu:14,validforip:24,state:[11,19,20,21,14,6,28,29,9],link:28,low:21,authcallback:[11,28],musht:6,drawn:11,realli:[21,14,6,27,29,7,8,9],"true":[11,19,0,20,18,4,28,7,8,24],arquicetur:16,congratul:[7,8],faster:[14,8],count:[21,9],"_number":6,rememb:[0,18,14,6,28,7,8,21,9,30],utf:[11,21,6,23,7,8,9],cleanup:25,consist:20,possibl:[11,21,14,6,23,7,8,9],whether:[11,21,14,6,23,7,8,9],warrante:18,caller:19,maximum:17,mustassignmanuali:18,inplement:9,asynchron:[29,6],crystal:12,below:[4,6,10],"_mac":21,sent:[11,7,14],otherwis:[11,19,21,6,23,7,8,9],inform:[24,0,25,28,18,14,6,22,23,8,21,9,30,10],ascii_uppercas:6,display:4,expect:[21,4,14,28,29,9],editablelist:[11,4,8],model:13,user4:4,featur:7,constant:14,user3:4,icon:[11,0,3,23,7,8,10],createus:[11,28],"int":[21,9,6],wich:28,year:7,bebito:4,doesn:[19,14],repres:[11,19,25,0,20,18,4,14,28,29,7,24,30,10],"char":[4,0],publishexcept:17,exist:[19,0,21,4,14,28,9],aliv:7,file:[11,0,1,3,4,6,23,7,8,24,10],behavior:[18,6,28],request:[11,0,20,21,4,14,6,17,29,7,9,28],"_ip":21,inact:[11,28],fill:[11,0,18,4,14,28,29,8,30],notif:[21,14,28],again:[18,14,6,28,29,21,9,30],readi:[20,21,14,17,29,1,9],wast:1,moduleauthor:[11,21,6,7,8,9],movecach:14,usescach:8,contact:15,creat:[11,19,24,1,28,3,4,14,6,27,17,29,7,20,21,9,30,10],when:[11,25,0,20,18,4,14,6,28,29,7,8,21,9,30],detail:[18,4,14,29,30],actor:[21,9,14,8],intanc:6,"default":[11,19,0,1,18,4,14,6,15,28,29,7,8,21,9,20,30],finish:[20,21,14,6,29,9],other:[13,5],excet:9,unl:11,normal:[18,14,28,29,7,21,30],writabl:4,beforedelet:[19,25,24,20],you:[11,14,0,1,28,3,4,5,6,15,27,23,29,7,30,8,18,9,21,10],test:[0,1,21,4,6,15,16,28,7,8,9,24],architectur:22,deseri:[25,0,18,14,6,29,30],draw:[11,28],exatli:27,intend:[28,25,0,30,1],setdefvalu:4,specidi:20,maxservicesreachedexcept:17,why:[29,6],decod:[21,0],consequenti:[11,21,6,23,7,8,9],push:7,dircetli:[21,14],releas:[21,9,14],track:[28,20,6,1],log:[11,19,21,14,6,28,7,8,9],consid:[28,20],sql:19,previous:0,infourl:28,fncvalu:4,pool:[21,4],needspassword:11,reduc:20,"_count":21,receiv:[11,0,21,4,14,28,8,9],haven:[18,29,14,30,21],overri:30,directori:19,descript:[11,0,21,4,7,8],involv:12,dbauthent:[11,28],newlevel:[21,14],text:[11,28,4,0],obj:0,scare:1,checkstat:[21,29,9,6,14],datetim:6,readdata:9,getlogg:[11,21,6,7,8,9],"8th":4},objtypes:{"0":"py:module","1":"py:method","2":"py:exception","3":"py:class","4":"py:staticmethod","5":"py:classmethod","6":"py:attribute"},objnames:{"0":["py","module","Python module"],"1":["py","method","Python method"],"2":["py","exception","Python exception"],"3":["py","class","Python class"],"4":["py","staticmethod","Python static method"],"5":["py","classmethod","Python class method"],"6":["py","attribute","Python attribute"]},filenames:["api/modules/BaseModule","intro/install","development/repository","api/modules/AuthenticatorModule","api/modules/FormFields","api/models","development/samples/services/Publication","development/samples/services/Provider","development/samples/services/Service","development/samples/services/DeployedServiceOne","api/modules/ServiceModules","development/samples/auths/Authenticator","index","api/index","api/modules/services/UserDeployment","intro/overview","development/architecture","api/modules/services/Exceptions","api/modules/services/Service","api/models/authentication","api/models/services","development/samples/services/DeployedServiceTwo","api/modules","development/samples/services/whatisneeded","api/models/transport","api/models/other","development/contributing","development/samples/samples","api/modules/auths/Authenticator","api/modules/services/Publication","api/modules/services/Provider"],titles:["Base Module","Installing UDS","UDS Repository","Authenticator Modules","Form Fields","UDS Database Models","Sample publication","Sample Service Provider","Sample service","Sample User Deployment One","Service Modules","Sample Authenticator","UDS’s documentation","UDS’s core API","UserDeployment interface","UDS at a glance","UDS’s architecture","Service Exceptions","Service interface","Authentication Related models","Service Related models","Sample User Deployment Two","UDS Modules","Needs for a service package","Transport Related models","Other models","Contributing to UDS","UDS Modules Samples","Authenticator Interface","Publication interface","Provider interface"],objects:{"uds.models.User":{prefs:[19,1,1,""],getUsernameForAuth:[19,1,1,""],beforeDelete:[19,4,1,""],isStaff:[19,1,1,""],updateLastAccess:[19,1,1,""],logout:[19,1,1,""],getManager:[19,1,1,""]},"uds.core.auths.Authenticator":{Group:[28,3,1,""],getForAuth:[28,1,1,""],canCheckUserPassword:[28,5,1,""],modifyGroup:[28,1,1,""],userType:[28,6,1,""],getRealName:[28,1,1,""],removeUser:[28,1,1,""],internalAuthenticate:[28,1,1,""],getGroups:[28,1,1,""],infoUrl:[28,1,1,""],removeGroup:[28,1,1,""],authenticate:[28,1,1,""],getHtml:[28,1,1,""],recreateGroups:[28,1,1,""],User:[28,3,1,""],authCallback:[28,1,1,""],groupType:[28,6,1,""],modifyUser:[28,1,1,""],transformUsername:[28,1,1,""],dbAuthenticator:[28,1,1,""],logout:[28,1,1,""],createUser:[28,1,1,""],initialize:[28,1,1,""],isCustom:[28,5,1,""],searchGroups:[28,1,1,""],searchUsers:[28,1,1,""],getInfo:[28,1,1,""],createGroup:[28,1,1,""],callbackUrl:[28,1,1,""]},"uds.core.services.Publication":{osManager:[29,1,1,""],finish:[29,1,1,""],service:[29,1,1,""],dsName:[29,1,1,""],reasonOfError:[29,1,1,""],cancel:[29,1,1,""],checkState:[29,1,1,""],publish:[29,1,1,""],initialize:[29,1,1,""],destroy:[29,1,1,""],revision:[29,1,1,""]},"uds.core.services.ServiceProvider":{initialize:[30,1,1,""],getServiceByType:[30,5,1,""],getServicesTypes:[30,5,1,""]},"uds.core.auths.Authenticator.Group":{dbGroup:[28,1,1,""],manager:[28,1,1,""]},"uds.models.UserService":{isReady:[20,1,1,""],removeOrCancel:[20,1,1,""],recoverValue:[20,1,1,""],cancel:[20,1,1,""],setState:[20,1,1,""],getConnectionSource:[20,1,1,""],getUniqueId:[20,1,1,""],getInstance:[20,1,1,""],setInUse:[20,1,1,""],processUserPassword:[20,1,1,""],beforeDelete:[20,4,1,""],assignToUser:[20,1,1,""],getUserAssignedServices:[20,4,1,""],isPreparing:[20,1,1,""],setConnectionSource:[20,1,1,""],storeValue:[20,1,1,""],getEnvironment:[20,1,1,""],moveToLevel:[20,1,1,""],remove:[20,1,1,""],updateData:[20,1,1,""],isUsable:[20,1,1,""],transformsUserOrPasswordForService:[20,1,1,""],getName:[20,1,1,""],setOsState:[20,1,1,""]},"uds.core.ui.UserInterface":{gui:[4,3,1,""],UserInterface:[0,3,1,""]},"uds.core.services.Exceptions":{DeploymentException:[17,2,1,""],UnsupportedException:[17,2,1,""],OperationException:[17,2,1,""],CancelException:[17,2,1,""],MaxServicesReachedException:[17,2,1,""],InvalidServiceException:[17,2,1,""],PublishException:[17,2,1,""]},"uds.models.Cache":{cleanUp:[25,4,1,""]},"uds.models.DeployedService":{storeValue:[20,1,1,""],getEnvironment:[20,1,1,""],markOldUserServicesAsRemovables:[20,1,1,""],validateUser:[20,1,1,""],recoverValue:[20,1,1,""],remove:[20,1,1,""],processUserPassword:[20,1,1,""],unpublish:[20,1,1,""],isRestrained:[20,1,1,""],beforeDelete:[20,4,1,""],publish:[20,1,1,""],erroneousUserServices:[20,1,1,""],getDeployedServicesForGroups:[20,4,1,""],activePublication:[20,1,1,""],assignedUserServices:[20,1,1,""],removed:[20,1,1,""],cachedUserServices:[20,1,1,""],setState:[20,1,1,""]},"uds.core.auths.Authenticator.User":{dbUser:[28,1,1,""],manager:[28,1,1,""],groups:[28,1,1,""]},"uds.models.DeployedServicePublication":{getEnvironment:[20,1,1,""],getInstance:[20,1,1,""],unpublish:[20,1,1,""],updateData:[20,1,1,""],beforeDelete:[20,4,1,""],cancel:[20,1,1,""],setState:[20,1,1,""]},"uds.core.ui.UserInterface.gui.MultiChoiceField":{setValues:[4,1,1,""]},"uds.core":{services:[14,0,0,"-"],auths:[28,0,0,"-"],Environmentable:[0,3,1,""],Serializable:[0,3,1,""],Module:[0,3,1,""]},"uds.core.Environmentable":{storage:[0,1,1,""],cache:[0,1,1,""],setEnv:[0,1,1,""],idGenerators:[0,1,1,""],env:[0,1,1,""]},"uds.core.Serializable":{serialize:[0,1,1,""],unmarshal:[0,1,1,""],marshal:[0,1,1,""],unserialize:[0,1,1,""]},uds:{models:[24,0,0,"-"],core:[0,0,0,"-"]},"uds.core.ui.UserInterface.gui.InputField":{guiDescription:[4,1,1,""],defValue:[4,6,1,""],isType:[4,1,1,""],value:[4,6,1,""],setDefValue:[4,1,1,""]},"uds.core.ui.UserInterface.gui.ChoiceField":{setValues:[4,1,1,""]},"uds.core.services":{Exceptions:[17,0,0,"-"],ServiceProvider:[30,3,1,""],UserDeployment:[14,3,1,""],Publication:[29,3,1,""],Service:[18,3,1,""]},"uds.models":{Config:[25,3,1,""],Group:[19,3,1,""],Scheduler:[25,3,1,""],Service:[20,3,1,""],UserPreference:[19,3,1,""],DelayedTask:[25,3,1,""],Cache:[25,3,1,""],Storage:[25,3,1,""],Authenticator:[19,3,1,""],DeployedServicePublication:[20,3,1,""],User:[19,3,1,""],UniqueId:[25,3,1,""],Provider:[20,3,1,""],UserService:[20,3,1,""],DeployedService:[20,3,1,""],Transport:[24,3,1,""],Network:[24,3,1,""]},"uds.models.Transport":{getEnvironment:[24,1,1,""],validForIp:[24,1,1,""],getType:[24,1,1,""],beforeDelete:[24,4,1,""],getInstance:[24,1,1,""]},"uds.models.Authenticator":{getEnvironment:[19,1,1,""],all:[19,4,1,""],getOrCreateUser:[19,1,1,""],getInstance:[19,1,1,""],getType:[19,1,1,""],beforeDelete:[19,4,1,""],isValidUser:[19,1,1,""]},"uds.core.services.UserDeployment":{osmanager:[14,1,1,""],dbservice:[14,1,1,""],setIp:[14,1,1,""],cancel:[14,1,1,""],moveToCache:[14,1,1,""],getUniqueId:[14,1,1,""],notifyReadyFromOsManager:[14,1,1,""],publication:[14,1,1,""],service:[14,1,1,""],doLog:[14,1,1,""],getName:[14,1,1,""],nameGenerator:[14,1,1,""],destroy:[14,1,1,""],getIp:[14,1,1,""],assignToUser:[14,1,1,""],setReady:[14,1,1,""],deployForCache:[14,1,1,""],finish:[14,1,1,""],initialize:[14,1,1,""],userLoggedOut:[14,1,1,""],macGenerator:[14,1,1,""],reasonOfError:[14,1,1,""],checkState:[14,1,1,""],userLoggedIn:[14,1,1,""],deployForUser:[14,1,1,""]},"uds.core.ui":{UserInterface:[4,0,0,"-"]},"uds.models.Group":{getManager:[19,1,1,""],beforeDelete:[19,4,1,""]},"uds.models.Scheduler":{getEnvironment:[25,1,1,""],beforeDelete:[25,4,1,""],getInstance:[25,1,1,""]},"uds.core.services.Service":{initialize:[18,1,1,""],macGenerator:[18,1,1,""],nameGenerator:[18,1,1,""],parent:[18,1,1,""],requestServicesForAssignation:[18,1,1,""]},"uds.models.Provider":{getEnvironment:[20,1,1,""],beforeDelete:[20,4,1,""],getInstance:[20,1,1,""]},"uds.models.Service":{getEnvironment:[20,1,1,""],getType:[20,1,1,""],beforeDelete:[20,4,1,""],getInstance:[20,1,1,""]},"uds.core.ui.UserInterface.gui.CheckBoxField":{isTrue:[4,1,1,""]},"uds.core.Module":{name:[0,5,1,""],unmarshal:[0,1,1,""],description:[0,5,1,""],check:[0,1,1,""],ValidationException:[0,2,1,""],test:[0,4,1,""],destroy:[0,1,1,""],isDirty:[0,1,1,""],type:[0,5,1,""],marshal:[0,1,1,""],icon:[0,5,1,""]},"uds.core.ui.UserInterface.UserInterface":{initGui:[0,1,1,""],unserializeForm:[0,1,1,""],guiDescription:[0,5,1,""],valuesDict:[0,1,1,""],serializeForm:[0,1,1,""]},"uds.core.ui.UserInterface.gui.NumericField":{num:[4,1,1,""]},"uds.core.auths":{Authenticator:[28,3,1,""]},"uds.models.Network":{create:[24,4,1,""],netStart:[24,6,1,""],networksFor:[24,4,1,""],netEnd:[24,6,1,""],update:[24,1,1,""]},"uds.core.ui.UserInterface.gui":{EditableList:[4,3,1,""],InputField:[4,3,1,""],HiddenField:[4,3,1,""],ChoiceField:[4,3,1,""],CheckBoxField:[4,3,1,""],MultiChoiceField:[4,3,1,""],TextField:[4,3,1,""],NumericField:[4,3,1,""],PasswordField:[4,3,1,""]}},titleterms:{serializ:0,acknowledg:12,modul:[25,0,3,22,27,10],except:17,packag:23,intern:12,api:13,sampl:[11,21,6,27,7,8,9],authent:[11,3,27,28,19],glanc:15,need:23,instal:1,open:12,transport:24,compon:16,basemodul:0,databas:5,two:21,environment:0,field:4,other:25,interfac:[18,29,14,30,28],schedul:25,document:12,userinterfac:0,architectur:16,"function":16,core:13,userdeploy:14,sourc:12,contribut:26,form:4,deploy:[21,9],relat:[19,25,24,20],worker:25,step:12,base:0,user:[21,9],repositori:2,provid:[7,30],servic:[23,20,18,27,17,7,8,10],background:25,"public":[29,6],project:12,environ:25,model:[19,24,5,25,20],first:12}}) \ No newline at end of file diff --git a/server/documentation/_downloads/samples/auths/SampleAuth.py b/server/documentation/_downloads/samples/auths/SampleAuth.py deleted file mode 100644 index 7b3699b8..00000000 --- a/server/documentation/_downloads/samples/auths/SampleAuth.py +++ /dev/null @@ -1,307 +0,0 @@ -# -*- coding: utf-8 -*- - -# -# Copyright (c) 2012 Virtual Cable S.L. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of Virtual Cable S.L. nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -''' -.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com -''' -from django.utils.translation import ugettext_noop as translatable -from uds.core.ui.UserInterface import gui -from uds.core import auths - -import logging - -logger = logging.getLogger(__name__) - -class SampleAuth(auths.Authenticator): - ''' - This class represents a sample authenticator. - - As this, it will provide: - * The authenticator functionality - * 3 Groups, "Mortals", "Gods" and "Daemons", just random group names selected.. :-), - plus groups that we enter at Authenticator form, from admin interface. - * Search of groups (inside the 3 groups used in this sample plus entered) - * Search for people (will return the search string + 000...999 as usernames) - * The Required form description for administration interface, so admins can create - new authenticators of this kind. - - In this sample, we will provide a simple standard auth, with owner drawn - login form that will simply show users that has been created and allow web user - to select one of them. - - For this class to get visible at administration client as a authenticator type, - we MUST register it at package __init__ - - :note: At class level, the translations must be simply marked as so - using ugettext_noop. This is done in this way because we will translate - the string when it is sent to the administration client. - ''' - - #: Name of type, used at administration interface to identify this - #: authenticator (i.e. LDAP, SAML, ...) - #: This string will be translated when provided to admin interface - #: using ugettext, so you can mark it as "translatable" at derived classes (using ugettext_noop) - #: if you want so it can be translated. - typeName = translatable('Sample Authenticator') - - #: Name of type used by Managers to identify this type of service - #: We could have used here the Class name, but we decided that the - #: module implementator will be the one that will provide a name that - #: will relation the class (type) and that name. - typeType = 'SampleAuthenticator' - - #: Description shown at administration level for this authenticator. - #: This string will be translated when provided to admin interface - #: using ugettext, so you can mark it as "translatable" at derived classes (using ugettext_noop) - #: if you want so it can be translated. - typeDescription = translatable('Sample dummy authenticator') - - - #: Icon file, used to represent this authenticator at administration interface - #: This file should be at same folder as this class is, except if you provide - #: your own :py:meth:uds.core.BaseModule.BaseModule.icon method. - iconFile = 'auth.png' - - #: Mark this authenticator as that the users comes from outside the UDS - #: database, that are most authenticator (except Internal DB) - #: True is the default value, so we do not need it in fact - # isExternalSource = True - - #: If we need to enter the password for this user when creating a new - #: user at administration interface. Used basically by internal authenticator. - #: False is the default value, so this is not needed in fact - #: needsPassword = False - - #: Label for username field, shown at administration interface user form. - userNameLabel = translatable('Fake User') - - # Label for group field, shown at administration interface user form. - groupNameLabel = translatable('Fake Group') - - #: Definition of this type of authenticator form - #: We will define a simple form where we will use a simple - #: list editor to allow entering a few group names - - groups = gui.EditableList(label=translatable('Groups'), values = ['Gods', 'Daemons', 'Mortals']) - - def initialize(self, values): - ''' - Simply check if we have - at least one group in the list - ''' - - # To avoid problems, we only check data if values are passed - # If values are not passed in, form data will only be available after - # unserialization, and at this point all will be default values - # so self.groups.value will be [] - if values is not None and len(self.groups.value) < 2: - raise auths.Authenticator.ValidationException(translatable('We need more that two items!')) - - def searchUsers(self, pattern): - ''' - Here we will receive a pattern for searching users. - - This method is invoked from interface, so an administrator can search users. - - If we do not provide this method, the authenticator will not provide search - facility for users. In our case, we will simply return a list of users - (array of dictionaries with ids and names) with the pattern plus 1..10 - ''' - return [ { 'id' : '{0}-{1}'.format(pattern, a), 'name' : '{0} number {1}'.format(pattern, a) } for a in range(1, 10)] - - def searchGroups(self, pattern): - ''' - Here we we will receive a patter for searching groups. - - In this sample, we will try to locate elements that where entered at - sample authenticator form (when created), and return the ones that - contains the pattern indicated. - ''' - pattern = pattern.lower() - res = [] - for g in self.groups.value: - if g.lower().find(pattern) != -1: - res.append({'id' : g, 'name' : ''}) - return res - - def authenticate(self, username, credentials, groupsManager): - ''' - This method is invoked by UDS whenever it needs an user to be authenticated. - It is used from web interface, but also from administration interface to - check credentials and access of user. - - The tricky part of this method is the groupsManager, but it's easy to - understand what is used it for. - - Imagine some authenticator, for example, an LDAP. It has its users, it has - its groups, and it has it relations (which user belongs to which group). - - Now think about UDS. UDS know nothing about this, it only knows what - the administator has entered at admin interface (groups mainly, but he can - create users also). - - UDS knows about this groups, but we need to relation those with the ones - know by the authenticator. - - To do this, we have created a simple mechanism, where the authenticator - receives a groupsManager, that knows all groups known by UDS, and has - the method so the authenticator can say, for the username being validated, - to which uds groups it belongs to. - - This is done using the :py:meth:uds.core.auths.GroupsManager.GroupsManager.validate - method of the provided groups manager. - - At return, UDS will do two things: - * If there is no group inside the groupsManager mareked as valid, it will - denied access. - * If there is some groups marked as valid, it will refresh the known - UDS relations (this means that the database will be refresehd so the user - has valid groups). - - This also means that the group membership is only checked at user login (well, - in fact its also checked when an administrator tries to modify an user) - - So, authenticate must not also validate the user credentials, but also - indicate the group membership of this user inside UDS. - - :note: groupsManager is an in/out parameter - ''' - if username != credentials: # All users with same username and password are allowed - return False - - # Now the tricky part. We will make this user belong to groups that contains at leat - # two letters equals to the groups names known by UDS - # For this, we will ask the groups manager for the groups names, and will check that and, - # if the user match this criteria, will mark that group as valid - for g in groupsManager.getGroupsNames(): - if len(set(g.lower()).intersection(username.lower())) >= 2: - groupsManager.validate(g) - - return True - - def getGroups(self, username, groupsManager): - ''' - As with authenticator part related to groupsManager, this - method will fill the groups to which the specified username belongs to. - - We have to fill up groupsManager from two different places, so it's not - a bad idea to make a method that get the "real" authenticator groups and - them simply call to :py:meth:uds.core.auths.GroupsManager.GroupsManager.validate - - In our case, we simply repeat the process that we also do at authenticate - ''' - for g in groupsManager.getGroupsNames(): - if len(set(g.lower()).intersection(username.lower())) >= 2: - groupsManager.validate(g) - - def getHtml(self, request): - ''' - If we override this method from the base one, we are telling UDS - that we want to draw our own authenticator. - - This way, we can do whataver we want here (for example redirect to a site - for a single sign on) generation our ouwn html (and javascript ofc). - - ''' - # Here there is a sample, commented out - # In this sample, we will make a list of valid users, and when clicked, - # it will fill up original form with username and same password, and submit it. - #res = '' - #for u in self.dbAuthenticator().users.all(): - # res += '{0}
'.format(u.name) - # - #res += '' - #return res - - # I know, this is a bit ugly, but this is just a sample :-) - - res = '

Login name:

' - res +='

Login

' - return res - - - def authCallback(self, parameters): - ''' - We provide this as a sample of callback for an user. - We will accept all petitions that has "user" parameter - - This method will get invoked by url redirections, probably by an SSO. - - The idea behind this is that we can provide: - * Simple user/password authentications - * Own authentications (not UDS, authenticator "owned"), but with no redirections - * Own authentications via redirections (as most SSO will do) - - Here, we will receive the parameters for this - ''' - user = parameters.get('user', None) - - return user - - def createUser(self, usrData): - ''' - This method provides a "check oportunity" to authenticators for users created - manually at administration interface. - - If we do not provide this method, the administration interface will not allow - to create new users "by hand", i mean, the "new" options from menus will dissapear. - - usrData is a dictionary that contains the input parameters from user, - with at least name, realName, comments, state & password. - - We can modify this parameters, we can modify ALL, but name is not recommended to - modify it unles you know what you are doing. - - Here, we will set the state to "Inactive" and realName to the same as username, but twice :-) - ''' - from uds.core.util.State import State - usrData['realName'] = usrData['name'] + ' ' + usrData['name'] - usrData['state'] = State.INACTIVE - - def modifyUser(self, usrData): - ''' - This method provides a "check opportunity" to authenticator for users modified - at administration interface. - - If we do not provide this method, nothing will happen (default one does nothing, but - it's valid). - - usrData is a dictionary that contains the input parameters from user, - with at least name, realName, comments, state & password. - - We can modify this parameters, we can modify ALL, but name is not recommended to - modify it unless you know what you are doing. - - Here, we will simply update the realName of the user, and (we have to take care - this this kind of things) modify the userName to a new one, the original plus '-1' - ''' - usrData['realName'] = usrData['name'] + ' ' + usrData['name'] - usrData['name'] = usrData['name'] + '-1' diff --git a/server/documentation/_downloads/samples/auths/__init__.py b/server/documentation/_downloads/samples/auths/__init__.py deleted file mode 100644 index 548fde41..00000000 --- a/server/documentation/_downloads/samples/auths/__init__.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: utf-8 -*- - -# -# Copyright (c) 2012 Virtual Cable S.L. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of Virtual Cable S.L. nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -''' -Dummy test authenticator. Not used in production (it doesn't registers itself) - -@author: Adolfo Gómez, dkmaster at dkmon dot com -''' -from uds.core import auths -from SampleAuth import SampleAuth - -# Commented, this auth exists for testing purposes only -auths.factory().insert(SampleAuth) diff --git a/server/documentation/_downloads/samples/auths/auth.png b/server/documentation/_downloads/samples/auths/auth.png deleted file mode 100644 index c8560b1d52b07059aa5066b274114304e7807b91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1225 zcmY+EeNa?Y7{=doKbB=-S=e0^S3WitcYsBZufPml3J@r9F)?bi3CA>xX;O=r9K$HT zs;SImBypN%imWuX5o|Qc6&;;S16KqoS{G>%WS9NEyLa#1(*-N+kN2E;|2V&So@d_o z>@id=l}c0+0FYLcm#h%(=&2Hmgfq#F>j0>aD@ux2Hnvg5>?pk+N{vk3yCvVXytsd> z?CIB3yL!e~o$cM0+p=x+oBgG=m(J%Wl)qChHz>z;I))Z}?m1RJU(5+Cj45NaWVwkLDduz`3W);4A*J&K4>D!qK+hfh4Wo%g2m>LHtBF)a0rs5^5*V;Q6hah5 zLuo|hgQ%d;goI*v4pUT^T<+`EV$0D9m(^_x0YS&=k|8-?ciTPMf-!4LC&Q>1U@^W%8yu^UW-~Ds_R?W95Z_YJ6 z`_}RsDOt(6mr)R|BVLH*->ito0mx-Szr=2@{j0N6#Rfz8NwuOT4-E%-M1cLe#bhzJ zg~gZ2YdAmVJ4`>SCe&lKfiw&U<2~dIii)RcEF}mC^LmF_g20Zkdwg5{79b0ER7I;4 z;IevkB5C2i#-@ECB+O2Pg2ar7A13AjjEQ(5XhGFl`5j9jOP6{%>=^bmxhxO$}vQt*9a9m1|8$1}p#IB0tD!Uw!1K;rOOo7v`LL_2uI^?yfpc_JAY- zh)I?WDN|F`LB@wUnG)NURzj3+A&%iWJ_Hy%?uCR)vKonri`b3qI6)n&9-J6A>wJR! znV_)XXjXRi=D5_fPC+~s@OWWXf(p$eoe0UKltdCksUEsVB+iv1m)8p+F-xUrRGrxg zshimh@qKsG^NBjk%GN7Ys#Z^LFDNrIut+WkV%&lU?lO~a;M#*OQGiu0`)H#^6RwC1 zk459mDD+u|&?B>p;OfnR4Ku3HS6b~^iO*M*l%F4pNl&N3laffskQtcXE5YBaoM?yP zPf*Nf*^IbMS{s`TW~Z6&vkr27H!XzE8tR@#O>OP=1!6e&rFi9)5$nj>r2b33?34qk zhrOBA*DfUcPj5L;d|1@p`_wbPpO6i{6un{Nf^BQEq-T~p8f#mc^ECX7B8vC>E4@zV zBB|Z3psiLX&oKSMQVem74;X(Cyi5?t2;ZRzpY4#1v1@D|N7|&@DRVkKHh%zL{6~>7 zX1h8PjPF= 5: - return State.FINISHED - - # random fail - if random.randint(0, 9) == 9: - self.storage().saveData('error', 'Random error at checkState :-)') - return State.ERROR - - self.storage().saveData('count', str(count)) - return State.RUNNING - - def finish(self): - ''' - Invoked when the core notices that the deployment of a service has finished. - (No matter wether it is for cache or for an user) - - This gives the oportunity to make something at that moment. - :note: You can also make these operations at checkState, this is really - not needed, but can be provided (default implementation of base class does - nothing) - ''' - # Note that this is not really needed, is just a sample of storage use - self.storage().remove('count') - - def assignToUser(self, user): - ''' - This method is invoked whenever a cache item gets assigned to an user. - This gives the User Deployment an oportunity to do whatever actions - are required so the service puts at a correct state for using by a service. - - In our sample, the service is always ready, so this does nothing. - - This is not a task method. All level 1 cache items can be diretly - assigned to an user with no more work needed, but, if something is needed, - here you can do whatever you need - ''' - pass - - def userLoggedIn(self, user): - ''' - This method must be available so os managers can invoke it whenever - an user get logged into a service. - - Default implementation does nothing, so if you are going to do nothing, - you don't need to implement it. - - The responability of notifying it is of os manager actor, and it's - directly invoked by os managers (right now, linux os manager and windows - os manager) - - The user provided is just an string, that is provided by actor. - ''' - # We store the value at storage, but never get used, just an example - self.storage().saveData('user', user) - - def userLoggedOut(self, user): - ''' - This method must be available so os managers can invoke it whenever - an user get logged out if a service. - - Default implementation does nothing, so if you are going to do nothing, - you don't need to implement it. - - The responability of notifying it is of os manager actor, and it's - directly invoked by os managers (right now, linux os manager and windows - os manager) - - The user provided is just an string, that is provided by actor. - ''' - # We do nothing more that remove the user - self.storage().remove('user') - - def reasonOfError(self): - ''' - Returns the reason of the error. - - Remember that the class is responsible of returning this whenever asked - for it, and it will be asked everytime it's needed to be shown to the - user (when the administation asks for it). - ''' - return self.storage().readData('error') or 'No error' - - def destroy(self): - ''' - This is a task method. As that, the excepted return values are - State values RUNNING, FINISHED or ERROR. - - Invoked for destroying a deployed service - Do whatever needed here, as deleting associated data if needed (i.e. a copy of the machine, snapshots, etc...) - @return: State.FINISHED if no more checks/steps for deployment are needed, State.RUNNING if more steps are needed (steps checked using checkState) - ''' - return State.FINISHED - - def cancel(self): - ''' - This is a task method. As that, the excepted return values are - State values RUNNING, FINISHED or ERROR. - - This can be invoked directly by an administration or by the clean up - of the deployed service (indirectly). - When administrator requests it, the cancel is "delayed" and not - invoked directly. - ''' - return State.FINISHED - \ No newline at end of file diff --git a/server/documentation/_downloads/samples/services/SampleUserDeploymentTwo.py b/server/documentation/_downloads/samples/services/SampleUserDeploymentTwo.py deleted file mode 100644 index 687971e7..00000000 --- a/server/documentation/_downloads/samples/services/SampleUserDeploymentTwo.py +++ /dev/null @@ -1,469 +0,0 @@ -# -*- coding: utf-8 -*- - -# -# Copyright (c) 2012 Virtual Cable S.L. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of Virtual Cable S.L. nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -''' -.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com -''' - -from uds.core.services import UserDeployment -from uds.core.util.State import State -import logging - -logger = logging.getLogger(__name__) - -class SampleUserDeploymentTwo(UserDeployment): - ''' - This class generates the user consumable elements of the service tree. - - This is almost the same as SampleUserDeploymentOne, but differs that this one - uses the publication to get data from it, in a very basic way. - - After creating at administration interface an Deployed Service, UDS will - create consumable services for users using UserDeployment class as - provider of this elements. - - At class instantiation, this will receive an environment with"generator", - that are classes that provides a way to generate unique items. - - The generators provided right now are 'mac' and 'name'. To get more info - about this, look at py:class:`uds.core.util.UniqueMacGenerator.UniqueNameGenerator` - and py:class:`uds.core.util.UniqueNameGenerator.UniqueNameGenerator` - - As sample also of environment storage usage, wi will use here the provider - storage to keep all our needed info, leaving marshal and unmarshal (needed - by Serializable classes, like this) empty (that is, returns '' first and does - nothing the second one) - - Also Remember, if you don't include this class as the deployedType of the - SampleServiceTwo, or whenever you try to access a service of SampleServiceTwo, - you will get an exception that says that you haven't included the deployedType. - ''' - - #: Recheck every five seconds by default (for task methods) - suggestedTime = 2 - - def initialize(self): - ''' - Initialize default attributes values here. We can do whatever we like, - but for this sample this is just right... - ''' - self._name = '' - self._ip = '' - self._mac = '' - self._error = '' - self._count = 0 - - # Serializable needed methods - def marshal(self): - ''' - Marshal own data, in this sample we will marshal internal needed - attributes. - - In this case, the data will be store with the database record. To - minimize database storage usage, we will "zip" data before returning it. - Anyway, we should keep this data as low as possible, we also have an - storage for loading larger data. - - :note: It's a good idea when providing marshalers, to store a 'version' - beside the values, so we can, at a later stage, treat with old - data for current modules. - ''' - data = '\t'.join(['v1', self._name, self._ip, self._mac, self._error, - str(self._count)]) - return data.encode('zip') - - def unmarshal(self, str_): - ''' - We unmarshal the content. - ''' - data = str_.decode('zip').split('\t') - # Data Version check - # If we include some new data at some point in a future, we can - # add "default" values at v1 check, and load new values at 'v2' check. - if data[0] == 'v1': - self._name, self._ip, self._mac, self._error, count = data[1:] - self._count = int(count) - - def getName(self): - ''' - We override this to return a name to display. Default implementation - (in base class), returns getUniqueIde() value - This name will help user to identify elements, and is only used - at administration interface. - - We will use here the environment name provided generator to generate - a name for this element. - - The namaGenerator need two params, the base name and a length for a - numeric incremental part for generating unique names. This are unique for - all UDS names generations, that is, UDS will not generate this name again - until this name is freed, or object is removed, what makes its environment - to also get removed, that makes all unique ids (names and macs right now) - to also get released. - - Every time get method of a generator gets called, the generator creates - a new unique name, so we keep the first generated name cached and don't - generate more names. (Generator are simple utility classes) - ''' - if self._name == '': - self._name = self.nameGenerator().get( self.publication().getBaseName(), - 3 ) - # self._name will be stored when object is marshaled - return self._name - - def setIp(self, ip): - ''' - In our case, there is no OS manager associated with this, so this method - will never get called, but we put here as sample. - - Whenever an os manager actor notifies the broker the state of the service - (mainly machines), the implementation of that os manager can (an probably will) - need to notify the IP of the deployed service. Remember that UDS treats with - IP services, so will probable needed in every service that you will create. - :note: This IP is the IP of the "consumed service", so the transport can - access it. - ''' - self._ip = ip - - def getUniqueId(self): - ''' - Return and unique identifier for this service. - In our case, we will generate a mac name, that can be also as sample - of 'mac' generator use, and probably will get used something like this - at some services. - - The get method of a mac generator takes one param, that is the mac range - to use to get an unused mac. - - The mac generated is not used by anyone, it will not depend on - the range, the generator will take care that this mac is unique - and in the range provided, or it will return None. The ranges - are wide enough to ensure that we always will get a mac address - in this case, but if this is not your case, take into account that - None is a possible return value, and in that case, you should return an - invalid id right now. Every time a task method is invoked, the core - will try to update the value of the unique id using this method, so - that id can change with time. (In fact, it's not unique at database level, - it's unique in the sense that you must return an unique id that can, for - example, be used by os managers to identify this element). - - :note: Normally, getting out of macs in the mac pool is a bad thing... :-) - ''' - if self._mac == '': - self._mac = self.macGenerator().get( '00:00:00:00:00:00-00:FF:FF:FF:FF:FF' ) - return self._mac - - def getIp(self): - ''' - We need to implement this method, so we can return the IP for transports - use. If no IP is known for this service, this must return None - - If our sample do not returns an IP, IP transport will never work with - this service. Remember in real cases to return a valid IP address if - the service is accesible and you alredy know that (for example, because - the IP has been assigend via setIp by an os manager) or because - you get it for some other method. - - Storage returns None if key is not stored. - - :note: Keeping the IP address is responsibility of the User Deployment. - Every time the core needs to provide the service to the user, or - show the IP to the administrator, this method will get called - - ''' - if self._ip == '': - return '192.168.0.34' # Sample IP for testing purposes only - return self._ip - - def setReady(self): - ''' - This is a task method. As that, the excepted return values are - State values RUNNING, FINISHED or ERROR. - - The method is invoked whenever a machine is provided to an user, right - before presenting it (via transport rendering) to the user. - - This method exist for this kind of situations (i will explain it with a - sample) - - Imagine a Service tree (Provider, Service, ...) for virtual machines. - This machines will get created by the UserDeployment implementation, but, - at some time, the machine can be put at in an state (suspend, shut down) - that will make the transport impossible to connect with it. - - This method, in this case, will check the state of the machine, and if - it is "ready", that is, powered on and accessible, it will return - "State.FINISHED". If the machine is not accessible (has been erased, for - example), it will return "State.ERROR" and store a reason of error so UDS - can ask for it and present this information to the Administrator. - - If the machine powered off, or suspended, or any other state that is not - directly usable but can be put in an usable state, it will return - "State.RUNNING", and core will use checkState to see when the operation - has finished. - - I hope this sample is enough to explain the use of this method.. - ''' - - # In our case, the service is always ready - return State.FINISHED - - def deployForUser(self, user): - ''' - Deploys an service instance for an user. - - This is a task method. As that, the excepted return values are - State values RUNNING, FINISHED or ERROR. - - The user parameter is not realy neded, but provided. It indicates the - Database User Object (see py:mod:`uds.modules`) to which this deployed - user service will be assigned to. - - This method will get called whenever a new deployed service for an user - is needed. This will give this class the oportunity to create - a service that is assigned to an user. - - The way of using this method is as follows: - - If the service gets created in "one step", that is, before the return - of this method, the consumable service for the user gets created, it - will return "State.FINISH". - If the service needs more steps (as in this case), we will return - "State.RUNNING", and if it has an error, it wil return "State.ERROR" and - store an error string so administration interface can show it. - - We do not use user for anything, as in most cases will be. - ''' - import random - - self._count = 0 - - # random fail - if random.randint(0, 9) == 9: - # Note that we can mark this string as translatable, and return - # it translated at reasonOfError method - self._error = 'Random error at deployForUser :-)' - return State.ERROR - - return State.RUNNING - - def deployForCache(self, cacheLevel): - ''' - Deploys a user deployment as cache. - - This is a task method. As that, the expected return values are - State values RUNNING, FINISHED or ERROR. - - In our sample, this will do exactly the same as deploy for user, - except that it will never will give an error. - - See deployForUser for a description of what this method should do. - - :note: deployForCache is invoked whenever a new cache element is needed - for an specific user deployment. It will also indicate for what - cache level (L1, L2) is the deployment - ''' - self._count = 0 - return State.RUNNING - - def moveToCache(self, newLevel): - ''' - This method is invoked whenever the core needs to move from the current - cache level to a new cache level an user deployment. - - This is a task method. As that, the expected return values are - State values RUNNING, FINISHED or ERROR. - - We only provide newLevel, because there is only two cache levels, so if - newLevel is L1, the actual is L2, and if it is L2, the actual is L1. - - Actually there is no possibility to move assigned services again back to - cache. If some service needs that kind of functionallity, this must be - provided at service level (for example, when doing publishing creating - a number of services that will be used, released and reused by users). - - Also, user deployments that are at cache level 2 will never get directly - assigned to user. First, it will pass to L1 and then it will get assigned. - - A good sample of a real implementation of this is moving a virtual machine - from a "suspended" state to "running" state to assign it to an user. - - In this sample, there is L2 cache also, but moving from L1 to L2 and - from L2 to L1 is doing really nothing, so this method will do nothing. - - In a real scenario, we will, for example, suspend or resume virtual machine - and, return State.RUNNING and at checkState check if this task is completed. - ''' - pass - - def checkState(self): - ''' - Our deployForUser method will initiate the consumable service deployment, - but will not finish it. - - So in our sample, we will only check if a number reaches 5, and if so - return that we have finished, else we will return that we are working - on it. - - One deployForUser returns State.RUNNING, this task will get called until - checkState returns State.FINISHED. - - Also, we will make the user deployment fail one of every 10 calls to this - method. - - Note: Destroying, canceling and deploying for cache also makes use of - this method, so you must keep the info of that you are checking if you - need it. - - In our case, destroy is 1-step action so this will no get called while - destroying, and cancel will simply invoke destroy. Cache deployment is - exactly as user deployment, except that the core will not assign it to - anyone, and cache moving operations is - ''' - import random - - self._count += 1 - # Count is always a valid value, because this method will never get - # called before deployForUser, deployForCache, destroy or cancel. - # In our sample, we only use checkState in case of deployForUser, - # so at first call count will be 0. - if self._count >= 5: - return State.FINISHED - - # random fail - if random.randint(0, 9) == 9: - self._error = 'Random error at checkState :-)' - return State.ERROR - - return State.RUNNING - - def finish(self): - ''' - Invoked when the core notices that the deployment of a service has finished. - (No matter whether it is for cache or for an user) - - This gives the opportunity to make something at that moment. - - :note: You can also make these operations at checkState, this is really - not needed, but can be provided (default implementation of base class does - nothing) - ''' - # We set count to 0, not needed but for sample purposes - self._count = 0 - - def assignToUser(self, user): - ''' - This method is invoked whenever a cache item gets assigned to an user. - This is not a task method right now, simply a notification. This means - that L1 cache items must be directly usable (except for the readyness part) - by users in a single step operation. - - Note that there will be an setReady call before letting the user consume - this user deployment, so this is more informational (so, if you keep at - what cache level is this instance, you can update it) than anything else. - - This is not a task method. All level 1 cache items can be dircetly - assigned to an user with no more work needed, but, if something is needed, - here you can do whatever you need. - - user is a Database user object. - ''' - logger.debug('Assigned to user {0}'.format(user)) - - def userLoggedIn(self, user): - ''' - This method must be available so os managers can invoke it whenever - an user get logged into a service. - - Default implementation does nothing, so if you are going to do nothing, - you don't need to implement it. - - The responsibility of notifying it is of os manager actor, and it's - directly invoked by os managers (right now, linux os manager and windows - os manager) - - The user provided is just an string, that is provided by actors. - ''' - # We store the value at storage, but never get used, just an example - self.storage().saveData('user', user) - - def userLoggedOut(self, user): - ''' - This method must be available so os managers can invoke it whenever - an user get logged out if a service. - - Default implementation does nothing, so if you are going to do nothing, - you don't need to implement it. - - The responability of notifying it is of os manager actor, and it's - directly invoked by os managers (right now, linux os manager and windows - os manager) - - The user provided is just an string, that is provided by actor. - ''' - # We do nothing more that remove the user - self.storage().remove('user') - - def reasonOfError(self): - ''' - Returns the reason of the error. - - Remember that the class is responsible of returning this whenever asked - for it, and it will be asked everytime it's needed to be shown to the - user (when the administation asks for it). - - :note: Remember that you can use ugettext to translate this error to - user language whenever it is possible. (This one will get invoked - directly from admin interface and, as so, will have translation - environment correctly set up. - ''' - return self._error - - def destroy(self): - ''' - This is a task method. As that, the excepted return values are - State values RUNNING, FINISHED or ERROR. - - Invoked for destroying a deployed service - Do whatever needed here, as deleting associated data if needed (i.e. a copy of the machine, snapshots, etc...) - @return: State.FINISHED if no more checks/steps for deployment are needed, State.RUNNING if more steps are needed (steps checked using checkState) - ''' - return State.FINISHED - - def cancel(self): - ''' - This is a task method. As that, the excepted return values are - State values RUNNING, FINISHED or ERROR. - - This can be invoked directly by an administration or by the clean up - of the deployed service (indirectly). - When administrator requests it, the cancel is "delayed" and not - invoked directly. - ''' - return State.FINISHED diff --git a/server/documentation/_downloads/samples/services/__init__.py b/server/documentation/_downloads/samples/services/__init__.py deleted file mode 100644 index 38a9126a..00000000 --- a/server/documentation/_downloads/samples/services/__init__.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- - -# -# Copyright (c) 2012 Virtual Cable S.L. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of Virtual Cable S.L. nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -''' -Sample Service module. - -This package simply shows how a new service can be implemented. - - -The first thing to do in every package that is a module is register the -class that is responsible of providing the module with the system. - -For this, we must simply import the class at __init__, UDS will take care -of the rest -''' - -from SampleProvider import Provider - diff --git a/server/documentation/_downloads/samples/services/provider.png b/server/documentation/_downloads/samples/services/provider.png deleted file mode 100644 index d2a954d44526a447e6f4e693324450868f7443b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 491 zcmV@I z6tZ>cs#3?$MGAIGp@M&a*2RKp$X#+d-yK9MULgrQczO4}pZ6m4M zO;r>{>SMK1(R3jAkU$c z(ue|C=n(p<8K9a`77{=;?4T$LkSNe1Vn%?5fE)o*{&oS%K|tex5Zy(6z;}}H5(OFOaM9~Q zx7&rU^;%d7NZx5-7`_aL!@KIe_FWhZ2B&COuIuhI#@gB+jYenIeO0r?aeN&F!KL=o zG(F6?Xp54<9?3z011HBvpSaL>eLkDbZue{YI{B7A; zx^zG+3`~(Sh76=N$^gPH@B}t~{eE8{Qq_s}Bc0B^clW(J|M0A}@Cg0^OH^2+eWX=z z8HV;9tA?$Y#~XCs8)eiD`C;wl#NCMX9_3J#DwZG;yA(cv%$jyaC7s6 zE3I*NH|N>gxtL5Qa(_%f^G&E%3b9(P{uT&=6^lLX z&UHLKeamS)yuRv7&0Gw~Ajab{`u+a9fTeNw4=^TXvZa_O&nYAfl2g!g-+^ei+c;q* z`(?de-|OLAfZmE8=2uN%Mx)WT+wE3y0khd`tJ?F=^odr-WyG{^|NT4v2BY2&XM6rZ QqyPW_07*qoM6N<$f=DO_-T(jq diff --git a/server/documentation/_images/LogoUDS.png b/server/documentation/_images/LogoUDS.png deleted file mode 100644 index f3196430b40fba4013ea2b266c472edacf56a1b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9441 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 diff --git a/server/documentation/api/index.rst b/server/documentation/api/index.rst deleted file mode 100644 index 1353be23..00000000 --- a/server/documentation/api/index.rst +++ /dev/null @@ -1,9 +0,0 @@ -============== -UDS's core API -============== - -.. toctree:: - - models - modules - /development/samples/samples diff --git a/server/documentation/api/models.rst b/server/documentation/api/models.rst deleted file mode 100644 index e2639d1a..00000000 --- a/server/documentation/api/models.rst +++ /dev/null @@ -1,24 +0,0 @@ -=================== -UDS Database Models -=================== - -This section describes de models used in UDS. - -The models described here are implemented using Django models, so you can get more -info about Django models functionalty at `Django project website `_ - -The function of the models inside UDS is to provide the persistence needed by -the core and by other utility classes that are provided, such as a Cache, Storage -or unique IDs. - -Right now the models are used all over UDS, but with time we will limit the use -of this models to be done through managers or utility clases designed for that -purpose. - -.. toctree:: - - models/services - models/authentication - models/transport - models/other - diff --git a/server/documentation/api/models/authentication.rst b/server/documentation/api/models/authentication.rst deleted file mode 100644 index 75d64235..00000000 --- a/server/documentation/api/models/authentication.rst +++ /dev/null @@ -1,25 +0,0 @@ -============================= -Authentication Related models -============================= -.. toctree:: - :maxdepth: 2 - -.. module:: uds.models - -.. autoclass:: Authenticator - :members: - :show-inheritance: - -.. autoclass:: User - :members: - :show-inheritance: - -.. autoclass:: Group - :members: - :show-inheritance: - -.. autoclass:: UserPreference - :members: - :show-inheritance: - - diff --git a/server/documentation/api/models/other.rst b/server/documentation/api/models/other.rst deleted file mode 100644 index 6c6f9e2e..00000000 --- a/server/documentation/api/models/other.rst +++ /dev/null @@ -1,41 +0,0 @@ -============ -Other models -============ - -Environment related -------------------- - -.. module:: uds.models - -.. toctree:: - :maxdepth: 2 - -.. autoclass:: Cache - :members: - :show-inheritance: - -.. autoclass:: Storage - :members: - :show-inheritance: - -.. autoclass:: UniqueId - :members: - :show-inheritance: - -Module related --------------- - -.. autoclass:: Config - :members: - :show-inheritance: - -Scheduling and background workers related ------------------------------------------ - -.. autoclass:: Scheduler - :members: - :show-inheritance: - -.. autoclass:: DelayedTask - :members: - :show-inheritance: diff --git a/server/documentation/api/models/services.rst b/server/documentation/api/models/services.rst deleted file mode 100644 index c11794cf..00000000 --- a/server/documentation/api/models/services.rst +++ /dev/null @@ -1,33 +0,0 @@ -====================== -Service Related models -====================== - -This models takes cares of persistence of the Services and its associated elements. - - DESCRIBE HIEARARCHY HERE - - -.. toctree:: - :maxdepth: 2 - -.. module:: uds.models - -.. autoclass:: Provider - :members: - :show-inheritance: - -.. autoclass:: Service - :members: - :show-inheritance: - -.. autoclass:: DeployedService - :members: - :show-inheritance: - -.. autoclass:: DeployedServicePublication - :members: - :show-inheritance: - -.. autoclass:: UserService - :members: - :show-inheritance: diff --git a/server/documentation/api/models/transport.rst b/server/documentation/api/models/transport.rst deleted file mode 100644 index 3fb2545c..00000000 --- a/server/documentation/api/models/transport.rst +++ /dev/null @@ -1,18 +0,0 @@ -======================== -Transport Related models -======================== -.. toctree:: - :maxdepth: 2 - -.. module:: uds.models - -.. autoclass:: Transport - :members: - :show-inheritance: - -.. autoclass:: Network - :members: - :show-inheritance: - - - diff --git a/server/documentation/api/modules.rst b/server/documentation/api/modules.rst deleted file mode 100644 index 5aaebc0d..00000000 --- a/server/documentation/api/modules.rst +++ /dev/null @@ -1,18 +0,0 @@ -=========== -UDS Modules -=========== - - -Modules are the basic component of plugin architecture of UDS. - -As so, they are spreadly covered here, and with -:doc:`samples ` must give enough information for -allowing anyone to develop their own modules. - -.. toctree:: - - modules/BaseModule - modules/FormFields - modules/ServiceModules - modules/AuthenticatorModule - diff --git a/server/documentation/api/modules/AuthenticatorModule.rst b/server/documentation/api/modules/AuthenticatorModule.rst deleted file mode 100644 index b210793a..00000000 --- a/server/documentation/api/modules/AuthenticatorModule.rst +++ /dev/null @@ -1,27 +0,0 @@ -===================== -Authenticator Modules -===================== - -Authenticator modules are responsible of providing the user authentication -part inside UDS. - -They are composed of a package where it is provided and, at least, the following -elements: - - * One icon for administration interface representation. Icon is png file of - 16x16. - * One class, derived from uds.core.auths.Authenticator, providing the needed - logic for that authenticator. - * Registration of the class inside uds at package's __init__. - -All packages included inside uds.auths will automatically be imported, but -the authenticators needs to register as valid authenticators, and the best place -to do that is at the authenticator's package __init__. - -The best way to understand what you need to create your own authenticator, -is to look at :doc:`modules samples ` - - -.. toctree:: - - auths/Authenticator \ No newline at end of file diff --git a/server/documentation/api/modules/BaseModule.rst b/server/documentation/api/modules/BaseModule.rst deleted file mode 100644 index 294d2add..00000000 --- a/server/documentation/api/modules/BaseModule.rst +++ /dev/null @@ -1,53 +0,0 @@ -=========== -Base Module -=========== - -The Base module is the base class used for all modules of UDS. - -In order to deveplop an UDS Module, there is a number of basic methods that you must provide. - -There are the clases that are base of BaseModule, that are: - * BaseModule_ - * Environmentable_ - * Serializable_ - * UserInterface_ - -.. toctree:: - -BaseModule ----------- - -.. module:: uds.core - -.. autoclass:: Module - :members: - -Environmentable ---------------- - -.. autoclass:: Environmentable - :members: - - -Serializable ------------- - -.. autoclass:: Serializable - :members: - - -UserInterface -------------- - - UserInterface is the class responsible for managing the Field Descriptions of modules. - - This fields descriptions are intended for allowing an easy exposition of configuration form via the - administration interface. - - You can obtain more information about user interface fields at :doc:`User interface fields types `. - -.. module:: uds.core.ui.UserInterface - -.. autoclass:: UserInterface - :members: - diff --git a/server/documentation/api/modules/FormFields.rst b/server/documentation/api/modules/FormFields.rst deleted file mode 100644 index 3b15da2a..00000000 --- a/server/documentation/api/modules/FormFields.rst +++ /dev/null @@ -1,33 +0,0 @@ -Form Fields -=========== - -Form Fields are utility clases provided for allowing easy communication of modules -and administration interface. - -It helps to define the administration level forms that will be used to manage -different modules (service providers, services, authenticators, transports, ...) - -All modules that needs to be presented to admin users, use UserInterface as one -of their base class. - -Think that not all interfaces needed by different modules need a direct representation -at administration interface level, (for example, UserDeployment do not need to be -managed by administrators, nor publications, both corresponding to service modules). - -.. module:: uds.core.ui.UserInterface - -.. toctree:: - - -The types of fields provided are: - * :py:class:`gui.TextField` - * :py:class:`gui.NumericField` - * :py:class:`gui.PasswordField` - * :py:class:`gui.HiddenField` - * :py:class:`gui.CheckBoxField` - * :py:class:`gui.ChoiceField` - * :py:class:`gui.MultiChoiceField` - * :py:class:`gui.EditableList` - -.. autoclass:: gui - :members: InputField, TextField, NumericField, PasswordField, HiddenField, CheckBoxField, ChoiceField, MultiChoiceField, EditableList diff --git a/server/documentation/api/modules/ServiceModules.rst b/server/documentation/api/modules/ServiceModules.rst deleted file mode 100644 index a3c9c1e4..00000000 --- a/server/documentation/api/modules/ServiceModules.rst +++ /dev/null @@ -1,53 +0,0 @@ -=============== -Service Modules -=============== - -Service modules are responsible for giving the user consumable ip services for -users. - -They are composed of a package where it is provided, at least, the following -elements: - - * One icon for administration interface representation. Icon is png file of - 16x16. - * A Full tree of classes, derived from interfaces (descrived below) - * Registration of the class inside UDS at package's __init__. - -All packages included inside uds.services will automatically be imported, but -the service providers (root of service trees) needs to register as valid -providers, and the best place to do that is at the authenticator's package __init__. - -the Full tree of classes needed by the service modules are: - - * **Provider**: This is the root tree of any service. It represents an agrupation - of services under the same root. As sample, a service provider can be an - Open nebula server, an VC, or whataver is a common root for a number of services. - * **Service**: This is the representation of what a service will give to an user. - As such, this is not what the user will consume, but this is more the definition - of what the user will consume. Before assigning a service to an user, the admin - will need to declare a "Deployed Service", that is a definition, using this service - an a number of other modules, of what the user will consume. Inside this service - we need to provide the information needed for deploying an user consumable item, - such as if it needs to be "prepared", if it supports cache, if it must be assigned - to an user "manually", and all the custom data that the user deployments and publications - will need. - * **Publication**. Some services, before being assigned to users, needs some kind of - preparation. This process of preparation is called here "publication". The service - itself will declare if it needs a publication and, if needed, who is responsible of - that. Services with needed publication will use this kind of class to provide - such preparation. - * **User Deployment**. This is what will provide the final user consumable service. - The user deployment is the last responsible for, using the provided service - and provided publication (if needed), to create the elements that the user will - consume. - -The best way to understand what you need to create your own services, -is to look at :doc:`modules samples ` - -.. toctree:: - - services/Provider - services/Service - services/Publication - services/UserDeployment - services/Exceptions \ No newline at end of file diff --git a/server/documentation/api/modules/auths/Authenticator.rst b/server/documentation/api/modules/auths/Authenticator.rst deleted file mode 100644 index f30d9fb7..00000000 --- a/server/documentation/api/modules/auths/Authenticator.rst +++ /dev/null @@ -1,15 +0,0 @@ -======================= -Authenticator Interface -======================= - -The authenticator class is in fact an interface. UDS authenticators must derive -from this, and must provide the logic so UDS can manage the users and groups that -an authenticator provides. - - -.. toctree:: - -.. module:: uds.core.auths - -.. autoclass:: Authenticator - :members: diff --git a/server/documentation/api/modules/services/Exceptions.rst b/server/documentation/api/modules/services/Exceptions.rst deleted file mode 100644 index f137b05b..00000000 --- a/server/documentation/api/modules/services/Exceptions.rst +++ /dev/null @@ -1,9 +0,0 @@ -================== -Service Exceptions -================== - -.. toctree:: - -.. automodule:: uds.core.services.Exceptions - :members: - diff --git a/server/documentation/api/modules/services/Provider.rst b/server/documentation/api/modules/services/Provider.rst deleted file mode 100644 index ad7fde37..00000000 --- a/server/documentation/api/modules/services/Provider.rst +++ /dev/null @@ -1,27 +0,0 @@ -================== -Provider interface -================== - -The provider class is the root class of the module. It keeps the common information -needed by all services provided by this "provider". - -Think about a provider as the class that will declare all stuff neded by core and -child services to provide and administrator user a way to create services to be -consumed by users. - -One good example is a Virtualization server. Here we keep information about that -server (ip address, protocol, ....) and services provided by that "provider" will -make use of that information to make the administrator not provide it once an again -for every service we put on that virtualization server. - -.. toctree:: - -.. module:: uds.core.services - -For a detailed example of a service provider, you can see the provided -:doc:`provider sample ` - -.. autoclass:: ServiceProvider - :members: - - diff --git a/server/documentation/api/modules/services/Publication.rst b/server/documentation/api/modules/services/Publication.rst deleted file mode 100644 index 290e9150..00000000 --- a/server/documentation/api/modules/services/Publication.rst +++ /dev/null @@ -1,30 +0,0 @@ -===================== -Publication interface -===================== - -The publication class is in fact an interface. It represents, in those case that -a service needs the preparation, the logic for that preparation. - -So the publication class is responsible of doing whatever is needed to get the -deployed service (that is the compound of a service, an os manager, transports -and authenticators) ready for deploying user consumables. - -Note that not all services needs to implement this class, only in those case -where that service declares that a publication is needed. - - -As functional sample of a publication, imagine that we want to assing KVM COW -machines to users. The publication class can make a clone of the base machine -(that the service itself has taken note of which one is), and then the COWs will -be created from this cloned machine. - -.. toctree:: - -.. module:: uds.core.services - -For a detailed example of a service provider, you can see the provided -:doc:`publication sample ` - -.. autoclass:: Publication - :members: - diff --git a/server/documentation/api/modules/services/Service.rst b/server/documentation/api/modules/services/Service.rst deleted file mode 100644 index 6e26c128..00000000 --- a/server/documentation/api/modules/services/Service.rst +++ /dev/null @@ -1,25 +0,0 @@ -================= -Service interface -================= - -The service class is in fact an interface. It represents the base for all user -deployments (that is, consumable user services) that will be provided. - -As such, the service is responsible for keeping the information that, at deployments, -will be neded by provided user consumable services. - -A good sample of a service can be a KVM machine that will be copied COW and that COWs -will be assigned to users. In that case, we will collect which machine will be copied, -where it is to be copied, an a few more params that the user deployments will need. - -.. toctree:: - -.. module:: uds.core.services - -For a detailed example of a service provider, you can see the provided -:doc:`service sample ` - -.. autoclass:: Service - :members: - - diff --git a/server/documentation/api/modules/services/UserDeployment.rst b/server/documentation/api/modules/services/UserDeployment.rst deleted file mode 100644 index 6f97c2de..00000000 --- a/server/documentation/api/modules/services/UserDeployment.rst +++ /dev/null @@ -1,23 +0,0 @@ -======================== -UserDeployment interface -======================== - -The user deployment class is in fact an interface. It represents the final consumable -that will be assigned to an user, and, as such, it must provide some mechanisms to -allow core to manage those consumables. - -A good sample of an user deployment can be a KVM Virtual Machine, cloned COW from -another, and assigned to an user. - -.. toctree:: - -.. module:: uds.core.services - -For detailed examples of a couple of user deployments, you can see the provided -:doc:`service sample ` and -:doc:`service sample ` - -.. autoclass:: UserDeployment - :members: - - diff --git a/server/documentation/conf.py b/server/documentation/conf.py deleted file mode 100644 index 0dfc3a43..00000000 --- a/server/documentation/conf.py +++ /dev/null @@ -1,258 +0,0 @@ -# -*- coding: utf-8 -*- -# -# UDS documentation build configuration file, created by -# sphinx-quickstart on Mon Jun 18 01:41:48 2012. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys, os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath('../src/')) - -os.environ['DJANGO_SETTINGS_MODULE'] = 'server.settings' - -#from server import settings -#from django.core.management import setup_environ -#setup_environ(settings) - -# -- General configuration ----------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.mathjax', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'UDS' -copyright = u'2012, Virtual Cable S.L.U.' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '1.0' -# The full version, including alpha/beta/rc tags. -release = '1.0' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# default, sphinxdoc, traditional, nature, scrolls, agogo, haiku, pyramid -html_theme = 'sphinxdoc' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -html_theme_options = { - # 'stickysidebar' : False, - # 'collapsiblesidebar' : True, - # 'externalrefs' : True, - -} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'UDSdoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -'papersize': 'a4paper', - -# The font size ('10pt', '11pt' or '12pt'). -'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -'preamble': '\setcounter{tocdepth}{6}', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'UDS.tex', u'UDS Documentation', - u'Virtual Cable S.L.U.', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -latex_logo = '_images/LogoUDS.png' - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -latex_show_pagerefs = True - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output -------------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'uds', u'UDS Documentation', - [u'Virtual Cable S.L.U.'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------------ - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'UDS', u'UDS Documentation', - u'Virtual Cable S.L.U.', 'UDS', 'Universal Desktop Services.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - - -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/server/documentation/development/architecture.rst b/server/documentation/development/architecture.rst deleted file mode 100644 index 0bf2b1fd..00000000 --- a/server/documentation/development/architecture.rst +++ /dev/null @@ -1,36 +0,0 @@ -================== -UDS's architecture -================== - -This section covers the current UDS Arquiceture & diagrams. - -UDS is built on the Django web framework, which itself is -built on Python, thus MyTARDIS follows the architectural model -of Django. - -Component Architecture ----------------------- - -This diagram shows the major components of UDS. - -* Core components - * `Apache Http `_ - * `WSGI `_ - * `Django `_ - * `Python `_. - -* RDBMS - UDS is currently being developed/testing on Mysql 5 Database. - May other databases will work also, but no one else has been tested. - -Functional Architecture ------------------------ - -UDS is build using Django as base support for Web acess and Database access. - -Over this, UDS uses the following diagram: - -DIAGRAM - -Core - Basic core funcionality. diff --git a/server/documentation/development/contributing.rst b/server/documentation/development/contributing.rst deleted file mode 100644 index ec04f5a4..00000000 --- a/server/documentation/development/contributing.rst +++ /dev/null @@ -1,3 +0,0 @@ -=================== -Contributing to UDS -=================== diff --git a/server/documentation/development/repository.rst b/server/documentation/development/repository.rst deleted file mode 100644 index 36b5e39b..00000000 --- a/server/documentation/development/repository.rst +++ /dev/null @@ -1,3 +0,0 @@ -============== -UDS Repository -============== \ No newline at end of file diff --git a/server/documentation/development/samples/auths/Authenticator.rst b/server/documentation/development/samples/auths/Authenticator.rst deleted file mode 100644 index f4394981..00000000 --- a/server/documentation/development/samples/auths/Authenticator.rst +++ /dev/null @@ -1,15 +0,0 @@ -==================== -Sample Authenticator -==================== - -The authenticator is the responsible of providing the needed mechanisms to UDS for -user authentication. - -As thatm this must provide a number of methods, that will allow UDS to manage -things the way it needs to. (Access users, groups, check credentials, etc...) - -Here you can :download:`Download sample ` - - -.. literalinclude:: /_downloads/samples/auths/SampleAuth.py - :linenos: diff --git a/server/documentation/development/samples/samples.rst b/server/documentation/development/samples/samples.rst deleted file mode 100644 index 604170bf..00000000 --- a/server/documentation/development/samples/samples.rst +++ /dev/null @@ -1,100 +0,0 @@ -=================== -UDS Modules Samples -=================== - -In this section we cover basic samples of the different kind of mudules supported -by UDS. - -UDS is designed in a modular way, meaning this that it has a core that allows -a number of modules to get plugged inside the whole system. - -This modules are: - - * Services, including all stuff around them. - * Transports - * OS Managers - * Authenticators - -This secion will try to give sample of every module, what it must do and how this -must be done. - -Service Sample --------------- - -A service is composed of several classes. This classes depends on how the service works. - -This are: - - * *Provider*, that is simply the "root" where services - descent, so we can configure just one part of the service parameters and rest - of them at service level. - - One sample of provider is a virtualization server, such as oVirt, Open Nebula, or - others like it. We can keep info about server at provider level, and info about - what we need in an specific service at service level. - - * *Service*, that is a service definition, that must be deployed at a later stage - to offer something to the users. - - Following our previous sample, if provider was an oVirt server, a service can - be a Virtual Machine cloned COW. - - * *Publication*, This class is optional. If service declares that needs a - publication for deployment of user instance, this class implements exactly - that, the publication for that service. Publications are in fact a way of - allowing services to prepare something in a stage prior to creating the - user consumable services. - - Following our previous sample, if provider was an oVirt Server and the service - was a Virtual Machine cloned for Cow, the poblication can be a full clone of - the service machine for making COWS from this one. - - * *DeployedService*, This class is the user consumed service itself. After a - service is created, it must be deployed, and deploy will mean that there will - be "instances" of that service (User Deployments) that will be consumed by - users. - - Following our previous sample, if the publication was a full copy machine, - an deployed service can be a machine in COW format using as base that - machine. - - -From theese, the only not really needed is Publication. Publication will only be -needed whenever a service needs a "preparation" before creating the user consumable -deployed services. For a service to be usable, we will need the full tree, meaning -this that we will provide all controllers (Provider, service or services, publication -or publications, deployed service or deployed services.). - -All class belonging to a service must be grouped under the same package, and we -well need to register this package for the system to recognize it as service. - -For this, we must register the Provider, that has references to rest of items. - -Provider declares which services it provides. Services declares which publication -and deployed service it needs. Provider can declare multiples services it offers, -but services has at most one publication and exatly one deployed service. - -So, by registering the Provider, we register the whole tree provided by de package. - -Here you can find samples of every class needed for creating a new package of -services. - -.. toctree:: - - services/whatisneeded - services/Provider - services/Service - services/Publication - services/DeployedServiceOne - services/DeployedServiceTwo - - -Authenticator Sample --------------------- - -An authenticator is composed of a single class, derived from :py:class:`uds.core.auths.Authenticator`. - -Here you can find a sample of an authenticator. - -.. toctree:: - auths/Authenticator \ No newline at end of file diff --git a/server/documentation/development/samples/services/DeployedServiceOne.rst b/server/documentation/development/samples/services/DeployedServiceOne.rst deleted file mode 100644 index abf2b43d..00000000 --- a/server/documentation/development/samples/services/DeployedServiceOne.rst +++ /dev/null @@ -1,20 +0,0 @@ -========================== -Sample User Deployment One -========================== - -User deployments are the class that are responsible for creating the ultimate consumable -user service, that is, for managing that whenever the core requests a new service for -an user, this classes will take responsibility to provide it. - -Here we cover SampleUserDeploymentOne that is for SampleServiceOne, do not needs to be -published and do not uses cache. - -You can easily follow the code to see what it does, and what you have to do if you -want to provide a new one. - -:download:`Download sample ` - - -.. literalinclude:: /_downloads/samples/services/SampleUserDeploymentOne.py - :linenos: - diff --git a/server/documentation/development/samples/services/DeployedServiceTwo.rst b/server/documentation/development/samples/services/DeployedServiceTwo.rst deleted file mode 100644 index f3664a74..00000000 --- a/server/documentation/development/samples/services/DeployedServiceTwo.rst +++ /dev/null @@ -1,20 +0,0 @@ -========================== -Sample User Deployment Two -========================== - -User deployments are the class that are responsible for creating the ultimate consumable -user service, that is, for managing that whenever the core requests a new service for -an user, this classes will take responsibility to provide it. - -Here we cover SampleUserDeploymentTwo that is for SampleServiceTwo, needs to be -published and has L1 and L2 cache items. - -You can easily follow the code to see what it does, and what you have to do if you -want to provide a new one. - -:download:`Download sample ` - - -.. literalinclude:: /_downloads/samples/services/SampleUserDeploymentTwo.py - :linenos: - diff --git a/server/documentation/development/samples/services/Provider.rst b/server/documentation/development/samples/services/Provider.rst deleted file mode 100644 index b792a642..00000000 --- a/server/documentation/development/samples/services/Provider.rst +++ /dev/null @@ -1,19 +0,0 @@ -======================= -Sample Service Provider -======================= - -The service provider is the top of the tree of services needed clases. -It main function is to provide a base for services, where this services contains -a common parent that is, for example, a server, a range of IPs, etc... - -This sample covers a simple service provider, explains also a bit about FormFields -and shows what tasks must be done by a service provider. - -You can easily follow the code to see what it does, and what you have to do if you -want to provide a new one. - -:download:`Download sample ` - - -.. literalinclude:: /_downloads/samples/services/SampleProvider.py - :linenos: diff --git a/server/documentation/development/samples/services/Publication.rst b/server/documentation/development/samples/services/Publication.rst deleted file mode 100644 index 7d82cc0c..00000000 --- a/server/documentation/development/samples/services/Publication.rst +++ /dev/null @@ -1,23 +0,0 @@ -================== -Sample publication -================== - -A publication is a class responsible for making a service defined available to be -consumed by users. - -Not all services needs publications as you have already seen if you are following -the samples. Publications are only needed for services that needs some kind of -preparation, as, for example, with Virtual Machines, clone the base virtual machine -so we can create COW copies from this clone. This kind of behavior needs a preparation -step, that is efectively to clone the virtual base, and that will be the task of a -publication for that kind of services. - -You can easily follow the code to see what it does, and what you have to do if you -want to provide a new one. - -:download:`Download sample ` - - -.. literalinclude:: /_downloads/samples/services/SamplePublication.py - :linenos: - diff --git a/server/documentation/development/samples/services/Service.rst b/server/documentation/development/samples/services/Service.rst deleted file mode 100644 index 49482e70..00000000 --- a/server/documentation/development/samples/services/Service.rst +++ /dev/null @@ -1,15 +0,0 @@ -============== -Sample service -============== - -Here we cover two services. ServiceOne, that do not needs publication and -ServiceTwo, that needs publication. - -This sample should be enought to guide you through the creation of a new service. - -:download:`Download sample ` - - -.. literalinclude:: /_downloads/samples/services/SampleService.py - :linenos: - diff --git a/server/documentation/development/samples/services/whatisneeded.rst b/server/documentation/development/samples/services/whatisneeded.rst deleted file mode 100644 index 20eb9ffb..00000000 --- a/server/documentation/development/samples/services/whatisneeded.rst +++ /dev/null @@ -1,32 +0,0 @@ -Needs for a service package ---------------------------- - -For a new package of services, you will need: - - - * One package (python package), of course :-). - * One icon for the provider, in png format an 16x16 size. Colours is left - to your election. This icon will be informed at Provider class. - * One icon for every service that the provider will expose. Same as provider - icons. These icons will be informed at Service class. Every single class - must provide its own icon. - * Registering the provider. For the samples show here, this will be at - __init__ of the package. - - The contents of the sample package __init__ file is: - - .. literalinclude:: /_downloads/samples/services/__init__.py - :linenos: - - :download:`Download sample ` - - * Put the package under the apropiate uds package. In the case of - services, this is under "uds.core". - - Core will look for all packages under "uds.services" and import them at - initialization of the server, so every package under this will get their - __init__ called, where we register the provider. - - * Follow the samples provided here as base - - \ No newline at end of file diff --git a/server/documentation/index.rst b/server/documentation/index.rst deleted file mode 100644 index b7e3f500..00000000 --- a/server/documentation/index.rst +++ /dev/null @@ -1,71 +0,0 @@ -.. _index: - -=================== -UDS's documentation -=================== - -This documentation is provided so we can understand (hopefully) UDS, its internals, -and everything about it. - -Right now the documentation is not too ritch, but we are working on it so it will -get the needed level for this kind of project. - - -First Steps -=========== - -* **From scratch:** - :doc:`Overview ` | - :doc:`Installation ` - -.. toctree:: - :hidden: - - intro/overview - intro/install - -The internals of uds -==================== - -.. toctree:: - - development/architecture - development/development - api/index - -UDS Open source project -======================= - -* **Community:** - :doc:`How to get involved ` | - :doc:`The UDS source code repository ` - -.. toctree:: - :hidden: - - development/contributing - development/repository - - -Acknowledgements -================ - -We want to thaks all the people that has contributed to de project, an also -other Open Source project used to improve this one. - -List of other software used to build UDS: - - * `Django `_ - * `XML-RPC.NET Copyright (c) 2006 Charles Cook `_ - * `Darkglass reworked graphics `_ - * `Crystal project `_ - * `South `_ - * `Jsch `_ - * `JQuery `_ - * `Plugin detect library `_ - * `JQuery UI `_ - -I hope to do nor forget anythinh here, if i do, please, report it so we can credit -to every project that UDS makes use of. - - \ No newline at end of file diff --git a/server/documentation/intro/install.rst b/server/documentation/intro/install.rst deleted file mode 100644 index 04b9922e..00000000 --- a/server/documentation/intro/install.rst +++ /dev/null @@ -1,46 +0,0 @@ -============== -Installing UDS -============== - -In order to run UDS, you will need: - - * Django Server 1.4 - * South module for Django - * Mysql libraries for python - * Mysql Database - * Ldap Libraries for python - * Criptographic package for python - -Default transports are compiled in binary form, and kept inside the UDS repository, -so you won't need Java to put UDS to work. - -Once you have all of this, you will have to follow these steps: - - * Obtain UDS from repository, you can see how to do this from -:doc:`repository access documentation ` - * Configure a database for use with UDS. To do this, simply create a database - inside your Mysql server, and a user with all permissions in this database. - * Configure UDS settings. - Inside "server" folder, you will find "settings.py". This file contains the - configuration of UDS (if it runs in debug mode, ..). The most important part - here is the DATABASES section, where you will set up the database that UDS - will use. Simply change "host", "port", "username", "password" and "name" - to match your database settings. - Here, we have to take care that, if we left UDS in debug mode, Django will keep - track of all petitions to UDS, so memory will grow constantly. Do not get scared - if you see that UDS starts consuming memory. Simply restart it or, if it's - intended to be running for a while, set DEBUG variable to "False". - Important sections are: - - * Create initial database tables. - Inside UDS folder(where you downloaded it), you will see a "manage.py". - This python application is the responsible for managing UDS, from database creation, - migrations, backend start & stop, web server (testing web server btw), ... - To create initial databases, we will do: - - python manage.py sync - python manage.py migrate - - Now we have all databases and everything that UDS needs for starting up ready... :-) - - diff --git a/server/documentation/intro/overview.rst b/server/documentation/intro/overview.rst deleted file mode 100644 index 4f4d8463..00000000 --- a/server/documentation/intro/overview.rst +++ /dev/null @@ -1,31 +0,0 @@ -=============== -UDS at a glance -=============== - -UDS has been developed to make a single open source server that provides the access -to the growing ip services catalog. - -For this, we have made a framework that allows the use of any ip service, -focusing initially at VDI because it's the major of people who have initially contacted us. - -Also, first version of UDS has been developed "fast" (very fast indeed), so -we'll need to make a revision and adapt the code of the framework so it's more -'pythonic'. (Think that I start learning python one day, and less than -a week later I started this project). So althouth UDS is fully -functional and has been tested and is stable enough for any production environment, -there is a lot of work to do. - -UDS not only provides default modules for a lot of things (virtualization -provider, authentication providers, protocols...), but also provides the core -itself to allow anyone who wants or needs something to incorporate it to the -UDS catalog quickly and easily. - -* In order to use UDS, you must simply :doc:`Follow the installation guide `. - -* In order to design and implement your own modules, you must: - - * :doc:`Understand the architecture ` - * :doc:`See some module samples ` - -* In order to contribute, you must install UDS, understand it, an read the - :doc:`contributing guide ` diff --git a/server/documentation/make.bat b/server/documentation/make.bat deleted file mode 100644 index 3ebfb5f0..00000000 --- a/server/documentation/make.bat +++ /dev/null @@ -1,190 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set BUILDDIR=_build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . -set I18NSPHINXOPTS=%SPHINXOPTS% . -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% - set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. texinfo to make Texinfo files - echo. gettext to make PO message catalogs - echo. changes to make an overview over all changed/added/deprecated items - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\UDS.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\UDS.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "texinfo" ( - %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. - goto end -) - -if "%1" == "gettext" ( - %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The message catalogs are in %BUILDDIR%/locale. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -:end diff --git a/server/samples/sample_output_REST3.txt b/server/samples/sample_output_REST3.txt index 586b8ae6..1141ae1c 100644 --- a/server/samples/sample_output_REST3.txt +++ b/server/samples/sample_output_REST3.txt @@ -854,7 +854,7 @@ Listing supported auths and related info > name: Active Directory Authenticator > passwordLabel: Password > type: ActiveDirectoryAuthenticator - > description: Authenticate against Active Directory + > description: against Active Directory > userNameLabel: Username > canSearchUsers: True > canSearchGroups: True diff --git a/server/src/uds/auths/Sample/SampleAuth.py b/server/src/uds/auths/Sample/SampleAuth.py index c0921759..e9749c04 100644 --- a/server/src/uds/auths/Sample/SampleAuth.py +++ b/server/src/uds/auths/Sample/SampleAuth.py @@ -42,6 +42,7 @@ if typing.TYPE_CHECKING: HttpRequest, HttpResponse, ) # pylint: disable=ungrouped-imports + from uds.core.util.request import ExtendedHttpRequestWithUser logger = logging.getLogger(__name__) @@ -271,7 +272,7 @@ class SampleAuth(auths.Authenticator): return res def authCallback( - self, parameters: typing.Dict[str, typing.Any], gm: 'auths.GroupsManager' + self, parameters: typing.Dict[str, typing.Any], gm: 'auths.GroupsManager', request: 'ExtendedHttpRequestWithUser' ) -> typing.Optional[str]: """ We provide this as a sample of callback for an user. diff --git a/server/src/uds/core/auths/auth.py b/server/src/uds/core/auths/auth.py index bf7db292..ab006c25 100644 --- a/server/src/uds/core/auths/auth.py +++ b/server/src/uds/core/auths/auth.py @@ -290,7 +290,7 @@ def authenticate( def authenticateViaCallback( - authenticator: Authenticator, params: typing.Any + authenticator: Authenticator, params: typing.Any, request: 'ExtendedHttpRequestWithUser' ) -> typing.Optional[User]: """ Given an username, this method will get invoked whenever the url for a callback @@ -317,7 +317,7 @@ def authenticateViaCallback( if authInstance.authCallback is auths.Authenticator.authCallback: raise auths.exceptions.InvalidAuthenticatorException() - username = authInstance.authCallback(params, gm) + username = authInstance.authCallback(params, gm, request) if username is None or username == '' or gm.hasValidGroups() is False: raise auths.exceptions.InvalidUserException('User doesn\'t has access to UDS') diff --git a/server/src/uds/core/auths/authenticator.py b/server/src/uds/core/auths/authenticator.py index 03200829..191b58fb 100644 --- a/server/src/uds/core/auths/authenticator.py +++ b/server/src/uds/core/auths/authenticator.py @@ -44,6 +44,7 @@ if typing.TYPE_CHECKING: HttpResponse, ) # pylint: disable=ungrouped-imports from uds.core.environment import Environment + from uds.core.util.request import ExtendedHttpRequestWithUser from uds import models from .groups_manager import GroupsManager @@ -482,7 +483,10 @@ class Authenticator(Module): # pylint: disable=too-many-public-methods return None def authCallback( - self, parameters: typing.Dict[str, typing.Any], gm: 'GroupsManager' + self, + parameters: typing.Dict[str, typing.Any], + gm: 'GroupsManager', + request: 'ExtendedHttpRequestWithUser', ) -> typing.Optional[str]: """ There is a view inside UDS, an url, that will redirect the petition diff --git a/server/src/uds/core/util/calendar/__init__.py b/server/src/uds/core/util/calendar/__init__.py index a3699b38..bfc36f7c 100644 --- a/server/src/uds/core/util/calendar/__init__.py +++ b/server/src/uds/core/util/calendar/__init__.py @@ -123,7 +123,9 @@ class CalendarChecker: return data - def _updateEvents(self, checkFrom, startEvent=True): + def _updateEvents( + self, checkFrom: datetime.datetime, startEvent: bool = True + ) -> typing.Optional[datetime.datetime]: next_event = None for rule in self.calendar.rules.all(): # logger.debug('RULE: start = {}, checkFrom = {}, end'.format(rule.start.date(), checkFrom.date())) @@ -140,7 +142,7 @@ class CalendarChecker: return next_event - def check(self, dtime=None) -> bool: + def check(self, dtime: typing.Optional[datetime.datetime] = None) -> bool: """ Checks if the given time is a valid event on calendar @param dtime: Datetime object to check @@ -180,16 +182,19 @@ class CalendarChecker: return bool(data[dtime.hour * 60 + dtime.minute]) def nextEvent( - self, checkFrom=None, startEvent=True, offset=None + self, + checkFrom: typing.Optional[datetime.datetime] = None, + startEvent: bool = True, + offset: typing.Optional[datetime.timedelta] = None, ) -> typing.Optional[datetime.datetime]: """ Returns next event for this interval """ logger.debug('Obtaining nextEvent') - if checkFrom is None: + if not checkFrom: checkFrom = getSqlDatetime() - if offset is None: + if not offset: offset = datetime.timedelta(minutes=0) cacheKey = ( @@ -200,13 +205,15 @@ class CalendarChecker: + 'event' + ('x' if startEvent else '_') ) - next_event = CalendarChecker.cache.get(cacheKey, None) - if next_event is None: + next_event: typing.Optional[datetime.datetime] = CalendarChecker.cache.get( + cacheKey, None + ) + if not next_event: logger.debug('Regenerating cached nextEvent') next_event = self._updateEvents( checkFrom + offset, startEvent ) # We substract on checkin, so we can take into account for next execution the "offset" on start & end (just the inverse of current, so we substract it) - if next_event is not None: + if next_event: next_event += offset CalendarChecker.cache.put(cacheKey, next_event, 3600) else: diff --git a/server/src/uds/models/calendar_rule.py b/server/src/uds/models/calendar_rule.py index e6ce3d66..7ddd2281 100644 --- a/server/src/uds/models/calendar_rule.py +++ b/server/src/uds/models/calendar_rule.py @@ -124,7 +124,7 @@ class CalendarRule(UUIDModel): db_table = 'uds_calendar_rules' app_label = 'uds' - def as_rrule(self) -> rules.rrule: + def _rrule(self, atEnd: bool) -> rules.rrule: if self.interval == 0: # Fix 0 intervals self.interval = 1 @@ -133,6 +133,9 @@ class CalendarRule(UUIDModel): datetime.datetime.max.time(), ) + # If at end of interval is requested, displace dstart to match end of interval + dstart = self.start if not atEnd else self.start + datetime.timedelta(minutes=self.duration_as_minutes) + if self.frequency == WEEKDAYS: dw = [] l = self.interval @@ -140,43 +143,19 @@ class CalendarRule(UUIDModel): if l & 1 == 1: dw.append(weekdays[i]) l >>= 1 - return rules.rrule(rules.DAILY, byweekday=dw, dtstart=self.start, until=end) + return rules.rrule(rules.DAILY, byweekday=dw, dtstart=dstart, until=end) return rules.rrule( frq_to_rrl[self.frequency], interval=self.interval, - dtstart=self.start, + dtstart=dstart, until=end, ) + def as_rrule(self) -> rules.rrule: + return self._rrule(False) + def as_rrule_end(self) -> rules.rrule: - if self.interval == 0: # Fix 0 intervals - self.interval = 1 - - end = datetime.datetime.combine( - self.end if self.end is not None else datetime.datetime.max.date(), - datetime.datetime.max.time(), - ) - - if self.frequency == WEEKDAYS: - dw = [] - l = self.interval - for i in range(7): - if l & 1 == 1: - dw.append(weekdays[i]) - l >>= 1 - return rules.rrule( - rules.DAILY, - byweekday=dw, - dtstart=self.start - + datetime.timedelta(minutes=self.duration_as_minutes), - until=end, - ) - return rules.rrule( - frq_to_rrl[self.frequency], - interval=self.interval, - dtstart=self.start + datetime.timedelta(minutes=self.duration_as_minutes), - until=end, - ) + return self._rrule(True) @property def frequency_as_minutes(self) -> int: diff --git a/server/src/uds/web/views/auth.py b/server/src/uds/web/views/auth.py index 739ad683..8fe78bd7 100644 --- a/server/src/uds/web/views/auth.py +++ b/server/src/uds/web/views/auth.py @@ -70,7 +70,7 @@ logger = logging.getLogger(__name__) @csrf_exempt -def authCallback(request: HttpRequest, authName: str) -> HttpResponse: +def authCallback(request: 'ExtendedHttpRequestWithUser', authName: str) -> HttpResponse: """ This url is provided so external SSO authenticators can get an url for redirecting back the users. @@ -113,7 +113,7 @@ def authCallback_stage2( request.session.session_key, ) - user = authenticateViaCallback(authenticator, params) + user = authenticateViaCallback(authenticator, params, request) os = OsDetector.getOsFromUA(request.META['HTTP_USER_AGENT'])