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 7b7d6406..00000000 Binary files a/server/documentation/_build/doctrees/api/index.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/api/models.doctree b/server/documentation/_build/doctrees/api/models.doctree deleted file mode 100644 index 19c20e89..00000000 Binary files a/server/documentation/_build/doctrees/api/models.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/api/models/authentication.doctree b/server/documentation/_build/doctrees/api/models/authentication.doctree deleted file mode 100644 index f19728b3..00000000 Binary files a/server/documentation/_build/doctrees/api/models/authentication.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/api/models/other.doctree b/server/documentation/_build/doctrees/api/models/other.doctree deleted file mode 100644 index f3a1577b..00000000 Binary files a/server/documentation/_build/doctrees/api/models/other.doctree and /dev/null differ 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 ae1c2d68..00000000 Binary files a/server/documentation/_build/doctrees/api/models/services.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/api/models/transport.doctree b/server/documentation/_build/doctrees/api/models/transport.doctree deleted file mode 100644 index 85c06e14..00000000 Binary files a/server/documentation/_build/doctrees/api/models/transport.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/api/modules.doctree b/server/documentation/_build/doctrees/api/modules.doctree deleted file mode 100644 index 6d45f1f5..00000000 Binary files a/server/documentation/_build/doctrees/api/modules.doctree and /dev/null differ 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 7080a1a3..00000000 Binary files a/server/documentation/_build/doctrees/api/modules/AuthenticatorModule.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/api/modules/BaseModule.doctree b/server/documentation/_build/doctrees/api/modules/BaseModule.doctree deleted file mode 100644 index 84259daf..00000000 Binary files a/server/documentation/_build/doctrees/api/modules/BaseModule.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/api/modules/FormFields.doctree b/server/documentation/_build/doctrees/api/modules/FormFields.doctree deleted file mode 100644 index 7b5f924b..00000000 Binary files a/server/documentation/_build/doctrees/api/modules/FormFields.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/api/modules/ServiceModules.doctree b/server/documentation/_build/doctrees/api/modules/ServiceModules.doctree deleted file mode 100644 index 20984c04..00000000 Binary files a/server/documentation/_build/doctrees/api/modules/ServiceModules.doctree and /dev/null differ 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 851ee5bb..00000000 Binary files a/server/documentation/_build/doctrees/api/modules/auths/Authenticator.doctree and /dev/null differ 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 248ac97e..00000000 Binary files a/server/documentation/_build/doctrees/api/modules/services/Exceptions.doctree and /dev/null differ 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 9cf1e234..00000000 Binary files a/server/documentation/_build/doctrees/api/modules/services/Provider.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/api/modules/services/Publication.doctree b/server/documentation/_build/doctrees/api/modules/services/Publication.doctree deleted file mode 100644 index 5c5b34a9..00000000 Binary files a/server/documentation/_build/doctrees/api/modules/services/Publication.doctree and /dev/null differ 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 28180d61..00000000 Binary files a/server/documentation/_build/doctrees/api/modules/services/Service.doctree and /dev/null differ 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 e8e38a9f..00000000 Binary files a/server/documentation/_build/doctrees/api/modules/services/UserDeployment.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/development/architecture.doctree b/server/documentation/_build/doctrees/development/architecture.doctree deleted file mode 100644 index 76cc7a8f..00000000 Binary files a/server/documentation/_build/doctrees/development/architecture.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/development/contributing.doctree b/server/documentation/_build/doctrees/development/contributing.doctree deleted file mode 100644 index 4c0eb2e8..00000000 Binary files a/server/documentation/_build/doctrees/development/contributing.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/development/repository.doctree b/server/documentation/_build/doctrees/development/repository.doctree deleted file mode 100644 index c354c925..00000000 Binary files a/server/documentation/_build/doctrees/development/repository.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/development/samples/auths/Authenticator.doctree b/server/documentation/_build/doctrees/development/samples/auths/Authenticator.doctree deleted file mode 100644 index 7d5b2991..00000000 Binary files a/server/documentation/_build/doctrees/development/samples/auths/Authenticator.doctree and /dev/null differ 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 71dcf9f8..00000000 Binary files a/server/documentation/_build/doctrees/development/samples/samples.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/development/samples/services/DeployedServiceOne.doctree b/server/documentation/_build/doctrees/development/samples/services/DeployedServiceOne.doctree deleted file mode 100644 index 74e2b16b..00000000 Binary files a/server/documentation/_build/doctrees/development/samples/services/DeployedServiceOne.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/development/samples/services/DeployedServiceTwo.doctree b/server/documentation/_build/doctrees/development/samples/services/DeployedServiceTwo.doctree deleted file mode 100644 index 7f93b6a4..00000000 Binary files a/server/documentation/_build/doctrees/development/samples/services/DeployedServiceTwo.doctree and /dev/null differ 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 b7d536d7..00000000 Binary files a/server/documentation/_build/doctrees/development/samples/services/Provider.doctree and /dev/null differ 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 83c7621d..00000000 Binary files a/server/documentation/_build/doctrees/development/samples/services/Publication.doctree and /dev/null differ 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 73216f79..00000000 Binary files a/server/documentation/_build/doctrees/development/samples/services/Service.doctree and /dev/null differ 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 f68c8ab3..00000000 Binary files a/server/documentation/_build/doctrees/development/samples/services/whatisneeded.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/environment.pickle b/server/documentation/_build/doctrees/environment.pickle deleted file mode 100644 index fb96b8b2..00000000 Binary files a/server/documentation/_build/doctrees/environment.pickle and /dev/null differ diff --git a/server/documentation/_build/doctrees/index.doctree b/server/documentation/_build/doctrees/index.doctree deleted file mode 100644 index 753a0ba3..00000000 Binary files a/server/documentation/_build/doctrees/index.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/intro/install.doctree b/server/documentation/_build/doctrees/intro/install.doctree deleted file mode 100644 index 50cc7a95..00000000 Binary files a/server/documentation/_build/doctrees/intro/install.doctree and /dev/null differ diff --git a/server/documentation/_build/doctrees/intro/overview.doctree b/server/documentation/_build/doctrees/intro/overview.doctree deleted file mode 100644 index 20d07925..00000000 Binary files a/server/documentation/_build/doctrees/intro/overview.doctree and /dev/null differ 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 61faf8ca..00000000 Binary files a/server/documentation/_build/html/_static/ajax-loader.gif and /dev/null differ 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 551517b8..00000000 Binary files a/server/documentation/_build/html/_static/comment-bright.png and /dev/null differ diff --git a/server/documentation/_build/html/_static/comment-close.png b/server/documentation/_build/html/_static/comment-close.png deleted file mode 100644 index 09b54be4..00000000 Binary files a/server/documentation/_build/html/_static/comment-close.png and /dev/null differ diff --git a/server/documentation/_build/html/_static/comment.png b/server/documentation/_build/html/_static/comment.png deleted file mode 100644 index 92feb52b..00000000 Binary files a/server/documentation/_build/html/_static/comment.png and /dev/null differ diff --git a/server/documentation/_build/html/_static/contents.png b/server/documentation/_build/html/_static/contents.png deleted file mode 100644 index 7fb82154..00000000 Binary files a/server/documentation/_build/html/_static/contents.png and /dev/null differ diff --git a/server/documentation/_build/html/_static/doctools.js b/server/documentation/_build/html/_static/doctools.js deleted file mode 100644 index c5455c90..00000000 --- a/server/documentation/_build/html/_static/doctools.js +++ /dev/null @@ -1,238 +0,0 @@ -/* - * doctools.js - * ~~~~~~~~~~~ - * - * Sphinx JavaScript utilities for all documentation. - * - * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/** - * select a different prefix for underscore - */ -$u = _.noConflict(); - -/** - * make the code below compatible with browsers without - * an installed firebug like debugger -if (!window.console || !console.firebug) { - var names = ["log", "debug", "info", "warn", "error", "assert", "dir", - "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", - "profile", "profileEnd"]; - window.console = {}; - for (var i = 0; i < names.length; ++i) - window.console[names[i]] = function() {}; -} - */ - -/** - * small helper function to urldecode strings - */ -jQuery.urldecode = function(x) { - return decodeURIComponent(x).replace(/\+/g, ' '); -}; - -/** - * small helper function to urlencode strings - */ -jQuery.urlencode = encodeURIComponent; - -/** - * This function returns the parsed url parameters of the - * current request. Multiple values per key are supported, - * it will always return arrays of strings for the value parts. - */ -jQuery.getQueryParameters = function(s) { - if (typeof s == 'undefined') - s = document.location.search; - var parts = s.substr(s.indexOf('?') + 1).split('&'); - var result = {}; - for (var i = 0; i < parts.length; i++) { - var tmp = parts[i].split('=', 2); - var key = jQuery.urldecode(tmp[0]); - var value = jQuery.urldecode(tmp[1]); - if (key in result) - result[key].push(value); - else - result[key] = [value]; - } - return result; -}; - -/** - * highlight a given string on a jquery object by wrapping it in - * span elements with the given class name. - */ -jQuery.fn.highlightText = function(text, className) { - function highlight(node) { - if (node.nodeType == 3) { - var val = node.nodeValue; - var pos = val.toLowerCase().indexOf(text); - if (pos >= 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 6f7ad782..00000000 Binary files a/server/documentation/_build/html/_static/down-pressed.png and /dev/null differ diff --git a/server/documentation/_build/html/_static/down.png b/server/documentation/_build/html/_static/down.png deleted file mode 100644 index 3003a887..00000000 Binary files a/server/documentation/_build/html/_static/down.png and /dev/null differ diff --git a/server/documentation/_build/html/_static/file.png b/server/documentation/_build/html/_static/file.png deleted file mode 100644 index d18082e3..00000000 Binary files a/server/documentation/_build/html/_static/file.png and /dev/null differ 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 a0fca5cf..00000000 Binary files a/server/documentation/_build/html/objects.inv and /dev/null differ 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 c8560b1d..00000000 Binary files a/server/documentation/_downloads/samples/auths/auth.png and /dev/null differ diff --git a/server/documentation/_downloads/samples/services/SampleProvider.py b/server/documentation/_downloads/samples/services/SampleProvider.py deleted file mode 100644 index 127c5220..00000000 --- a/server/documentation/_downloads/samples/services/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/_downloads/samples/services/SamplePublication.py b/server/documentation/_downloads/samples/services/SamplePublication.py deleted file mode 100644 index f9ccfd5b..00000000 --- a/server/documentation/_downloads/samples/services/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/_downloads/samples/services/SampleService.py b/server/documentation/_downloads/samples/services/SampleService.py deleted file mode 100644 index e38c96f6..00000000 --- a/server/documentation/_downloads/samples/services/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/_downloads/samples/services/SampleUserDeploymentOne.py b/server/documentation/_downloads/samples/services/SampleUserDeploymentOne.py deleted file mode 100644 index e49d4a15..00000000 --- a/server/documentation/_downloads/samples/services/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/_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 d2a954d4..00000000 Binary files a/server/documentation/_downloads/samples/services/provider.png and /dev/null differ diff --git a/server/documentation/_downloads/samples/services/service.png b/server/documentation/_downloads/samples/services/service.png deleted file mode 100644 index c7b626c4..00000000 Binary files a/server/documentation/_downloads/samples/services/service.png and /dev/null differ diff --git a/server/documentation/_images/LogoUDS.png b/server/documentation/_images/LogoUDS.png deleted file mode 100644 index f3196430..00000000 Binary files a/server/documentation/_images/LogoUDS.png and /dev/null differ 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'])