[python-oca] create new repo
This commit is contained in:
commit
b202172a30
|
@ -0,0 +1,8 @@
|
|||
language: python
|
||||
python:
|
||||
- "2.7"
|
||||
- "3.5"
|
||||
|
||||
install:
|
||||
- pip install tox tox-travis
|
||||
script: tox
|
|
@ -0,0 +1,9 @@
|
|||
=========
|
||||
AUTHORS
|
||||
=========
|
||||
|
||||
Łukasz Oleś <lukaszoles@gmail.com>
|
||||
Mattias de Hollander <m.dehollander@nioo.knaw.nl>
|
||||
Matthias Schmitz <matthias@sigxcpu.org>
|
||||
Michael Schmidt <michael@familie-schmidt.com>
|
||||
Sysradium <sysradium@users.noreply.github.com>
|
|
@ -0,0 +1,5 @@
|
|||
include README.rst
|
||||
recursive-include docs *
|
||||
recursive-include oca *
|
||||
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
##############################################
|
||||
OCA - OpenNebula Cloud Api
|
||||
##############################################
|
||||
|
||||
:Version: 4.10.0
|
||||
:TravisCI Status:
|
||||
.. image:: https://travis-ci.org/python-oca/python-oca.svg
|
||||
:target: https://travis-ci.org/python-oca/python-oca
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
Bindings for XMLRPC OpenNebula Cloud API
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
See http://python-oca.github.io/python-oca/index.html and http://docs.opennebula.org/4.10/integration/system_interfaces/api.html
|
||||
|
||||
All `allocate` functions are implemented as static methods.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Show all running virtual machines::
|
||||
|
||||
client = oca.Client('user:password', 'http://12.12.12.12:2633/RPC2')
|
||||
vm_pool = oca.VirtualMachinePool(client)
|
||||
vm_pool.info()
|
||||
|
||||
for vm in vm_pool:
|
||||
ip_list = ', '.join(v.ip for v in vm.template.nics)
|
||||
print("{} {} {} (memory: {} MB)".format(vm.name, ip_list, vm.str_state, vm.template.memory))
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
OCA is under Apache Software License
|
||||
|
||||
Authors
|
||||
-------
|
||||
|
||||
See AUTHORS file
|
|
@ -0,0 +1,130 @@
|
|||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
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) .
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> 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 " 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/oca.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/oca.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/oca"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/oca"
|
||||
@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."
|
||||
|
||||
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."
|
|
@ -0,0 +1,17 @@
|
|||
API Documentation
|
||||
=================
|
||||
|
||||
See http://docs.opennebula.org/4.10/integration/system_interfaces/api.html
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
api/client
|
||||
api/host
|
||||
api/image
|
||||
api/vn
|
||||
api/user
|
||||
api/group
|
||||
api/template
|
||||
api/vm
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
.. _oca module:
|
||||
|
||||
:mod:`oca.Client`
|
||||
--------------------------------
|
||||
|
||||
.. autoclass:: oca.Client
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
.. _group module:
|
||||
|
||||
:mod:`oca.group`
|
||||
--------------------------------
|
||||
|
||||
.. autoclass:: oca.Group
|
||||
.. autoclass:: oca.GroupPool
|
||||
:members: info
|
||||
:no-inherited-members:
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
.. _host module:
|
||||
|
||||
:mod:`oca.host`
|
||||
--------------------------------
|
||||
|
||||
.. autoclass:: oca.Host
|
||||
.. autoclass:: oca.HostPool
|
||||
:members: info
|
||||
:no-inherited-members:
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
.. _image module:
|
||||
|
||||
:mod:`oca.image`
|
||||
--------------------------------
|
||||
|
||||
.. autoclass:: oca.Image
|
||||
.. autoclass:: oca.ImagePool
|
||||
:members: info
|
||||
:no-inherited-members:
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
.. _template module:
|
||||
|
||||
:mod:`oca.template`
|
||||
--------------------------------
|
||||
|
||||
.. autoclass:: oca.VmTemplate
|
||||
.. autoclass:: oca.VmTemplatePool
|
||||
:members: info
|
||||
:no-inherited-members:
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
.. _user module:
|
||||
|
||||
:mod:`oca.user`
|
||||
--------------------------------
|
||||
|
||||
.. autoclass:: oca.User
|
||||
.. autoclass:: oca.UserPool
|
||||
:members: info
|
||||
:no-inherited-members:
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
.. _virtualmachine module:
|
||||
|
||||
:mod:`oca.virtualmachine`
|
||||
--------------------------------
|
||||
|
||||
.. autoclass:: oca.VirtualMachine
|
||||
:members:
|
||||
.. autoclass:: oca.VirtualMachinePool
|
||||
:members: info
|
||||
:no-inherited-members:
|
|
@ -0,0 +1,11 @@
|
|||
.. _virtualnetwork module:
|
||||
|
||||
:mod:`oca.virtualnetwork`
|
||||
--------------------------------
|
||||
|
||||
.. autoclass:: oca.VirtualNetwork
|
||||
:members:
|
||||
|
||||
.. autoclass:: oca.VirtualNetworkPool
|
||||
:members: info
|
||||
:no-inherited-members:
|
|
@ -0,0 +1,218 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# oca documentation build configuration file, created by
|
||||
# sphinx-quickstart on Sat Dec 11 00:53:18 2010.
|
||||
#
|
||||
# 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('.'))
|
||||
|
||||
# -- 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.todo', 'sphinx.ext.coverage', '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'oca'
|
||||
copyright = u'2010-2015, Python OCA authors'
|
||||
|
||||
# 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 = '4.10.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '4.10.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.
|
||||
html_theme = 'default'
|
||||
|
||||
# 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 = {}
|
||||
|
||||
# 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
|
||||
# "<project> v<release> 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 <link> 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 = 'ocadoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
# The paper size ('letter' or 'a4').
|
||||
#latex_paper_size = 'letter'
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#latex_font_size = '10pt'
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'oca.tex', u'oca Documentation',
|
||||
u'Łukasz Oleś', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# 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 = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#latex_preamble = ''
|
||||
|
||||
# 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', 'oca', u'oca Documentation',
|
||||
[u'Łukasz Oleś'], 1)
|
||||
]
|
||||
|
||||
autodoc_default_flags = ['members', 'undoc-members', 'inherited-members', 'show-inheritance']
|
|
@ -0,0 +1,23 @@
|
|||
.. oca documentation master file, created by
|
||||
sphinx-quickstart on Sat Dec 11 00:53:18 2010.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to oca's documentation!
|
||||
===============================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
user_guide
|
||||
api
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
@ECHO OFF
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set BUILDDIR=_build
|
||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
|
||||
if NOT "%PAPER%" == "" (
|
||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo.Please use `make ^<target^>` where ^<target^> 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. 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\oca.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\oca.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" == "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
|
|
@ -0,0 +1,17 @@
|
|||
User Guide
|
||||
==========
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Allocating new host::
|
||||
|
||||
import oca
|
||||
client = oca.Client('user:password', 'http:12.12.12.12:2633/RPC2')
|
||||
new_host_id = oca.Host.allocate(client, 'host_name', 'im_xen', 'vmm_xen', 'tm_nfs')
|
||||
hostpool = oca.HostPool(client)
|
||||
hostpool.info()
|
||||
vm = hostpool.get_by_id(new_host_id)
|
||||
print vm.name, vm.str_state
|
||||
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import http.client
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import socket
|
||||
import xmlrpc.client
|
||||
|
||||
from .cluster import Cluster, ClusterPool
|
||||
from .datastore import Datastore, DatastorePool
|
||||
from .exceptions import OpenNebulaException
|
||||
from .group import Group, GroupPool
|
||||
from .host import Host, HostPool
|
||||
from .image import Image, ImagePool
|
||||
from .template import VmTemplate, VmTemplatePool
|
||||
from .user import User, UserPool
|
||||
from .vm import VirtualMachine, VirtualMachinePool
|
||||
from .vn import VirtualNetwork, VirtualNetworkPool
|
||||
|
||||
CONNECTED = -3
|
||||
ALL = -2
|
||||
CONNECTED_AND_GROUP = -1
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TimeoutHTTPConnection(http.client.HTTPConnection):
|
||||
def connect(self):
|
||||
http.client.HTTPConnection.connect(self)
|
||||
self.sock.settimeout(self.timeout)
|
||||
|
||||
|
||||
class TimeoutHTTP(http.client.HTTPConnection):
|
||||
_connection_class = TimeoutHTTPConnection
|
||||
|
||||
def set_timeout(self, timeout):
|
||||
self._conn.timeout = timeout
|
||||
|
||||
|
||||
class ProxiedTransport(xmlrpc.client.Transport):
|
||||
def __init__(self, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, *args, **kwargs):
|
||||
xmlrpc.client.Transport.__init__(self, *args, **kwargs)
|
||||
self.timeout = timeout
|
||||
|
||||
def set_proxy(self, proxy):
|
||||
self.proxy = proxy
|
||||
|
||||
def make_connection(self, host):
|
||||
self.realhost = host
|
||||
h = http.client.HTTPConnection(self.proxy)
|
||||
return h
|
||||
|
||||
def send_request(self, connection, handler, request_body):
|
||||
connection.putrequest("POST", 'http://%s%s' % (self.realhost, handler))
|
||||
|
||||
def send_host(self, connection, host):
|
||||
connection.putheader('Host', self.realhost)
|
||||
|
||||
|
||||
class Client(object):
|
||||
"""
|
||||
The client class, represents the connection with the core and handles the
|
||||
xml-rpc calls(see http://www.opennebula.org/documentation:rel3.2:api)
|
||||
"""
|
||||
DEFAULT_ONE_AUTH = "~/.one/one_auth"
|
||||
ONE_AUTH_RE = re.compile('^(.+?):(.+)$')
|
||||
DEFAULT_ONE_ADDRESS = "http://localhost:2633/RPC2"
|
||||
|
||||
def __init__(self, secret=None, address=None, proxy=None):
|
||||
self.one_version = None
|
||||
|
||||
if secret:
|
||||
one_secret = secret
|
||||
elif "ONE_AUTH" in os.environ and os.environ["ONE_AUTH"]:
|
||||
one_auth = os.path.expanduser(os.environ["ONE_AUTH"])
|
||||
with open(one_auth) as f:
|
||||
one_secret = f.read().strip()
|
||||
elif os.path.exists(os.path.expanduser(self.DEFAULT_ONE_AUTH)):
|
||||
with open(os.path.expanduser(self.DEFAULT_ONE_AUTH)) as f:
|
||||
one_secret = f.read().strip()
|
||||
else:
|
||||
raise OpenNebulaException('ONE_AUTH file not present')
|
||||
|
||||
one_secret = self.ONE_AUTH_RE.match(one_secret)
|
||||
if one_secret:
|
||||
user = one_secret.groups()[0]
|
||||
password = one_secret.groups()[1]
|
||||
else:
|
||||
raise OpenNebulaException("Authorization file malformed")
|
||||
|
||||
self.one_auth = '{0}:{1}'.format(user, password)
|
||||
|
||||
if address:
|
||||
self.one_address = address
|
||||
elif "ONE_XMLRPC" in os.environ and os.environ["ONE_XMLRPC"]:
|
||||
self.one_address = os.environ["ONE_XMLRPC"]
|
||||
else:
|
||||
self.one_address = self.DEFAULT_ONE_ADDRESS
|
||||
|
||||
if proxy:
|
||||
p = ProxiedTransport(timeout=100)
|
||||
p.set_proxy(proxy)
|
||||
self.server = xmlrpc.client.ServerProxy(self.one_address, transport=p)
|
||||
else:
|
||||
self.server = xmlrpc.client.ServerProxy(self.one_address)
|
||||
|
||||
def call(self, function, *args):
|
||||
"""
|
||||
Calls rpc function.
|
||||
|
||||
Arguments
|
||||
|
||||
``function``
|
||||
OpenNebula xmlrpc funtcion name (without preceding 'one.')
|
||||
|
||||
``args``
|
||||
function arguments
|
||||
|
||||
"""
|
||||
try:
|
||||
func = getattr(self.server.one, function)
|
||||
ret = func(self.one_auth, *args)
|
||||
try:
|
||||
is_success, data, return_code = ret
|
||||
except ValueError:
|
||||
logger.error(
|
||||
"""Called function: {function}
|
||||
arguments: {args}
|
||||
Return value = {ret}"""
|
||||
.format(
|
||||
function=function, args=str(args),
|
||||
ret=str(ret)
|
||||
)
|
||||
)
|
||||
data = ''
|
||||
is_success = False
|
||||
except socket.error as e:
|
||||
# connection error
|
||||
raise e
|
||||
if not is_success:
|
||||
raise OpenNebulaException(data)
|
||||
return data
|
||||
|
||||
def version(self):
|
||||
"""
|
||||
Get the version of the connected OpenNebula server.
|
||||
"""
|
||||
self.one_version = self.call('system.version')
|
||||
return self.one_version
|
||||
|
||||
|
||||
__all__ = [Client, OpenNebulaException, Host, HostPool, VirtualMachine,
|
||||
VirtualMachinePool, User, UserPool,
|
||||
Image, ImagePool, VirtualNetwork, VirtualNetworkPool,
|
||||
Group, GroupPool, VmTemplate, VmTemplatePool, ALL, CONNECTED,
|
||||
Cluster, ClusterPool, Datastore, DatastorePool]
|
|
@ -0,0 +1 @@
|
|||
# -*- coding: UTF-8 -*-
|
|
@ -0,0 +1,56 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
from .pool import Pool, PoolElement, Template, extractString
|
||||
|
||||
|
||||
class Cluster(PoolElement):
|
||||
METHODS = {
|
||||
# 'info' : 'cluster.info',
|
||||
'allocate': 'cluster.allocate',
|
||||
'delete': 'cluster.delete',
|
||||
# 'enable' : 'cluster.enable',
|
||||
# 'update' : 'cluster.update'
|
||||
}
|
||||
|
||||
XML_TYPES = {
|
||||
'id': int,
|
||||
'name': extractString,
|
||||
'host_ids': ['HOSTS', lambda hosts: [int(host_id.text) for host_id in hosts]],
|
||||
'datastore_ids': ['DATASTORES', lambda datastores: [int(datastore_id.text) for datastore_id in datastores]],
|
||||
'vnet_ids': ['VNETS', lambda vnets: [int(vnet_id.text) for vnet_id in vnets]],
|
||||
'template': ['TEMPLATE', Template],
|
||||
}
|
||||
|
||||
ELEMENT_NAME = 'CLUSTER'
|
||||
|
||||
@staticmethod
|
||||
def allocate(client, cluster_name):
|
||||
"""
|
||||
Adds a cluster to the cluster list
|
||||
|
||||
Arguments
|
||||
|
||||
``cluster_name``
|
||||
Clustername to add
|
||||
"""
|
||||
cluster_id = client.call(Cluster.METHODS['allocate'], cluster_name)
|
||||
return cluster_id
|
||||
|
||||
def __init__(self, xml, client):
|
||||
super(Cluster, self).__init__(xml, client)
|
||||
self._convert_types()
|
||||
|
||||
def __repr__(self):
|
||||
return '<oca.Cluster("%s")>' % self.name
|
||||
|
||||
|
||||
class ClusterPool(Pool):
|
||||
METHODS = {
|
||||
'info': 'clusterpool.info',
|
||||
}
|
||||
|
||||
def __init__(self, client):
|
||||
super(ClusterPool, self).__init__('CLUSTER_POOL', 'CLUSTER', client)
|
||||
|
||||
def _factory(self, xml):
|
||||
c = Cluster(xml, self.client)
|
||||
return c
|
|
@ -0,0 +1,71 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
from .pool import Pool, PoolElement, Template, extractString
|
||||
|
||||
|
||||
class Datastore(PoolElement):
|
||||
METHODS = {
|
||||
# 'info' : 'datastore.info',
|
||||
'allocate': 'datastore.allocate',
|
||||
'delete': 'datastore.delete',
|
||||
# 'enable' : 'datastore.enable',
|
||||
# 'update' : 'datastore.update'
|
||||
}
|
||||
|
||||
XML_TYPES = {
|
||||
'id': int,
|
||||
'name': extractString,
|
||||
'uid': int,
|
||||
'gid': int,
|
||||
'uname': extractString,
|
||||
'gname': extractString,
|
||||
# 'permissions' : Permissions,
|
||||
'ds_mad': extractString,
|
||||
'tm_mad': extractString,
|
||||
'base_path': extractString,
|
||||
'type': int,
|
||||
'disk_type': int,
|
||||
# 'state' : ???,
|
||||
# 'cluster_id': int,
|
||||
'cluster_ids': ['CLUSTERS', lambda clusters: [int(cluster_id.text) for cluster_id in clusters]],
|
||||
# 'cluster': extractString,
|
||||
'total_mb': int,
|
||||
'free_mb': int,
|
||||
'used_mb': int,
|
||||
'image_ids': ['IMAGES', lambda images: [int(image_id.text) for image_id in images]],
|
||||
'template': ['TEMPLATE', Template],
|
||||
}
|
||||
|
||||
ELEMENT_NAME = 'DATASTORE'
|
||||
|
||||
@staticmethod
|
||||
def allocate(client, datastore_template):
|
||||
"""
|
||||
Adds a datastore to the datastore list
|
||||
|
||||
Arguments
|
||||
|
||||
``datastore_template``
|
||||
Template for the datastore to add
|
||||
"""
|
||||
datastore_id = client.call(Datastore.METHODS['allocate'], datastore_template)
|
||||
return datastore_id
|
||||
|
||||
def __init__(self, xml, client):
|
||||
super(Datastore, self).__init__(xml, client)
|
||||
self._convert_types()
|
||||
|
||||
def __repr__(self):
|
||||
return '<oca.Datastore("%s")>' % self.name
|
||||
|
||||
|
||||
class DatastorePool(Pool):
|
||||
METHODS = {
|
||||
'info': 'datastorepool.info',
|
||||
}
|
||||
|
||||
def __init__(self, client):
|
||||
super(DatastorePool, self).__init__('DATASTORE_POOL', 'DATASTORE', client)
|
||||
|
||||
def _factory(self, xml):
|
||||
c = Datastore(xml, self.client)
|
||||
return c
|
|
@ -0,0 +1,5 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
|
||||
|
||||
class OpenNebulaException(Exception):
|
||||
pass
|
|
@ -0,0 +1,62 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
from .pool import Pool, PoolElement, Template, extractString
|
||||
|
||||
|
||||
class Group(PoolElement):
|
||||
METHODS = {
|
||||
'info': 'group.info',
|
||||
'allocate': 'group.allocate',
|
||||
'delete': 'group.delete',
|
||||
}
|
||||
|
||||
XML_TYPES = {
|
||||
'id': int,
|
||||
'name': extractString,
|
||||
'template': ['TEMPLATE', Template],
|
||||
'users': ['USERS', lambda users: [int(i.text) for i in users]],
|
||||
# 'resource_providers': handled separately
|
||||
# 'datastore_quota': handled separately
|
||||
# 'network_quota': handled separately
|
||||
# 'vm_quota': handled separately
|
||||
# 'image_quota'
|
||||
# 'default_group_quotas'
|
||||
}
|
||||
|
||||
ELEMENT_NAME = 'GROUP'
|
||||
|
||||
@staticmethod
|
||||
def allocate(client, group_name):
|
||||
"""
|
||||
Allocates a new group in OpenNebula
|
||||
|
||||
Arguments
|
||||
|
||||
``client``
|
||||
oca.Client object
|
||||
|
||||
``group``
|
||||
a string containing the group name
|
||||
"""
|
||||
group_id = client.call(Group.METHODS['allocate'], group_name)
|
||||
return group_id
|
||||
|
||||
def __init__(self, xml, client):
|
||||
super(Group, self).__init__(xml, client)
|
||||
self.id = self['ID'] if self['ID'] else None
|
||||
|
||||
def __repr__(self):
|
||||
return '<oca.Group("%s")>' % self.name
|
||||
|
||||
|
||||
class GroupPool(Pool):
|
||||
METHODS = {
|
||||
'info': 'grouppool.info',
|
||||
}
|
||||
|
||||
def __init__(self, client):
|
||||
super(GroupPool, self).__init__('GROUP_POOL', 'GROUP', client)
|
||||
|
||||
def _factory(self, xml):
|
||||
i = Group(xml, self.client)
|
||||
i._convert_types()
|
||||
return i
|
|
@ -0,0 +1,140 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
from .pool import Pool, PoolElement, Template, extractString
|
||||
|
||||
|
||||
class HostShare(Template):
|
||||
def __repr__(self):
|
||||
return '<oca.vm.HostShare()>'
|
||||
|
||||
|
||||
class Host(PoolElement):
|
||||
METHODS = {
|
||||
'info': 'host.info',
|
||||
'allocate': 'host.allocate',
|
||||
'delete': 'host.delete',
|
||||
'enable': 'host.enable',
|
||||
'update': 'host.update'
|
||||
}
|
||||
|
||||
INIT = 0
|
||||
MONITORING_MONITORED = 1 # Currently monitoring, previously MONITORED
|
||||
MONITORED = 2
|
||||
ERROR = 3
|
||||
DISABLED = 4
|
||||
MONITORING_ERROR = 5 # Currently monitoring, previously ERROR
|
||||
MONITORING_INIT = 6 # Currently monitoring, previously initialized
|
||||
MONITORING_DISABLED = 7 # Currently monitoring, previously DISABLED
|
||||
HOST_STATES = ['INIT', 'MONITORING_MONITORED', 'MONITORED', 'ERROR', 'DISABLED',
|
||||
'MONITORING_ERROR', 'MONITORING_INIT', 'MONITORING_DISABLED']
|
||||
|
||||
SHORT_HOST_STATES = {
|
||||
'INIT': 'on',
|
||||
'MONITORING_MONITORED': 'on',
|
||||
'MONITORED': 'on',
|
||||
'ERROR': 'err',
|
||||
'DISABLED': 'off',
|
||||
'MONITORING_ERROR': 'on',
|
||||
'MONITORING_INIT': 'on',
|
||||
'MONITORING_DISABLED': 'on',
|
||||
}
|
||||
|
||||
XML_TYPES = {
|
||||
'id': int,
|
||||
'name': extractString,
|
||||
'state': int,
|
||||
'im_mad': extractString,
|
||||
'vm_mad': extractString,
|
||||
'vn_mad': extractString,
|
||||
'last_mon_time': int,
|
||||
'cluster': extractString,
|
||||
'cluster_id': int,
|
||||
'vm_ids': ['VMS', lambda vms: [int(vmid.text) for vmid in vms]],
|
||||
'template': ['TEMPLATE', Template],
|
||||
'host_share': ['HOST_SHARE', HostShare],
|
||||
}
|
||||
|
||||
ELEMENT_NAME = 'HOST'
|
||||
|
||||
@staticmethod
|
||||
def allocate(client, hostname, im, vmm, tm, cluster_id=-1):
|
||||
"""
|
||||
Adds a host to the host list
|
||||
|
||||
Arguments
|
||||
|
||||
``hostname``
|
||||
Hostname machine to add
|
||||
|
||||
``im``
|
||||
Information manager'
|
||||
|
||||
``vmm``
|
||||
Virtual machine manager.
|
||||
|
||||
``tm``
|
||||
Transfer manager
|
||||
"""
|
||||
host_id = client.call(Host.METHODS['allocate'], hostname, im, vmm, tm, cluster_id)
|
||||
return host_id
|
||||
|
||||
def __init__(self, xml, client):
|
||||
# remove 'vn_mad' attribute in OpenNebula >= 5
|
||||
xml_types = Host.XML_TYPES
|
||||
if client.one_version is None:
|
||||
client.version()
|
||||
if client.one_version >= '5' and 'vn_mad' in xml_types:
|
||||
del xml_types['vn_mad']
|
||||
|
||||
super(Host, self).__init__(xml, client)
|
||||
self.id = self['ID'] if self['ID'] else None
|
||||
|
||||
def enable(self):
|
||||
"""
|
||||
Enable this host
|
||||
"""
|
||||
self.client.call(self.METHODS['enable'], self.id, True)
|
||||
|
||||
def disable(self):
|
||||
"""
|
||||
Disable this host.
|
||||
"""
|
||||
self.client.call(self.METHODS['enable'], self.id, False)
|
||||
|
||||
def update(self, template, merge=False):
|
||||
"""
|
||||
Update the template of this host. If merge is false (default),
|
||||
the existing template is replaced.
|
||||
"""
|
||||
self.client.call(self.METHODS['update'], self.id, template, 1 if merge else 0)
|
||||
|
||||
@property
|
||||
def str_state(self):
|
||||
"""
|
||||
String representation of host state.
|
||||
One of 'INIT', 'MONITORING', 'MONITORED', 'ERROR', 'DISABLED'
|
||||
"""
|
||||
return self.HOST_STATES[int(self.state)]
|
||||
|
||||
@property
|
||||
def short_state(self):
|
||||
"""
|
||||
Short string representation of host state. One of 'on', 'off', 'err'
|
||||
"""
|
||||
return self.SHORT_HOST_STATES[self.str_state]
|
||||
|
||||
def __repr__(self):
|
||||
return '<oca.Host("%s")>' % self.name
|
||||
|
||||
|
||||
class HostPool(Pool):
|
||||
METHODS = {
|
||||
'info': 'hostpool.info',
|
||||
}
|
||||
|
||||
def __init__(self, client):
|
||||
super(HostPool, self).__init__('HOST_POOL', 'HOST', client)
|
||||
|
||||
def _factory(self, xml):
|
||||
h = Host(xml, self.client)
|
||||
h._convert_types()
|
||||
return h
|
|
@ -0,0 +1,241 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
from .pool import Pool, PoolElement, Template, extractString
|
||||
|
||||
|
||||
class Image(PoolElement):
|
||||
METHODS = {
|
||||
'info': 'image.info',
|
||||
'allocate': 'image.allocate',
|
||||
'delete': 'image.delete',
|
||||
'update': 'image.update',
|
||||
'enable': 'image.enable',
|
||||
'publish': 'image.publish',
|
||||
'chmod': 'image.chmod',
|
||||
'chown': 'image.chown',
|
||||
'persistent': 'image.persistent',
|
||||
'clone': 'image.clone',
|
||||
}
|
||||
|
||||
XML_TYPES = {
|
||||
'id': int,
|
||||
'uid': int,
|
||||
'gid': int,
|
||||
'uname': extractString,
|
||||
'gname': extractString,
|
||||
'name': extractString,
|
||||
# 'permissions' : ???,
|
||||
'type': int,
|
||||
'disk_type': int,
|
||||
'persistent': int,
|
||||
'regtime': int,
|
||||
'source': extractString,
|
||||
'path': extractString,
|
||||
'fstype': extractString,
|
||||
'size': int,
|
||||
'state': int,
|
||||
'running_vms': int,
|
||||
'cloning_ops': int,
|
||||
'cloning_id': int,
|
||||
'datastore_id': int,
|
||||
'datastore': extractString,
|
||||
'vm_ids': ["VMS", lambda vms: [int(vm_id.text) for vm_id in vms]],
|
||||
'clone_ids': ["CLONES", lambda clones: [int(clone_id.text) for clone_id in clones]],
|
||||
'template': ['TEMPLATE', Template],
|
||||
}
|
||||
|
||||
INIT = 0
|
||||
READY = 1
|
||||
USED = 2
|
||||
DISABLED = 3
|
||||
IMAGE_STATES = ['INIT', 'READY', 'USED', 'DISABLED', 'LOCKED', 'ERROR', 'CLONE', 'DELETE', 'USED_PERS']
|
||||
|
||||
SHORT_IMAGE_STATES = {
|
||||
"INIT": "init",
|
||||
"READY": "rdy",
|
||||
"USED": "used",
|
||||
"DISABLED": "disa",
|
||||
"LOCKED": "lock",
|
||||
"ERROR": "err",
|
||||
"CLONE": "clon",
|
||||
"DELETE": "dele",
|
||||
"USED_PERS": "used"
|
||||
}
|
||||
|
||||
IMAGE_TYPES = ['OS', 'CDROM', 'DATABLOCK']
|
||||
|
||||
SHORT_IMAGE_TYPES = {
|
||||
"OS": "OS",
|
||||
"CDROM": "CD",
|
||||
"DATABLOCK": "DB"
|
||||
}
|
||||
|
||||
ELEMENT_NAME = 'IMAGE'
|
||||
|
||||
@staticmethod
|
||||
def allocate(client, template, datastore):
|
||||
"""
|
||||
Allocates a new image in OpenNebula
|
||||
|
||||
Arguments
|
||||
|
||||
``client``
|
||||
oca.Client object
|
||||
|
||||
``template``
|
||||
a string containing the template of the image
|
||||
``datastore``
|
||||
the datastore id where the image is to be allocated
|
||||
"""
|
||||
image_id = client.call(Image.METHODS['allocate'], template, datastore)
|
||||
return image_id
|
||||
|
||||
def __init__(self, xml, client):
|
||||
super(Image, self).__init__(xml, client)
|
||||
self.id = self['ID'] if self['ID'] else None
|
||||
|
||||
def update(self, template):
|
||||
"""
|
||||
Replaces the template contents
|
||||
|
||||
Arguments
|
||||
|
||||
``template``
|
||||
New template contents
|
||||
"""
|
||||
self.client.call(self.METHODS['update'], self.id, template)
|
||||
|
||||
def enable(self):
|
||||
"""
|
||||
Enables an image
|
||||
"""
|
||||
self.client.call(self.METHODS['enable'], self.id, True)
|
||||
|
||||
def disable(self):
|
||||
"""
|
||||
Disables an image
|
||||
"""
|
||||
self.client.call(self.METHODS['enable'], self.id, False)
|
||||
|
||||
def publish(self):
|
||||
"""
|
||||
Publishes an image
|
||||
"""
|
||||
self.client.call(self.METHODS['publish'], self.id, True)
|
||||
|
||||
def unpublish(self):
|
||||
"""
|
||||
Unpublishes an image
|
||||
"""
|
||||
self.client.call(self.METHODS['publish'], self.id, False)
|
||||
|
||||
def set_persistent(self):
|
||||
"""
|
||||
Set Image as persistent
|
||||
"""
|
||||
self.client.call(self.METHODS['persistent'], self.id, True)
|
||||
|
||||
def set_nonpersistent(self):
|
||||
"""
|
||||
Set Image as non persistent
|
||||
"""
|
||||
self.client.call(self.METHODS['persistent'], self.id, False)
|
||||
|
||||
def chown(self, uid, gid):
|
||||
"""
|
||||
Changes the owner/group
|
||||
|
||||
Arguments
|
||||
|
||||
``uid``
|
||||
New owner id. Set to -1 to leave current value
|
||||
``gid``
|
||||
New group id. Set to -1 to leave current value
|
||||
"""
|
||||
self.client.call(self.METHODS['chown'], self.id, uid, gid)
|
||||
|
||||
def chmod(self, owner_u, owner_m, owner_a, group_u, group_m, group_a, other_u, other_m, other_a):
|
||||
"""
|
||||
Changes the permission bits
|
||||
|
||||
Arguments
|
||||
|
||||
``owner_u``
|
||||
User USE bit. Set to -1 to leave current value
|
||||
``owner_m``
|
||||
User MANAGE bit. Set to -1 to leave current value
|
||||
``owner_a``
|
||||
User ADMIN bit. Set to -1 to leave current value
|
||||
``group_u``
|
||||
Group USE bit. Set to -1 to leave current value
|
||||
``group_m``
|
||||
Group MANAGE bit. Set to -1 to leave current value
|
||||
``group_a``
|
||||
Group ADMIN bit. Set to -1 to leave current value
|
||||
``other_u``
|
||||
Other USE bit. Set to -1 to leave current value
|
||||
``other_m``
|
||||
Other MANAGE bit. Set to -1 to leave current value
|
||||
``other_a``
|
||||
Other ADMIN bit. Set to -1 to leave current value
|
||||
"""
|
||||
self.client.call(self.METHODS['chmod'], self.id, owner_u, owner_m, owner_a, group_u, group_m, group_a, other_u,
|
||||
other_m, other_a)
|
||||
|
||||
def clone(self, name='', datastore_id=-1):
|
||||
"""
|
||||
Creates a clone of an image
|
||||
``name``
|
||||
name of a target element
|
||||
``datastore_id``
|
||||
The ID of the target datastore. Optional, can be set to -1 to use the current one.
|
||||
"""
|
||||
self.client.call(self.METHODS['clone'], self.id, name, datastore_id)
|
||||
|
||||
@property
|
||||
def str_state(self):
|
||||
"""
|
||||
String representation of image state.
|
||||
One of 'INIT', 'READY', 'USED', 'DISABLED', 'LOCKED', 'ERROR', 'CLONE', 'DELETE', 'USED_PERS'
|
||||
"""
|
||||
return self.IMAGE_STATES[int(self.state)]
|
||||
|
||||
@property
|
||||
def short_state(self):
|
||||
"""
|
||||
Short string representation of image state.
|
||||
One of 'init', 'rdy', 'used', 'disa', 'lock', 'err', 'clon', 'dele', 'used'
|
||||
"""
|
||||
return self.SHORT_IMAGE_STATES[self.str_state]
|
||||
|
||||
@property
|
||||
def str_type(self):
|
||||
"""
|
||||
String representation of image type.
|
||||
One of 'OS', 'CDROM', 'DATABLOCK'
|
||||
"""
|
||||
return self.IMAGE_TYPES[int(self.type)]
|
||||
|
||||
@property
|
||||
def short_type(self):
|
||||
"""
|
||||
Short string representation of image type.
|
||||
One of 'OS', 'CD', 'DB'
|
||||
"""
|
||||
return self.SHORT_IMAGE_TYPES[self.str_type]
|
||||
|
||||
def __repr__(self):
|
||||
return '<oca.Image("%s")>' % self.name
|
||||
|
||||
|
||||
class ImagePool(Pool):
|
||||
METHODS = {
|
||||
'info': 'imagepool.info',
|
||||
}
|
||||
|
||||
def __init__(self, client):
|
||||
super(ImagePool, self).__init__('IMAGE_POOL', 'IMAGE', client)
|
||||
|
||||
def _factory(self, xml):
|
||||
i = Image(xml, self.client)
|
||||
i._convert_types()
|
||||
return i
|
|
@ -0,0 +1,177 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from .exceptions import OpenNebulaException
|
||||
|
||||
|
||||
class WrongNameError(OpenNebulaException):
|
||||
pass
|
||||
|
||||
|
||||
class WrongIdError(OpenNebulaException):
|
||||
pass
|
||||
|
||||
|
||||
def extractString(xml_or_string):
|
||||
if isinstance(xml_or_string, str):
|
||||
return xml_or_string
|
||||
|
||||
# Py2 compatibility
|
||||
try:
|
||||
if isinstance(xml_or_string, unicode):
|
||||
return xml_or_string
|
||||
except NameError:
|
||||
pass
|
||||
|
||||
return xml_or_string.text or ''
|
||||
|
||||
|
||||
class Template(object):
|
||||
def __init__(self, xml_element, multiple=[]):
|
||||
self.xml = ET.tostring(xml_element)
|
||||
self.xml_element = xml_element
|
||||
self.multiple = multiple
|
||||
self.parse()
|
||||
|
||||
def parse(self):
|
||||
for element in self.xml_element:
|
||||
tag = element.tag
|
||||
if tag in self.multiple:
|
||||
self.parse_multiple(tag, element)
|
||||
else:
|
||||
setattr(self, tag.lower(), element.text)
|
||||
|
||||
def parse_multiple(self, tag, element):
|
||||
attr = tag.lower() + 's'
|
||||
attr_list = getattr(self, attr, [])
|
||||
|
||||
class_obj = type(tag.capitalize(), (Template,), {})
|
||||
|
||||
attr_list.append(class_obj(element))
|
||||
setattr(self, attr, attr_list)
|
||||
|
||||
|
||||
class XMLElement(object):
|
||||
XML_TYPES = {}
|
||||
|
||||
def __init__(self, xml=None):
|
||||
if not (xml is None or ET.iselement(xml)):
|
||||
xml = ET.fromstring(xml)
|
||||
self.xml = xml
|
||||
|
||||
def _initialize_xml(self, xml, root_element):
|
||||
self.xml = ET.fromstring(xml.encode('utf-8'))
|
||||
if self.xml.tag != root_element.upper():
|
||||
self.xml = None
|
||||
self._convert_types()
|
||||
|
||||
def __getitem__(self, key):
|
||||
value = self.xml.find(key.upper())
|
||||
if value is not None:
|
||||
if value.text:
|
||||
return value.text
|
||||
else:
|
||||
return value
|
||||
else:
|
||||
raise IndexError("Key {0} not found!".format(key))
|
||||
|
||||
def __getattr__(self, name):
|
||||
try:
|
||||
return self[name]
|
||||
except (IndexError, TypeError):
|
||||
raise AttributeError(name)
|
||||
|
||||
def _convert_types(self):
|
||||
for name, fun in self.XML_TYPES.items():
|
||||
if isinstance(fun, list):
|
||||
tag, cls = fun[0], fun[1]
|
||||
xml = self.xml.find(tag)
|
||||
setattr(self, name, cls(xml, *fun[2:]))
|
||||
else:
|
||||
setattr(self, name, fun(self[name]))
|
||||
|
||||
|
||||
class Pool(list, XMLElement):
|
||||
def __init__(self, pool, element, client):
|
||||
super(Pool, self).__init__()
|
||||
|
||||
self.pool_name = pool
|
||||
self.element_name = element
|
||||
self.client = client
|
||||
|
||||
def info(self, filter=-3, range_start=-1, range_end=-1, *args):
|
||||
"""
|
||||
Retrives/Refreshes resource pool information
|
||||
|
||||
``filter``
|
||||
Filter flag. By defaults retrives only connected user reources.
|
||||
|
||||
``range_start``
|
||||
Range start ID. -1 for all
|
||||
|
||||
``range_end``
|
||||
Range end ID. -1 for all
|
||||
"""
|
||||
self[:] = []
|
||||
data = self.client.call(self.METHODS['info'], filter,
|
||||
range_start, range_end, *args)
|
||||
self._initialize_xml(data, self.pool_name)
|
||||
for element in self.xml.findall(self.element_name):
|
||||
self.append(self._factory(element))
|
||||
|
||||
def _factory(self):
|
||||
pass
|
||||
|
||||
def get_by_id(self, id):
|
||||
for i in self:
|
||||
if i.id == id:
|
||||
return i
|
||||
raise WrongIdError()
|
||||
|
||||
def get_by_name(self, name):
|
||||
for i in self:
|
||||
if i.name == name:
|
||||
return i
|
||||
raise WrongNameError()
|
||||
|
||||
|
||||
class PoolElement(XMLElement):
|
||||
def __init__(self, xml, client):
|
||||
super(PoolElement, self).__init__(xml)
|
||||
self.client = client
|
||||
|
||||
@classmethod
|
||||
def new_with_id(cls, client, element_id):
|
||||
"""
|
||||
Retrives object which id equals ```id```.
|
||||
|
||||
Arguments
|
||||
|
||||
```client```
|
||||
oca.Client object.
|
||||
```element_id``
|
||||
object id.
|
||||
"""
|
||||
element = cls.ELEMENT_NAME
|
||||
xml = '<{0}><ID>{1}</ID></{0}>'.format(element, element_id)
|
||||
obj = cls(xml, client)
|
||||
obj.id = int(obj.id)
|
||||
return obj
|
||||
|
||||
def info(self, *args):
|
||||
data = self.client.call(self.METHODS['info'], self.id)
|
||||
self._initialize_xml(data, self.ELEMENT_NAME)
|
||||
|
||||
def delete(self):
|
||||
"""
|
||||
Deletes current object from the pool
|
||||
"""
|
||||
self.client.call(self.METHODS['delete'], self.id)
|
||||
|
||||
def clone(self, name=''):
|
||||
"""
|
||||
Creates a clone of an elemet
|
||||
``name``
|
||||
name of a target element
|
||||
"""
|
||||
self.client.call(self.METHODS['clone'], self.id, name)
|
|
@ -0,0 +1,112 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
from .pool import Pool, PoolElement, Template
|
||||
|
||||
|
||||
class VmTemplate(PoolElement):
|
||||
METHODS = {
|
||||
'info': 'template.info',
|
||||
'allocate': 'template.allocate',
|
||||
'delete': 'template.delete',
|
||||
'update': 'template.update',
|
||||
'publish': 'template.publish',
|
||||
'chown': 'template.chown',
|
||||
'instantiate': 'template.instantiate',
|
||||
'clone': 'template.clone',
|
||||
}
|
||||
|
||||
XML_TYPES = {
|
||||
'id': int,
|
||||
'uid': int,
|
||||
'gid': int,
|
||||
'name': str,
|
||||
'uname': str,
|
||||
'gname': str,
|
||||
'regtime': int,
|
||||
'template': ['TEMPLATE', Template, ['DISK']]
|
||||
}
|
||||
|
||||
ELEMENT_NAME = 'VMTEMPLATE'
|
||||
|
||||
@staticmethod
|
||||
def allocate(client, template):
|
||||
"""
|
||||
Allocates a new template in OpenNebula
|
||||
|
||||
``client``
|
||||
oca.Client object
|
||||
|
||||
``template``
|
||||
a string containing the template contents
|
||||
"""
|
||||
template_id = client.call(VmTemplate.METHODS['allocate'], template)
|
||||
return template_id
|
||||
|
||||
def __init__(self, xml, client):
|
||||
super(VmTemplate, self).__init__(xml, client)
|
||||
self.id = self['ID'] if self['ID'] else None
|
||||
|
||||
def update(self, template, update_type=0):
|
||||
"""
|
||||
Replaces the template contents.
|
||||
|
||||
``template``
|
||||
The new template contents.
|
||||
``update_type``
|
||||
Update type: 0: replace the whole template. 1: Merge new template with the existing one.
|
||||
"""
|
||||
self.client.call(VmTemplate.METHODS['update'], self.id, template, update_type)
|
||||
|
||||
def publish(self):
|
||||
"""
|
||||
Publishes a template.
|
||||
"""
|
||||
self.client.call(VmTemplate.METHODS['publish'], self.id, True)
|
||||
|
||||
def unpublish(self):
|
||||
"""
|
||||
Unpublishes a template.
|
||||
"""
|
||||
self.client.call(VmTemplate.METHODS['publish'], self.id, False)
|
||||
|
||||
def chown(self, uid=-1, gid=-1):
|
||||
"""
|
||||
Changes the ownership of a template.
|
||||
|
||||
``uid``
|
||||
The User ID of the new owner. If set to -1, the owner is not changed.
|
||||
``gid``
|
||||
The Group ID of the new group. If set to -1, the group is not changed.
|
||||
"""
|
||||
self.client.call(VmTemplate.METHODS['chown'], self.id, uid, gid)
|
||||
|
||||
def instantiate(self, name='', pending=False, extra_template=''):
|
||||
"""
|
||||
Creates a VM instance from a VmTemplate
|
||||
|
||||
``name``
|
||||
name of the VM instance
|
||||
``pending``
|
||||
False to create the VM on pending (default), True to create it on hold.
|
||||
``extra_template``
|
||||
A string containing an extra template to be merged with the one being instantiated
|
||||
"""
|
||||
return self.client.call(VmTemplate.METHODS['instantiate'], self.id, name, pending, extra_template)
|
||||
|
||||
def __repr__(self):
|
||||
return '<oca.VmTemplate("%s")>' % self.name
|
||||
|
||||
|
||||
class VmTemplatePool(Pool):
|
||||
METHODS = {
|
||||
'info': 'templatepool.info',
|
||||
}
|
||||
|
||||
def __init__(self, client):
|
||||
super(VmTemplatePool, self).__init__('VMTEMPLATE_POOL', 'VMTEMPLATE', client)
|
||||
|
||||
# def info(self,
|
||||
|
||||
def _factory(self, xml):
|
||||
i = VmTemplate(xml, self.client)
|
||||
i._convert_types()
|
||||
return i
|
|
@ -0,0 +1,20 @@
|
|||
<CLUSTER>
|
||||
<ID>101</ID>
|
||||
<NAME>oneCluster</NAME>
|
||||
<HOSTS>
|
||||
<ID>2</ID>
|
||||
<ID>3</ID>
|
||||
</HOSTS>
|
||||
<DATASTORES>
|
||||
<ID>4</ID>
|
||||
<ID>5</ID>
|
||||
</DATASTORES>
|
||||
<VNETS>
|
||||
<ID>6</ID>
|
||||
<ID>7</ID>
|
||||
</VNETS>
|
||||
<TEMPLATE>
|
||||
<RESERVED_CPU><![CDATA[]]></RESERVED_CPU>
|
||||
<RESERVED_MEM><![CDATA[]]></RESERVED_MEM>
|
||||
</TEMPLATE>
|
||||
</CLUSTER>
|
|
@ -0,0 +1,24 @@
|
|||
<CLUSTER_POOL>
|
||||
<CLUSTER>
|
||||
<ID>101</ID>
|
||||
<NAME>oneCluster</NAME>
|
||||
<HOSTS/>
|
||||
<DATASTORES/>
|
||||
<VNETS/>
|
||||
<TEMPLATE>
|
||||
<RESERVED_CPU><![CDATA[]]></RESERVED_CPU>
|
||||
<RESERVED_MEM><![CDATA[]]></RESERVED_MEM>
|
||||
</TEMPLATE>
|
||||
</CLUSTER>
|
||||
<CLUSTER>
|
||||
<ID>102</ID>
|
||||
<NAME>anotherCluster</NAME>
|
||||
<HOSTS/>
|
||||
<DATASTORES/>
|
||||
<VNETS/>
|
||||
<TEMPLATE>
|
||||
<RESERVED_CPU><![CDATA[]]></RESERVED_CPU>
|
||||
<RESERVED_MEM><![CDATA[]]></RESERVED_MEM>
|
||||
</TEMPLATE>
|
||||
</CLUSTER>
|
||||
</CLUSTER_POOL>
|
|
@ -0,0 +1,42 @@
|
|||
<DATASTORE>
|
||||
<ID>100</ID>
|
||||
<UID>0</UID>
|
||||
<GID>0</GID>
|
||||
<UNAME>oneadmin</UNAME>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>Custom-DS</NAME>
|
||||
<PERMISSIONS>
|
||||
<OWNER_U>1</OWNER_U>
|
||||
<OWNER_M>1</OWNER_M>
|
||||
<OWNER_A>0</OWNER_A>
|
||||
<GROUP_U>1</GROUP_U>
|
||||
<GROUP_M>0</GROUP_M>
|
||||
<GROUP_A>0</GROUP_A>
|
||||
<OTHER_U>0</OTHER_U>
|
||||
<OTHER_M>0</OTHER_M>
|
||||
<OTHER_A>0</OTHER_A>
|
||||
</PERMISSIONS>
|
||||
<DS_MAD><![CDATA[fs]]></DS_MAD>
|
||||
<TM_MAD><![CDATA[ssh]]></TM_MAD>
|
||||
<BASE_PATH><![CDATA[/var/lib/one//datastores/100]]></BASE_PATH>
|
||||
<TYPE>0</TYPE>
|
||||
<DISK_TYPE>0</DISK_TYPE>
|
||||
<STATE>0</STATE>
|
||||
<CLUSTER_ID>-1</CLUSTER_ID>
|
||||
<CLUSTER/>
|
||||
<TOTAL_MB>9952</TOTAL_MB>
|
||||
<FREE_MB>8999</FREE_MB>
|
||||
<USED_MB>425</USED_MB>
|
||||
<IMAGES>
|
||||
<ID>2</ID>
|
||||
<ID>3</ID>
|
||||
</IMAGES>
|
||||
<TEMPLATE>
|
||||
<BASE_PATH><![CDATA[/var/lib/one//datastores/]]></BASE_PATH>
|
||||
<CLONE_TARGET><![CDATA[SYSTEM]]></CLONE_TARGET>
|
||||
<DISK_TYPE><![CDATA[FILE]]></DISK_TYPE>
|
||||
<DS_MAD><![CDATA[fs]]></DS_MAD>
|
||||
<LN_TARGET><![CDATA[SYSTEM]]></LN_TARGET>
|
||||
<TM_MAD><![CDATA[ssh]]></TM_MAD>
|
||||
</TEMPLATE>
|
||||
</DATASTORE>
|
|
@ -0,0 +1,79 @@
|
|||
<DATASTORE_POOL>
|
||||
<DATASTORE>
|
||||
<ID>0</ID>
|
||||
<UID>0</UID>
|
||||
<GID>0</GID>
|
||||
<UNAME>oneadmin</UNAME>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>system</NAME>
|
||||
<PERMISSIONS>
|
||||
<OWNER_U>1</OWNER_U>
|
||||
<OWNER_M>1</OWNER_M>
|
||||
<OWNER_A>0</OWNER_A>
|
||||
<GROUP_U>1</GROUP_U>
|
||||
<GROUP_M>0</GROUP_M>
|
||||
<GROUP_A>0</GROUP_A>
|
||||
<OTHER_U>0</OTHER_U>
|
||||
<OTHER_M>0</OTHER_M>
|
||||
<OTHER_A>0</OTHER_A>
|
||||
</PERMISSIONS>
|
||||
<DS_MAD><![CDATA[-]]></DS_MAD>
|
||||
<TM_MAD><![CDATA[shared]]></TM_MAD>
|
||||
<BASE_PATH><![CDATA[/var/lib/one//datastores/0]]></BASE_PATH>
|
||||
<TYPE>1</TYPE>
|
||||
<DISK_TYPE>0</DISK_TYPE>
|
||||
<STATE>0</STATE>
|
||||
<CLUSTER_ID>-1</CLUSTER_ID>
|
||||
<CLUSTER>test</CLUSTER>
|
||||
<TOTAL_MB>0</TOTAL_MB>
|
||||
<FREE_MB>0</FREE_MB>
|
||||
<USED_MB>0</USED_MB>
|
||||
<IMAGES/>
|
||||
<TEMPLATE>
|
||||
<BASE_PATH><![CDATA[/var/lib/one//datastores/]]></BASE_PATH>
|
||||
<SHARED><![CDATA[YES]]></SHARED>
|
||||
<TM_MAD><![CDATA[shared]]></TM_MAD>
|
||||
<TYPE><![CDATA[SYSTEM_DS]]></TYPE>
|
||||
</TEMPLATE>
|
||||
</DATASTORE>
|
||||
<DATASTORE>
|
||||
<ID>1</ID>
|
||||
<UID>0</UID>
|
||||
<GID>0</GID>
|
||||
<UNAME>oneadmin</UNAME>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>default</NAME>
|
||||
<PERMISSIONS>
|
||||
<OWNER_U>1</OWNER_U>
|
||||
<OWNER_M>1</OWNER_M>
|
||||
<OWNER_A>0</OWNER_A>
|
||||
<GROUP_U>1</GROUP_U>
|
||||
<GROUP_M>0</GROUP_M>
|
||||
<GROUP_A>0</GROUP_A>
|
||||
<OTHER_U>0</OTHER_U>
|
||||
<OTHER_M>0</OTHER_M>
|
||||
<OTHER_A>0</OTHER_A>
|
||||
</PERMISSIONS>
|
||||
<DS_MAD><![CDATA[fs]]></DS_MAD>
|
||||
<TM_MAD><![CDATA[shared]]></TM_MAD>
|
||||
<BASE_PATH><![CDATA[/var/lib/one//datastores/1]]></BASE_PATH>
|
||||
<TYPE>0</TYPE>
|
||||
<DISK_TYPE>0</DISK_TYPE>
|
||||
<STATE>0</STATE>
|
||||
<CLUSTER_ID>-1</CLUSTER_ID>
|
||||
<CLUSTER/>
|
||||
<TOTAL_MB>9952</TOTAL_MB>
|
||||
<FREE_MB>8999</FREE_MB>
|
||||
<USED_MB>425</USED_MB>
|
||||
<IMAGES/>
|
||||
<TEMPLATE>
|
||||
<BASE_PATH><![CDATA[/var/lib/one//datastores/]]></BASE_PATH>
|
||||
<CLONE_TARGET><![CDATA[SYSTEM]]></CLONE_TARGET>
|
||||
<DISK_TYPE><![CDATA[FILE]]></DISK_TYPE>
|
||||
<DS_MAD><![CDATA[fs]]></DS_MAD>
|
||||
<LN_TARGET><![CDATA[NONE]]></LN_TARGET>
|
||||
<TM_MAD><![CDATA[shared]]></TM_MAD>
|
||||
<TYPE><![CDATA[IMAGE_DS]]></TYPE>
|
||||
</TEMPLATE>
|
||||
</DATASTORE>
|
||||
</DATASTORE_POOL>
|
|
@ -0,0 +1,11 @@
|
|||
<GROUP>
|
||||
<ID>1</ID>
|
||||
<NAME>users</NAME>
|
||||
<TEMPLATE>
|
||||
<HELLO>world</HELLO>
|
||||
</TEMPLATE>
|
||||
<USERS>
|
||||
<ID>1</ID>
|
||||
<ID>2</ID>
|
||||
</USERS>
|
||||
</GROUP>
|
|
@ -0,0 +1,21 @@
|
|||
<GROUP_POOL>
|
||||
<GROUP>
|
||||
<ID>1</ID>
|
||||
<NAME>users</NAME>
|
||||
<TEMPLATE/>
|
||||
<USERS>
|
||||
<ID>1</ID>
|
||||
<ID>2</ID>
|
||||
</USERS>
|
||||
</GROUP>
|
||||
<GROUP>
|
||||
<ID>2</ID>
|
||||
git <NAME>admins</NAME>
|
||||
<TEMPLATE/>
|
||||
<USERS>
|
||||
<ID>3</ID>
|
||||
<ID>4</ID>
|
||||
</USERS>
|
||||
</GROUP>
|
||||
</GROUP_POOL>
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<HOST>
|
||||
<ID>7</ID>
|
||||
<NAME>dummyhost</NAME>
|
||||
<STATE>2</STATE>
|
||||
<IM_MAD>im_dummy</IM_MAD>
|
||||
<VM_MAD>vmm_dummy</VM_MAD>
|
||||
<VN_MAD>vn_dummy</VN_MAD>
|
||||
<TM_MAD>tm_dummy</TM_MAD>
|
||||
<LAST_MON_TIME>1277733596</LAST_MON_TIME>
|
||||
<CLUSTER/>
|
||||
<CLUSTER_ID>-1</CLUSTER_ID>
|
||||
<HOST_SHARE>
|
||||
<HID>0</HID>
|
||||
<DISK_USAGE>0</DISK_USAGE>
|
||||
<MEM_USAGE>1572864</MEM_USAGE>
|
||||
<CPU_USAGE>300</CPU_USAGE>
|
||||
<MAX_DISK>0</MAX_DISK>
|
||||
<MAX_MEM>16777216</MAX_MEM>
|
||||
<MAX_CPU>800</MAX_CPU>
|
||||
<FREE_DISK>0</FREE_DISK>
|
||||
<FREE_MEM>16777216</FREE_MEM>
|
||||
<FREE_CPU>800</FREE_CPU>
|
||||
<USED_DISK>0</USED_DISK>
|
||||
<USED_MEM>0</USED_MEM>
|
||||
<USED_CPU>0</USED_CPU>
|
||||
<RUNNING_VMS>3</RUNNING_VMS>
|
||||
</HOST_SHARE>
|
||||
<VMS>
|
||||
<ID>82</ID>
|
||||
<ID>84</ID>
|
||||
<ID>85</ID>
|
||||
<ID>95</ID>
|
||||
<ID>96</ID>
|
||||
</VMS>
|
||||
<TEMPLATE>
|
||||
<CPUSPEED>2.2GHz</CPUSPEED>
|
||||
<FREECPU>800</FREECPU>
|
||||
<FREEMEMORY>16777216</FREEMEMORY>
|
||||
<HOSTNAME>dummyhost</HOSTNAME>
|
||||
<HYPERVISOR>dummy</HYPERVISOR>
|
||||
<MAC>50:20:20:20:20:21</MAC>
|
||||
<NAME>dummyhost</NAME>
|
||||
<TOTALCPU>800</TOTALCPU>
|
||||
<TOTALMEMORY>16777216</TOTALMEMORY>
|
||||
<USEDCPU>0</USEDCPU>
|
||||
<USEDMEMORY>0</USEDMEMORY>
|
||||
</TEMPLATE>
|
||||
</HOST>
|
|
@ -0,0 +1,62 @@
|
|||
<HOST_POOL>
|
||||
<HOST>
|
||||
<ID>0</ID>
|
||||
<NAME>dummyhost</NAME>
|
||||
<STATE>2</STATE>
|
||||
<IM_MAD>im_dummy</IM_MAD>
|
||||
<VM_MAD>vmm_dummy</VM_MAD>
|
||||
<VN_MAD>vn_dummy</VN_MAD>
|
||||
<TM_MAD>tm_dummy</TM_MAD>
|
||||
<LAST_MON_TIME>1277912461</LAST_MON_TIME>
|
||||
<CLUSTER>default</CLUSTER>
|
||||
<CLUSTER_ID>1</CLUSTER_ID>
|
||||
<HOST_SHARE>
|
||||
<HID>0</HID>
|
||||
<DISK_USAGE>0</DISK_USAGE>
|
||||
<MEM_USAGE>1572864</MEM_USAGE>
|
||||
<CPU_USAGE>300</CPU_USAGE>
|
||||
<MAX_DISK>0</MAX_DISK>
|
||||
<MAX_MEM>16777216</MAX_MEM>
|
||||
<MAX_CPU>800</MAX_CPU>
|
||||
<FREE_DISK>0</FREE_DISK>
|
||||
<FREE_MEM>16777216</FREE_MEM>
|
||||
<FREE_CPU>800</FREE_CPU>
|
||||
<USED_DISK>0</USED_DISK>
|
||||
<USED_MEM>0</USED_MEM>
|
||||
<USED_CPU>0</USED_CPU>
|
||||
<RUNNING_VMS>3</RUNNING_VMS>
|
||||
</HOST_SHARE>
|
||||
<VMS/>
|
||||
<TEMPLATE></TEMPLATE>
|
||||
</HOST>
|
||||
<HOST>
|
||||
<ID>1</ID>
|
||||
<NAME>thost</NAME>
|
||||
<STATE>2</STATE>
|
||||
<IM_MAD>im_dummy</IM_MAD>
|
||||
<VM_MAD>vmm_dummy</VM_MAD>
|
||||
<VN_MAD>vn_dummy</VN_MAD>
|
||||
<TM_MAD>tm_dummy</TM_MAD>
|
||||
<LAST_MON_TIME>1277912461</LAST_MON_TIME>
|
||||
<CLUSTER>default</CLUSTER>
|
||||
<CLUSTER_ID>1</CLUSTER_ID>
|
||||
<HOST_SHARE>
|
||||
<HID>1</HID>
|
||||
<DISK_USAGE>0</DISK_USAGE>
|
||||
<MEM_USAGE>0</MEM_USAGE>
|
||||
<CPU_USAGE>0</CPU_USAGE>
|
||||
<MAX_DISK>0</MAX_DISK>
|
||||
<MAX_MEM>16777216</MAX_MEM>
|
||||
<MAX_CPU>800</MAX_CPU>
|
||||
<FREE_DISK>0</FREE_DISK>
|
||||
<FREE_MEM>16777216</FREE_MEM>
|
||||
<FREE_CPU>800</FREE_CPU>
|
||||
<USED_DISK>0</USED_DISK>
|
||||
<USED_MEM>0</USED_MEM>
|
||||
<USED_CPU>0</USED_CPU>
|
||||
<RUNNING_VMS>0</RUNNING_VMS>
|
||||
</HOST_SHARE>
|
||||
<VMS/>
|
||||
<TEMPLATE></TEMPLATE>
|
||||
</HOST>
|
||||
</HOST_POOL>
|
|
@ -0,0 +1,38 @@
|
|||
<IMAGE>
|
||||
<ID>1</ID>
|
||||
<UID>0</UID>
|
||||
<GID>0</GID>
|
||||
<UNAME>oneadmin</UNAME>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>MATLAB install CD</NAME>
|
||||
<PERMISSIONS>
|
||||
<OWNER_U>1</OWNER_U>
|
||||
<OWNER_M>1</OWNER_M>
|
||||
<OWNER_A>0</OWNER_A>
|
||||
<GROUP_U>0</GROUP_U>
|
||||
<GROUP_M>0</GROUP_M>
|
||||
<GROUP_A>0</GROUP_A>
|
||||
<OTHER_U>0</OTHER_U>
|
||||
<OTHER_M>0</OTHER_M>
|
||||
<OTHER_A>0</OTHER_A>
|
||||
</PERMISSIONS>
|
||||
<TYPE>2</TYPE>
|
||||
<DISK_TYPE>0</DISK_TYPE>
|
||||
<PERSISTENT>0</PERSISTENT>
|
||||
<REGTIME>1435086617</REGTIME>
|
||||
<SOURCE><![CDATA[/var/lib/one//datastores/1/4f3591cfe3a4e0a00789087a3f92c433]]></SOURCE>
|
||||
<PATH><![CDATA[]]></PATH>
|
||||
<FSTYPE><![CDATA[ext2]]></FSTYPE>
|
||||
<SIZE>400</SIZE>
|
||||
<STATE>1</STATE>
|
||||
<RUNNING_VMS>0</RUNNING_VMS>
|
||||
<CLONING_OPS>0</CLONING_OPS>
|
||||
<CLONING_ID>-1</CLONING_ID>
|
||||
<DATASTORE_ID>1</DATASTORE_ID>
|
||||
<DATASTORE>default</DATASTORE>
|
||||
<VMS/>
|
||||
<CLONES/>
|
||||
<TEMPLATE>
|
||||
<DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX>
|
||||
</TEMPLATE>
|
||||
</IMAGE>
|
|
@ -0,0 +1,116 @@
|
|||
<IMAGE_POOL>
|
||||
<IMAGE>
|
||||
<ID>0</ID>
|
||||
<UID>0</UID>
|
||||
<GID>0</GID>
|
||||
<UNAME>oneadmin</UNAME>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>data</NAME>
|
||||
<PERMISSIONS>
|
||||
<OWNER_U>1</OWNER_U>
|
||||
<OWNER_M>1</OWNER_M>
|
||||
<OWNER_A>0</OWNER_A>
|
||||
<GROUP_U>0</GROUP_U>
|
||||
<GROUP_M>0</GROUP_M>
|
||||
<GROUP_A>0</GROUP_A>
|
||||
<OTHER_U>0</OTHER_U>
|
||||
<OTHER_M>0</OTHER_M>
|
||||
<OTHER_A>0</OTHER_A>
|
||||
</PERMISSIONS>
|
||||
<TYPE>2</TYPE>
|
||||
<DISK_TYPE>0</DISK_TYPE>
|
||||
<PERSISTENT>0</PERSISTENT>
|
||||
<REGTIME>1435086617</REGTIME>
|
||||
<SOURCE><![CDATA[/var/lib/one//datastores/1/4f3591cfe3a4e0a00789087a3f92c433]]></SOURCE>
|
||||
<PATH><![CDATA[]]></PATH>
|
||||
<FSTYPE><![CDATA[ext2]]></FSTYPE>
|
||||
<SIZE>400</SIZE>
|
||||
<STATE>1</STATE>
|
||||
<RUNNING_VMS>0</RUNNING_VMS>
|
||||
<CLONING_OPS>0</CLONING_OPS>
|
||||
<CLONING_ID>-1</CLONING_ID>
|
||||
<DATASTORE_ID>1</DATASTORE_ID>
|
||||
<DATASTORE>default</DATASTORE>
|
||||
<VMS/>
|
||||
<CLONES/>
|
||||
<TEMPLATE>
|
||||
<DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX>
|
||||
</TEMPLATE>
|
||||
</IMAGE>
|
||||
<IMAGE>
|
||||
<ID>1</ID>
|
||||
<UID>0</UID>
|
||||
<GID>0</GID>
|
||||
<UNAME>oneadmin</UNAME>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>data2</NAME>
|
||||
<PERMISSIONS>
|
||||
<OWNER_U>1</OWNER_U>
|
||||
<OWNER_M>1</OWNER_M>
|
||||
<OWNER_A>0</OWNER_A>
|
||||
<GROUP_U>0</GROUP_U>
|
||||
<GROUP_M>0</GROUP_M>
|
||||
<GROUP_A>0</GROUP_A>
|
||||
<OTHER_U>0</OTHER_U>
|
||||
<OTHER_M>0</OTHER_M>
|
||||
<OTHER_A>0</OTHER_A>
|
||||
</PERMISSIONS>
|
||||
<TYPE>2</TYPE>
|
||||
<DISK_TYPE>0</DISK_TYPE>
|
||||
<PERSISTENT>0</PERSISTENT>
|
||||
<REGTIME>1435086683</REGTIME>
|
||||
<SOURCE><![CDATA[/var/lib/one//datastores/1/bc928294936ce873228150af2052ebc3]]></SOURCE>
|
||||
<PATH><![CDATA[]]></PATH>
|
||||
<FSTYPE><![CDATA[ext2]]></FSTYPE>
|
||||
<SIZE>200</SIZE>
|
||||
<STATE>1</STATE>
|
||||
<RUNNING_VMS>0</RUNNING_VMS>
|
||||
<CLONING_OPS>0</CLONING_OPS>
|
||||
<CLONING_ID>-1</CLONING_ID>
|
||||
<DATASTORE_ID>1</DATASTORE_ID>
|
||||
<DATASTORE>default</DATASTORE>
|
||||
<VMS/>
|
||||
<CLONES/>
|
||||
<TEMPLATE>
|
||||
<DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX>
|
||||
</TEMPLATE>
|
||||
</IMAGE>
|
||||
<IMAGE>
|
||||
<ID>2</ID>
|
||||
<UID>0</UID>
|
||||
<GID>0</GID>
|
||||
<UNAME>oneadmin</UNAME>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>data3</NAME>
|
||||
<PERMISSIONS>
|
||||
<OWNER_U>1</OWNER_U>
|
||||
<OWNER_M>1</OWNER_M>
|
||||
<OWNER_A>0</OWNER_A>
|
||||
<GROUP_U>0</GROUP_U>
|
||||
<GROUP_M>0</GROUP_M>
|
||||
<GROUP_A>0</GROUP_A>
|
||||
<OTHER_U>0</OTHER_U>
|
||||
<OTHER_M>0</OTHER_M>
|
||||
<OTHER_A>0</OTHER_A>
|
||||
</PERMISSIONS>
|
||||
<TYPE>2</TYPE>
|
||||
<DISK_TYPE>0</DISK_TYPE>
|
||||
<PERSISTENT>0</PERSISTENT>
|
||||
<REGTIME>1435086941</REGTIME>
|
||||
<SOURCE><![CDATA[/var/lib/one//datastores/1/325e9c37fd02ae842a342ed5e464d0da]]></SOURCE>
|
||||
<PATH><![CDATA[]]></PATH>
|
||||
<FSTYPE><![CDATA[ext2]]></FSTYPE>
|
||||
<SIZE>200</SIZE>
|
||||
<STATE>1</STATE>
|
||||
<RUNNING_VMS>0</RUNNING_VMS>
|
||||
<CLONING_OPS>0</CLONING_OPS>
|
||||
<CLONING_ID>-1</CLONING_ID>
|
||||
<DATASTORE_ID>1</DATASTORE_ID>
|
||||
<DATASTORE>default</DATASTORE>
|
||||
<VMS/>
|
||||
<CLONES/>
|
||||
<TEMPLATE>
|
||||
<DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX>
|
||||
</TEMPLATE>
|
||||
</IMAGE>
|
||||
</IMAGE_POOL>
|
|
@ -0,0 +1 @@
|
|||
test:test
|
|
@ -0,0 +1,26 @@
|
|||
<VMTEMPLATE>
|
||||
<ID>1</ID>
|
||||
<UID>0</UID>
|
||||
<GID>0</GID>
|
||||
<UNAME>oneadmin</UNAME>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>test1</NAME>
|
||||
<PUBLIC>0</PUBLIC>
|
||||
<REGTIME>1320877281</REGTIME>
|
||||
<TEMPLATE>
|
||||
<CPU><![CDATA[1]]></CPU>
|
||||
<DISK>
|
||||
<IMAGE_ID><![CDATA[80]]></IMAGE_ID>
|
||||
</DISK>
|
||||
<MEMORY><![CDATA[2048]]></MEMORY>
|
||||
<NAME><![CDATA[test1]]></NAME>
|
||||
<NIC>
|
||||
<NETWORK_ID><![CDATA[21]]></NETWORK_ID>
|
||||
</NIC>
|
||||
<NIC>
|
||||
<NETWORK_ID><![CDATA[22]]></NETWORK_ID>
|
||||
</NIC>
|
||||
<VCPU><![CDATA[4]]></VCPU>
|
||||
</TEMPLATE>
|
||||
</VMTEMPLATE>
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<VMTEMPLATE_POOL>
|
||||
<VMTEMPLATE>
|
||||
<ID>0</ID>
|
||||
<UID>0</UID>
|
||||
<GID>0</GID>
|
||||
<UNAME>oneadmin</UNAME>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>test</NAME>
|
||||
<PUBLIC>0</PUBLIC>
|
||||
<REGTIME>1320877281</REGTIME>
|
||||
<TEMPLATE>
|
||||
<CPU><![CDATA[1]]></CPU>
|
||||
<DISK>
|
||||
<IMAGE_ID><![CDATA[80]]></IMAGE_ID>
|
||||
</DISK>
|
||||
<MEMORY><![CDATA[2048]]></MEMORY>
|
||||
<NAME><![CDATA[test]]></NAME>
|
||||
<NIC>
|
||||
<NETWORK_ID><![CDATA[21]]></NETWORK_ID>
|
||||
</NIC>
|
||||
<NIC>
|
||||
<NETWORK_ID><![CDATA[22]]></NETWORK_ID>
|
||||
</NIC>
|
||||
<VCPU><![CDATA[4]]></VCPU>
|
||||
</TEMPLATE>
|
||||
</VMTEMPLATE>
|
||||
<VMTEMPLATE>
|
||||
<ID>1</ID>
|
||||
<UID>0</UID>
|
||||
<GID>0</GID>
|
||||
<UNAME>oneadmin</UNAME>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>test1</NAME>
|
||||
<PUBLIC>0</PUBLIC>
|
||||
<REGTIME>1320877281</REGTIME>
|
||||
<TEMPLATE>
|
||||
<CPU><![CDATA[1]]></CPU>
|
||||
<DISK>
|
||||
<IMAGE_ID><![CDATA[80]]></IMAGE_ID>
|
||||
</DISK>
|
||||
<MEMORY><![CDATA[2048]]></MEMORY>
|
||||
<NAME><![CDATA[test1]]></NAME>
|
||||
<NIC>
|
||||
<NETWORK_ID><![CDATA[21]]></NETWORK_ID>
|
||||
</NIC>
|
||||
<NIC>
|
||||
<NETWORK_ID><![CDATA[22]]></NETWORK_ID>
|
||||
</NIC>
|
||||
<VCPU><![CDATA[4]]></VCPU>
|
||||
</TEMPLATE>
|
||||
</VMTEMPLATE>
|
||||
</VMTEMPLATE_POOL>
|
|
@ -0,0 +1,16 @@
|
|||
<USER>
|
||||
<ID>3</ID>
|
||||
<GID>0</GID>
|
||||
<GROUPS>
|
||||
<ID>0</ID>
|
||||
</GROUPS>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>dan</NAME>
|
||||
<PASSWORD>fe05bcdcdc4928012781a5f1a2a77cbb5398e106</PASSWORD>
|
||||
<AUTH_DRIVER>core</AUTH_DRIVER>
|
||||
<ENABLED>1</ENABLED>
|
||||
<LOGIN_TOKEN/>
|
||||
<TEMPLATE>
|
||||
<TOKEN_PASSWORD><![CDATA[97fc29a2162405277a5d2a0ef33acfcbd4f78e4e]]></TOKEN_PASSWORD>
|
||||
</TEMPLATE>
|
||||
</USER>
|
|
@ -0,0 +1,54 @@
|
|||
<USER_POOL>
|
||||
<USER>
|
||||
<ID>0</ID>
|
||||
<GID>0</GID>
|
||||
<GROUPS>
|
||||
<ID>0</ID>
|
||||
</GROUPS>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>oneadmin</NAME>
|
||||
<PASSWORD>fe05bcdcdc4928012781a5f1a2a77cbb5398e106</PASSWORD>
|
||||
<AUTH_DRIVER>core</AUTH_DRIVER>
|
||||
<ENABLED>1</ENABLED>
|
||||
<LOGIN_TOKEN/>
|
||||
<TEMPLATE>
|
||||
<TOKEN_PASSWORD><![CDATA[97fc29a2162405277a5d2a0ef33acfcbd4f78e4e]]></TOKEN_PASSWORD>
|
||||
</TEMPLATE>
|
||||
</USER>
|
||||
<QUOTAS>
|
||||
<ID>0</ID>
|
||||
<DATASTORE_QUOTA/>
|
||||
<NETWORK_QUOTA/>
|
||||
<VM_QUOTA/>
|
||||
<IMAGE_QUOTA/>
|
||||
</QUOTAS>
|
||||
<USER>
|
||||
<ID>1</ID>
|
||||
<GID>0</GID>
|
||||
<GROUPS>
|
||||
<ID>0</ID>
|
||||
</GROUPS>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>serveradmin</NAME>
|
||||
<PASSWORD>f9f3c8912fc6cc53012d743ded329c4f5fb035a5</PASSWORD>
|
||||
<AUTH_DRIVER>server_cipher</AUTH_DRIVER>
|
||||
<ENABLED>1</ENABLED>
|
||||
<LOGIN_TOKEN/>
|
||||
<TEMPLATE>
|
||||
<TOKEN_PASSWORD><![CDATA[d53363ad24f9f5b44a95d028c78f1a9d3320fdee]]></TOKEN_PASSWORD>
|
||||
</TEMPLATE>
|
||||
</USER>
|
||||
<QUOTAS>
|
||||
<ID>1</ID>
|
||||
<DATASTORE_QUOTA/>
|
||||
<NETWORK_QUOTA/>
|
||||
<VM_QUOTA/>
|
||||
<IMAGE_QUOTA/>
|
||||
</QUOTAS>
|
||||
<DEFAULT_USER_QUOTAS>
|
||||
<DATASTORE_QUOTA/>
|
||||
<NETWORK_QUOTA/>
|
||||
<VM_QUOTA/>
|
||||
<IMAGE_QUOTA/>
|
||||
</DEFAULT_USER_QUOTAS>
|
||||
</USER_POOL>
|
|
@ -0,0 +1,73 @@
|
|||
<VM>
|
||||
<ID>6</ID>
|
||||
<UID>0</UID>
|
||||
<GID>0</GID>
|
||||
<UNAME>oneadmin</UNAME>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>vm-example</NAME>
|
||||
<PERMISSIONS>
|
||||
<OWNER_U>1</OWNER_U>
|
||||
<OWNER_M>1</OWNER_M>
|
||||
<OWNER_A>0</OWNER_A>
|
||||
<GROUP_U>0</GROUP_U>
|
||||
<GROUP_M>0</GROUP_M>
|
||||
<GROUP_A>0</GROUP_A>
|
||||
<OTHER_U>0</OTHER_U>
|
||||
<OTHER_M>0</OTHER_M>
|
||||
<OTHER_A>0</OTHER_A>
|
||||
</PERMISSIONS>
|
||||
<LAST_POLL>1277729095</LAST_POLL>
|
||||
<STATE>3</STATE>
|
||||
<LCM_STATE>3</LCM_STATE>
|
||||
<RESCHED>0</RESCHED>
|
||||
<STIME>1277375180</STIME>
|
||||
<ETIME>0</ETIME>
|
||||
<DEPLOY_ID>dummy</DEPLOY_ID>
|
||||
<MEMORY>512</MEMORY>
|
||||
<CPU>1</CPU>
|
||||
<NET_TX>12345</NET_TX>
|
||||
<NET_RX>0</NET_RX>
|
||||
<TEMPLATE>
|
||||
<AUTOMATIC_REQUIREMENTS><![CDATA[!(PUBLIC_CLOUD = YES)]]></AUTOMATIC_REQUIREMENTS>
|
||||
<CPU><![CDATA[1]]></CPU>
|
||||
<DISK>
|
||||
<CLONE><![CDATA[YES]]></CLONE>
|
||||
<CLONE_TARGET><![CDATA[SYSTEM]]></CLONE_TARGET>
|
||||
<DATASTORE><![CDATA[default]]></DATASTORE>
|
||||
<DATASTORE_ID><![CDATA[1]]></DATASTORE_ID>
|
||||
<DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX>
|
||||
<DISK_ID><![CDATA[0]]></DISK_ID>
|
||||
<IMAGE><![CDATA[data]]></IMAGE>
|
||||
<IMAGE_ID><![CDATA[0]]></IMAGE_ID>
|
||||
<LN_TARGET><![CDATA[NONE]]></LN_TARGET>
|
||||
<READONLY><![CDATA[NO]]></READONLY>
|
||||
<SAVE><![CDATA[NO]]></SAVE>
|
||||
<SIZE><![CDATA[400]]></SIZE>
|
||||
<SOURCE><![CDATA[/var/lib/one//datastores/1/3c1e70af31901a043238e787aba8e5d4]]></SOURCE>
|
||||
<TARGET><![CDATA[hda]]></TARGET>
|
||||
<TM_MAD><![CDATA[shared]]></TM_MAD>
|
||||
<TYPE><![CDATA[FILE]]></TYPE>
|
||||
</DISK>
|
||||
<MEMORY><![CDATA[128]]></MEMORY>
|
||||
<VMID><![CDATA[0]]></VMID>
|
||||
</TEMPLATE>
|
||||
<USER_TEMPLATE>
|
||||
<GREETING><![CDATA[Hello World]]></GREETING>
|
||||
</USER_TEMPLATE>
|
||||
<HISTORY_RECORDS>
|
||||
<HISTORY>
|
||||
<SEQ>0</SEQ>
|
||||
<HOSTNAME>dummyhost</HOSTNAME>
|
||||
<HID>0</HID>
|
||||
<STIME>1277375186</STIME>
|
||||
<ETIME>0</ETIME>
|
||||
<PSTIME>1277375186</PSTIME>
|
||||
<PETIME>1277375186</PETIME>
|
||||
<RSTIME>1277375186</RSTIME>
|
||||
<RETIME>0</RETIME>
|
||||
<ESTIME>0</ESTIME>
|
||||
<EETIME>0</EETIME>
|
||||
<REASON>0</REASON>
|
||||
</HISTORY>
|
||||
</HISTORY_RECORDS>
|
||||
</VM>
|
|
@ -0,0 +1,215 @@
|
|||
<VM_POOL>
|
||||
<VM>
|
||||
<ID>6</ID>
|
||||
<UID>0</UID>
|
||||
<GID>0</GID>
|
||||
<UNAME>oneadmin</UNAME>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>vm-example</NAME>
|
||||
<PERMISSIONS>
|
||||
<OWNER_U>1</OWNER_U>
|
||||
<OWNER_M>1</OWNER_M>
|
||||
<OWNER_A>0</OWNER_A>
|
||||
<GROUP_U>0</GROUP_U>
|
||||
<GROUP_M>0</GROUP_M>
|
||||
<GROUP_A>0</GROUP_A>
|
||||
<OTHER_U>0</OTHER_U>
|
||||
<OTHER_M>0</OTHER_M>
|
||||
<OTHER_A>0</OTHER_A>
|
||||
</PERMISSIONS>
|
||||
<LAST_POLL>1277729095</LAST_POLL>
|
||||
<STATE>3</STATE>
|
||||
<LCM_STATE>3</LCM_STATE>
|
||||
<RESCHED>0</RESCHED>
|
||||
<STIME>1277375180</STIME>
|
||||
<ETIME>0</ETIME>
|
||||
<DEPLOY_ID>dummy</DEPLOY_ID>
|
||||
<MEMORY>512</MEMORY>
|
||||
<CPU>1</CPU>
|
||||
<NET_TX>12345</NET_TX>
|
||||
<NET_RX>0</NET_RX>
|
||||
<TEMPLATE>
|
||||
<AUTOMATIC_REQUIREMENTS><![CDATA[!(PUBLIC_CLOUD = YES)]]></AUTOMATIC_REQUIREMENTS>
|
||||
<CPU><![CDATA[1]]></CPU>
|
||||
<DISK>
|
||||
<CLONE><![CDATA[YES]]></CLONE>
|
||||
<CLONE_TARGET><![CDATA[SYSTEM]]></CLONE_TARGET>
|
||||
<DATASTORE><![CDATA[default]]></DATASTORE>
|
||||
<DATASTORE_ID><![CDATA[1]]></DATASTORE_ID>
|
||||
<DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX>
|
||||
<DISK_ID><![CDATA[0]]></DISK_ID>
|
||||
<IMAGE><![CDATA[data]]></IMAGE>
|
||||
<IMAGE_ID><![CDATA[0]]></IMAGE_ID>
|
||||
<LN_TARGET><![CDATA[NONE]]></LN_TARGET>
|
||||
<READONLY><![CDATA[NO]]></READONLY>
|
||||
<SAVE><![CDATA[NO]]></SAVE>
|
||||
<SIZE><![CDATA[400]]></SIZE>
|
||||
<SOURCE><![CDATA[/var/lib/one//datastores/1/3c1e70af31901a043238e787aba8e5d4]]></SOURCE>
|
||||
<TARGET><![CDATA[hda]]></TARGET>
|
||||
<TM_MAD><![CDATA[shared]]></TM_MAD>
|
||||
<TYPE><![CDATA[FILE]]></TYPE>
|
||||
</DISK>
|
||||
<MEMORY><![CDATA[128]]></MEMORY>
|
||||
<VMID><![CDATA[0]]></VMID>
|
||||
</TEMPLATE>
|
||||
<USER_TEMPLATE/>
|
||||
<HISTORY_RECORDS>
|
||||
<HISTORY>
|
||||
<SEQ>0</SEQ>
|
||||
<HOSTNAME>dummyhost</HOSTNAME>
|
||||
<HID>0</HID>
|
||||
<STIME>1277375186</STIME>
|
||||
<ETIME>0</ETIME>
|
||||
<PSTIME>1277375186</PSTIME>
|
||||
<PETIME>1277375186</PETIME>
|
||||
<RSTIME>1277375186</RSTIME>
|
||||
<RETIME>0</RETIME>
|
||||
<ESTIME>0</ESTIME>
|
||||
<EETIME>0</EETIME>
|
||||
<REASON>0</REASON>
|
||||
</HISTORY>
|
||||
</HISTORY_RECORDS>
|
||||
</VM>
|
||||
<VM>
|
||||
<ID>7</ID>
|
||||
<UID>0</UID>
|
||||
<GID>0</GID>
|
||||
<UNAME>oneadmin</UNAME>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>vm-in</NAME>
|
||||
<PERMISSIONS>
|
||||
<OWNER_U>1</OWNER_U>
|
||||
<OWNER_M>1</OWNER_M>
|
||||
<OWNER_A>0</OWNER_A>
|
||||
<GROUP_U>0</GROUP_U>
|
||||
<GROUP_M>0</GROUP_M>
|
||||
<GROUP_A>0</GROUP_A>
|
||||
<OTHER_U>0</OTHER_U>
|
||||
<OTHER_M>0</OTHER_M>
|
||||
<OTHER_A>0</OTHER_A>
|
||||
</PERMISSIONS>
|
||||
<LAST_POLL>1277729095</LAST_POLL>
|
||||
<STATE>3</STATE>
|
||||
<LCM_STATE>3</LCM_STATE>
|
||||
<RESCHED>0</RESCHED>
|
||||
<STIME>1277375180</STIME>
|
||||
<ETIME>0</ETIME>
|
||||
<DEPLOY_ID>dummy</DEPLOY_ID>
|
||||
<MEMORY>512</MEMORY>
|
||||
<CPU>1</CPU>
|
||||
<NET_TX>12345</NET_TX>
|
||||
<NET_RX>0</NET_RX>
|
||||
<TEMPLATE>
|
||||
<AUTOMATIC_REQUIREMENTS><![CDATA[!(PUBLIC_CLOUD = YES)]]></AUTOMATIC_REQUIREMENTS>
|
||||
<CPU><![CDATA[1]]></CPU>
|
||||
<DISK>
|
||||
<CLONE><![CDATA[YES]]></CLONE>
|
||||
<CLONE_TARGET><![CDATA[SYSTEM]]></CLONE_TARGET>
|
||||
<DATASTORE><![CDATA[default]]></DATASTORE>
|
||||
<DATASTORE_ID><![CDATA[1]]></DATASTORE_ID>
|
||||
<DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX>
|
||||
<DISK_ID><![CDATA[0]]></DISK_ID>
|
||||
<IMAGE><![CDATA[data]]></IMAGE>
|
||||
<IMAGE_ID><![CDATA[0]]></IMAGE_ID>
|
||||
<LN_TARGET><![CDATA[NONE]]></LN_TARGET>
|
||||
<READONLY><![CDATA[NO]]></READONLY>
|
||||
<SAVE><![CDATA[NO]]></SAVE>
|
||||
<SIZE><![CDATA[400]]></SIZE>
|
||||
<SOURCE><![CDATA[/var/lib/one//datastores/1/3c1e70af31901a043238e787aba8e5d4]]></SOURCE>
|
||||
<TARGET><![CDATA[hda]]></TARGET>
|
||||
<TM_MAD><![CDATA[shared]]></TM_MAD>
|
||||
<TYPE><![CDATA[FILE]]></TYPE>
|
||||
</DISK>
|
||||
<MEMORY><![CDATA[128]]></MEMORY>
|
||||
<VMID><![CDATA[0]]></VMID>
|
||||
</TEMPLATE>
|
||||
<USER_TEMPLATE/>
|
||||
<HISTORY_RECORDS>
|
||||
<HISTORY>
|
||||
<SEQ>0</SEQ>
|
||||
<HOSTNAME>dummyhost</HOSTNAME>
|
||||
<HID>0</HID>
|
||||
<STIME>1277375186</STIME>
|
||||
<ETIME>0</ETIME>
|
||||
<PSTIME>1277375186</PSTIME>
|
||||
<PETIME>1277375186</PETIME>
|
||||
<RSTIME>1277375186</RSTIME>
|
||||
<RETIME>0</RETIME>
|
||||
<ESTIME>0</ESTIME>
|
||||
<EETIME>0</EETIME>
|
||||
<REASON>0</REASON>
|
||||
</HISTORY>
|
||||
</HISTORY_RECORDS>
|
||||
</VM>
|
||||
<VM>
|
||||
<ID>8</ID>
|
||||
<UID>0</UID>
|
||||
<GID>0</GID>
|
||||
<UNAME>oneadmin</UNAME>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>vm-in</NAME>
|
||||
<PERMISSIONS>
|
||||
<OWNER_U>1</OWNER_U>
|
||||
<OWNER_M>1</OWNER_M>
|
||||
<OWNER_A>0</OWNER_A>
|
||||
<GROUP_U>0</GROUP_U>
|
||||
<GROUP_M>0</GROUP_M>
|
||||
<GROUP_A>0</GROUP_A>
|
||||
<OTHER_U>0</OTHER_U>
|
||||
<OTHER_M>0</OTHER_M>
|
||||
<OTHER_A>0</OTHER_A>
|
||||
</PERMISSIONS>
|
||||
<LAST_POLL>1277729095</LAST_POLL>
|
||||
<STATE>3</STATE>
|
||||
<LCM_STATE>3</LCM_STATE>
|
||||
<RESCHED>0</RESCHED>
|
||||
<STIME>1277375180</STIME>
|
||||
<ETIME>0</ETIME>
|
||||
<DEPLOY_ID>dummy</DEPLOY_ID>
|
||||
<MEMORY>512</MEMORY>
|
||||
<CPU>1</CPU>
|
||||
<NET_TX>12345</NET_TX>
|
||||
<NET_RX>0</NET_RX>
|
||||
<TEMPLATE>
|
||||
<AUTOMATIC_REQUIREMENTS><![CDATA[!(PUBLIC_CLOUD = YES)]]></AUTOMATIC_REQUIREMENTS>
|
||||
<CPU><![CDATA[1]]></CPU>
|
||||
<DISK>
|
||||
<CLONE><![CDATA[YES]]></CLONE>
|
||||
<CLONE_TARGET><![CDATA[SYSTEM]]></CLONE_TARGET>
|
||||
<DATASTORE><![CDATA[default]]></DATASTORE>
|
||||
<DATASTORE_ID><![CDATA[1]]></DATASTORE_ID>
|
||||
<DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX>
|
||||
<DISK_ID><![CDATA[0]]></DISK_ID>
|
||||
<IMAGE><![CDATA[data]]></IMAGE>
|
||||
<IMAGE_ID><![CDATA[0]]></IMAGE_ID>
|
||||
<LN_TARGET><![CDATA[NONE]]></LN_TARGET>
|
||||
<READONLY><![CDATA[NO]]></READONLY>
|
||||
<SAVE><![CDATA[NO]]></SAVE>
|
||||
<SIZE><![CDATA[400]]></SIZE>
|
||||
<SOURCE><![CDATA[/var/lib/one//datastores/1/3c1e70af31901a043238e787aba8e5d4]]></SOURCE>
|
||||
<TARGET><![CDATA[hda]]></TARGET>
|
||||
<TM_MAD><![CDATA[shared]]></TM_MAD>
|
||||
<TYPE><![CDATA[FILE]]></TYPE>
|
||||
</DISK>
|
||||
<MEMORY><![CDATA[128]]></MEMORY>
|
||||
<VMID><![CDATA[0]]></VMID>
|
||||
</TEMPLATE>
|
||||
<USER_TEMPLATE/>
|
||||
<HISTORY_RECORDS>
|
||||
<HISTORY>
|
||||
<SEQ>0</SEQ>
|
||||
<HOSTNAME>dummyhost</HOSTNAME>
|
||||
<HID>0</HID>
|
||||
<STIME>1277375186</STIME>
|
||||
<ETIME>0</ETIME>
|
||||
<PSTIME>1277375186</PSTIME>
|
||||
<PETIME>1277375186</PETIME>
|
||||
<RSTIME>1277375186</RSTIME>
|
||||
<RETIME>0</RETIME>
|
||||
<ESTIME>0</ESTIME>
|
||||
<EETIME>0</EETIME>
|
||||
<REASON>0</REASON>
|
||||
</HISTORY>
|
||||
</HISTORY_RECORDS>
|
||||
</VM>
|
||||
</VM_POOL>
|
|
@ -0,0 +1,46 @@
|
|||
<VNET>
|
||||
<ID>3</ID>
|
||||
<UID>0</UID>
|
||||
<GID>0</GID>
|
||||
<UNAME>oneadmin</UNAME>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>Red LAN</NAME>
|
||||
<PERMISSIONS>
|
||||
<OWNER_U>1</OWNER_U>
|
||||
<OWNER_M>1</OWNER_M>
|
||||
<OWNER_A>0</OWNER_A>
|
||||
<GROUP_U>0</GROUP_U>
|
||||
<GROUP_M>0</GROUP_M>
|
||||
<GROUP_A>0</GROUP_A>
|
||||
<OTHER_U>1</OTHER_U>
|
||||
<OTHER_M>0</OTHER_M>
|
||||
<OTHER_A>0</OTHER_A>
|
||||
</PERMISSIONS>
|
||||
<CLUSTER_ID>-1</CLUSTER_ID>
|
||||
<CLUSTER/>
|
||||
<BRIDGE>vbr0</BRIDGE>
|
||||
<VLAN>1</VLAN>
|
||||
<PARENT_NETWORK_ID/>
|
||||
<PHYDEV><![CDATA[bond1]]></PHYDEV>
|
||||
<VLAN_ID><![CDATA[1337]]></VLAN_ID>
|
||||
<USED_LEASES>3</USED_LEASES>
|
||||
<TEMPLATE/>
|
||||
<AR_POOL>
|
||||
<AR>
|
||||
<ALLOCATED><![CDATA[ 0 68719479930 1 68719545020]]></ALLOCATED>
|
||||
<AR_ID><![CDATA[0]]></AR_ID>
|
||||
<IP><![CDATA[10.1.0.10]]></IP>
|
||||
<MAC><![CDATA[00:22:44:66:88:aa]]></MAC>
|
||||
<SIZE><![CDATA[507]]></SIZE>
|
||||
<TYPE><![CDATA[IP4]]></TYPE>
|
||||
</AR>
|
||||
<AR>
|
||||
<ALLOCATED><![CDATA[ 0 68719546783]]></ALLOCATED>
|
||||
<AR_ID><![CDATA[1]]></AR_ID>
|
||||
<IP><![CDATA[10.1.2.5]]></IP>
|
||||
<MAC><![CDATA[00:22:44:66:aa:cc]]></MAC>
|
||||
<SIZE><![CDATA[507]]></SIZE>
|
||||
<TYPE><![CDATA[IP4]]></TYPE>
|
||||
</AR>
|
||||
</AR_POOL>
|
||||
</VNET>
|
|
@ -0,0 +1,60 @@
|
|||
<VNET_POOL>
|
||||
<VNET>
|
||||
<ID>4</ID>
|
||||
<UID>0</UID>
|
||||
<GID>0</GID>
|
||||
<UNAME>oneadmin</UNAME>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>Red LAN</NAME>
|
||||
<PERMISSIONS>
|
||||
<OWNER_U>1</OWNER_U>
|
||||
<OWNER_M>1</OWNER_M>
|
||||
<OWNER_A>0</OWNER_A>
|
||||
<GROUP_U>0</GROUP_U>
|
||||
<GROUP_M>0</GROUP_M>
|
||||
<GROUP_A>0</GROUP_A>
|
||||
<OTHER_U>1</OTHER_U>
|
||||
<OTHER_M>0</OTHER_M>
|
||||
<OTHER_A>0</OTHER_A>
|
||||
</PERMISSIONS>
|
||||
<CLUSTER_ID>-1</CLUSTER_ID>
|
||||
<CLUSTER/>
|
||||
<BRIDGE>vbr0</BRIDGE>
|
||||
<VLAN>1</VLAN>
|
||||
<PARENT_NETWORK_ID/>
|
||||
<PHYDEV><![CDATA[bond1]]></PHYDEV>
|
||||
<VLAN_ID><![CDATA[1337]]></VLAN_ID>
|
||||
<USED_LEASES>3</USED_LEASES>
|
||||
<TEMPLATE/>
|
||||
<AR_POOL/>
|
||||
</VNET>
|
||||
<VNET>
|
||||
<ID>9</ID>
|
||||
<UID>0</UID>
|
||||
<GID>0</GID>
|
||||
<UNAME>oneadmin</UNAME>
|
||||
<GNAME>oneadmin</GNAME>
|
||||
<NAME>Public</NAME>
|
||||
<PERMISSIONS>
|
||||
<OWNER_U>1</OWNER_U>
|
||||
<OWNER_M>1</OWNER_M>
|
||||
<OWNER_A>0</OWNER_A>
|
||||
<GROUP_U>0</GROUP_U>
|
||||
<GROUP_M>0</GROUP_M>
|
||||
<GROUP_A>0</GROUP_A>
|
||||
<OTHER_U>1</OTHER_U>
|
||||
<OTHER_M>0</OTHER_M>
|
||||
<OTHER_A>0</OTHER_A>
|
||||
</PERMISSIONS>
|
||||
<CLUSTER_ID>-1</CLUSTER_ID>
|
||||
<CLUSTER/>
|
||||
<BRIDGE>vbr0</BRIDGE>
|
||||
<VLAN>1</VLAN>
|
||||
<PARENT_NETWORK_ID/>
|
||||
<PHYDEV><![CDATA[bond1]]></PHYDEV>
|
||||
<VLAN_ID><![CDATA[42]]></VLAN_ID>
|
||||
<USED_LEASES>0</USED_LEASES>
|
||||
<TEMPLATE/>
|
||||
<AR_POOL/>
|
||||
</VNET>
|
||||
</VNET_POOL>
|
|
@ -0,0 +1,25 @@
|
|||
# vim: set fileencoding=utf8
|
||||
# encoding:utf8
|
||||
#
|
||||
# Author: Matthias Schmitz <matthias@sigxcpu.org>
|
||||
|
||||
import os
|
||||
import unittest
|
||||
|
||||
import oca
|
||||
|
||||
|
||||
@unittest.skipUnless(os.environ.get('OCA_INT_TESTS', False),
|
||||
"Skipping integration tests")
|
||||
class IntTestClient(unittest.TestCase):
|
||||
def setUp(self):
|
||||
try:
|
||||
del os.environ["ONE_AUTH"]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
self.c = oca.Client(os.environ['OCA_INT_TESTS_ONE_AUTH'],
|
||||
os.environ['OCA_INT_TESTS_ONE_XMLRPC'])
|
||||
|
||||
def test_connection(self):
|
||||
self.assertIn(os.environ['OCA_INT_TESTS'], self.c.version())
|
|
@ -0,0 +1,66 @@
|
|||
# vim: set fileencoding=utf8
|
||||
# encoding:utf8
|
||||
#
|
||||
# Author: Matthias Schmitz <matthias@sigxcpu.org>
|
||||
|
||||
import os
|
||||
import unittest
|
||||
|
||||
import oca
|
||||
from oca.exceptions import OpenNebulaException
|
||||
|
||||
|
||||
@unittest.skipUnless(os.environ.get('OCA_INT_TESTS', False),
|
||||
"Skipping integration tests")
|
||||
class IntTestTemplate(unittest.TestCase):
|
||||
def setUp(self):
|
||||
try:
|
||||
del os.environ["ONE_AUTH"]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
self.c = oca.Client(os.environ['OCA_INT_TESTS_ONE_AUTH'], os.environ['OCA_INT_TESTS_ONE_XMLRPC'])
|
||||
|
||||
def tearDown(self):
|
||||
print("teardown")
|
||||
vmp = oca.VirtualMachinePool(self.c)
|
||||
vmp.info()
|
||||
for vm in vmp:
|
||||
if vm.name.startswith('inttest_vm_'):
|
||||
vm.delete()
|
||||
|
||||
def test_allocate(self):
|
||||
templ = oca.VmTemplate.allocate(self.c, '<VMTEMPLATE><NAME>inttest01</NAME><TEMPLATE/></VMTEMPLATE>')
|
||||
templ = oca.VmTemplate.allocate(self.c, '<VMTEMPLATE><NAME>inttest02</NAME><TEMPLATE/></VMTEMPLATE>')
|
||||
templ = oca.VmTemplate.allocate(self.c, '<VMTEMPLATE><NAME>inttest03</NAME><TEMPLATE/></VMTEMPLATE>')
|
||||
templ = oca.VmTemplate.allocate(self.c, '<VMTEMPLATE><NAME>inttest04</NAME><TEMPLATE/></VMTEMPLATE>')
|
||||
|
||||
def test_allocate_with_same_name(self):
|
||||
with self.assertRaises(OpenNebulaException):
|
||||
templ = oca.VmTemplate.allocate(self.c, '<VMTEMPLATE><NAME>inttest01</NAME><TEMPLATE/></VMTEMPLATE>')
|
||||
|
||||
def test_update(self):
|
||||
oca.VmTemplate.allocate(self.c, '<VMTEMPLATE><NAME>inttest_update01</NAME><TEMPLATE/></VMTEMPLATE>')
|
||||
tp = oca.VmTemplatePool(self.c)
|
||||
tp.info()
|
||||
templ = tp.get_by_name('inttest_update01')
|
||||
templ.update('MEMORY=1024 CPU=2')
|
||||
|
||||
def test_delete(self):
|
||||
tp = oca.VmTemplatePool(self.c)
|
||||
tp.info()
|
||||
for tpl in tp:
|
||||
if tpl.name.startswith('inttest'):
|
||||
tpl.delete()
|
||||
|
||||
def test_instantiate(self):
|
||||
templ = oca.VmTemplate.allocate(self.c,
|
||||
'<VMTEMPLATE><NAME>inttest_instantiate_me01</NAME><MEMORY>1234</MEMORY><CPU>2</CPU></VMTEMPLATE>')
|
||||
tp = oca.VmTemplatePool(self.c)
|
||||
tp.info()
|
||||
templ = tp.get_by_name('inttest_instantiate_me01')
|
||||
templ.instantiate('inttest_vm_instantiate_me01')
|
||||
vmpool = oca.VirtualMachinePool(self.c)
|
||||
vmpool.info()
|
||||
vm = vmpool.get_by_name('inttest_vm_instantiate_me01')
|
||||
self.assertEqual(vm.name, 'inttest_vm_instantiate_me01')
|
|
@ -0,0 +1,107 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import socket
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
from nose.tools import raises
|
||||
|
||||
import oca
|
||||
|
||||
|
||||
class TestClient(unittest.TestCase):
|
||||
def setUp(self):
|
||||
try:
|
||||
del os.environ["ONE_AUTH"]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
def test_secret(self):
|
||||
c = oca.Client('test:test')
|
||||
assert c.one_auth == 'test:test'
|
||||
|
||||
def test_one_auth(self):
|
||||
os.environ["ONE_AUTH"] = os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/one_auth')
|
||||
try:
|
||||
c = oca.Client()
|
||||
secret = 'test:test'
|
||||
assert c.one_auth == secret
|
||||
finally:
|
||||
os.environ["ONE_AUTH"] = ''
|
||||
|
||||
def test_default_user_path(self):
|
||||
os.environ["ONE_AUTH"] = os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/one_auth')
|
||||
c = oca.Client()
|
||||
assert c.one_auth == 'test:test'
|
||||
|
||||
@raises(oca.OpenNebulaException)
|
||||
def test_wrong_default_user_path(self):
|
||||
oca.Client.DEFAULT_ONE_AUTH = '/ad/ads/a/das/d/sad/sad/sa/d/one_auth'
|
||||
c = oca.Client()
|
||||
|
||||
@raises(oca.OpenNebulaException)
|
||||
def test_invalid_secret(self):
|
||||
os.environ["ONE_AUTH"] = os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/one_auth')
|
||||
c = oca.Client('testtest')
|
||||
|
||||
def test_addres(self):
|
||||
c = oca.Client('test:test', "http://8.8.8.8:2633/RPC2")
|
||||
assert c.one_address == "http://8.8.8.8:2633/RPC2"
|
||||
|
||||
def test_one_xml_rpc(self):
|
||||
os.environ["ONE_AUTH"] = os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/one_auth')
|
||||
os.environ["ONE_XMLRPC"] = "http://8.8.8.8:2633/RPC2"
|
||||
try:
|
||||
c = oca.Client()
|
||||
assert c.one_address == "http://8.8.8.8:2633/RPC2"
|
||||
finally:
|
||||
os.environ["ONE_XMLRPC"] = ''
|
||||
|
||||
def test_defaul_xmlrpc(self):
|
||||
c = oca.Client('test:test')
|
||||
assert c.one_address == oca.Client.DEFAULT_ONE_ADDRESS
|
||||
|
||||
def test_version(self):
|
||||
c = oca.Client('test:test')
|
||||
assert c.one_version is None
|
||||
c.call = Mock(return_value='1.0.0')
|
||||
assert c.version() == '1.0.0'
|
||||
c.call.assert_called_once_with('system.version')
|
||||
assert c.one_version == '1.0.0'
|
||||
|
||||
def test_return_two_values_call(self):
|
||||
c = oca.Client('test:test')
|
||||
c.server.one = Mock()
|
||||
c.server.one.test_method = lambda x: [True, '2', 0]
|
||||
assert c.call('test_method') == '2'
|
||||
|
||||
def test_return_one_value_call(self):
|
||||
c = oca.Client('test:test')
|
||||
c.server.one = Mock()
|
||||
c.server.one.test_method = lambda x: [True, '', 0]
|
||||
assert c.call('test_method') == ''
|
||||
|
||||
@raises(oca.OpenNebulaException)
|
||||
def test_retrurn_error_code_0_call(self):
|
||||
c = oca.Client('test:test')
|
||||
c.server.one = Mock()
|
||||
c.server.one.test_method = lambda x: [False, '2', 1]
|
||||
c.call('test_method')
|
||||
|
||||
@raises(oca.OpenNebulaException)
|
||||
def test_invalid_call(self):
|
||||
c = oca.Client('test:test')
|
||||
c.server.one = Mock()
|
||||
c.server.one.test_method = lambda x: [False, '2']
|
||||
c.call('test_method')
|
||||
|
||||
@raises(socket.error)
|
||||
def test_connection_error(self):
|
||||
c = oca.Client('test:test')
|
||||
c.server.one = Mock()
|
||||
c.server.one.test_method = Mock(side_effect=socket.error(1))
|
||||
c.call('test_method')
|
|
@ -0,0 +1,33 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
|
||||
import oca
|
||||
|
||||
|
||||
class TestCluster(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/cluster.xml')).read()
|
||||
|
||||
def test_allocate(self):
|
||||
self.client.call = Mock(return_value=3)
|
||||
assert oca.Cluster.allocate(self.client, 'test') == 3
|
||||
|
||||
def test_repr(self):
|
||||
self.client.call = Mock()
|
||||
cluster = oca.Cluster(self.xml, self.client)
|
||||
assert repr(cluster) == '<oca.Cluster("oneCluster")>'
|
||||
|
||||
def test_convert_types(self):
|
||||
cluster = oca.Cluster(self.xml, None)
|
||||
cluster._convert_types()
|
||||
assert cluster.id == 101
|
||||
assert cluster.name == "oneCluster"
|
||||
assert cluster.host_ids == [2, 3]
|
||||
assert cluster.datastore_ids == [4, 5]
|
||||
assert cluster.vnet_ids == [6, 7]
|
||||
assert cluster.template.reserved_cpu is None
|
|
@ -0,0 +1,21 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
|
||||
import oca
|
||||
|
||||
|
||||
class TestClusterPool(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/clusterpool.xml')).read()
|
||||
|
||||
def test_info(self):
|
||||
self.client.call = Mock(return_value=self.xml)
|
||||
pool = oca.ClusterPool(self.client)
|
||||
pool.info()
|
||||
assert len(pool) == 2
|
||||
assert pool[1].name == "anotherCluster"
|
|
@ -0,0 +1,45 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
|
||||
import oca
|
||||
|
||||
|
||||
class TestDatastore(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/datastore.xml')).read()
|
||||
|
||||
def test_allocate(self):
|
||||
self.client.call = Mock(return_value=3)
|
||||
assert oca.Datastore.allocate(self.client, 'test') == 3
|
||||
|
||||
def test_repr(self):
|
||||
self.client.call = Mock()
|
||||
datastore = oca.Datastore(self.xml, self.client)
|
||||
assert repr(datastore) == '<oca.Datastore("Custom-DS")>'
|
||||
|
||||
def test_convert_types(self):
|
||||
cluster = oca.Datastore(self.xml, None)
|
||||
cluster._convert_types()
|
||||
assert cluster.id == 100
|
||||
assert cluster.name == "Custom-DS"
|
||||
assert cluster.uid == 0
|
||||
assert cluster.gid == 0
|
||||
assert cluster.uname == 'oneadmin'
|
||||
assert cluster.gname == 'oneadmin'
|
||||
assert cluster.ds_mad == 'fs'
|
||||
assert cluster.tm_mad == 'ssh'
|
||||
assert cluster.base_path == '/var/lib/one//datastores/100'
|
||||
assert cluster.type == 0
|
||||
assert cluster.disk_type == 0
|
||||
assert cluster.cluster_id == -1
|
||||
assert cluster.cluster == ""
|
||||
assert cluster.total_mb == 9952
|
||||
assert cluster.free_mb == 8999
|
||||
assert cluster.used_mb == 425
|
||||
assert cluster.image_ids == [2, 3]
|
||||
assert cluster.template.disk_type == 'FILE'
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
|
||||
import oca
|
||||
|
||||
|
||||
class TestDatastorePool(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/datastorepool.xml')).read()
|
||||
|
||||
def test_info(self):
|
||||
self.client.call = Mock(return_value=self.xml)
|
||||
pool = oca.DatastorePool(self.client)
|
||||
pool.info()
|
||||
assert len(list(pool)) == 2
|
|
@ -0,0 +1,37 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
|
||||
import oca
|
||||
|
||||
|
||||
class TestGroup(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/group.xml')).read()
|
||||
|
||||
def test_allocate(self):
|
||||
self.client.call = Mock(return_value=3)
|
||||
assert oca.Group.allocate(self.client, 'test') == 3
|
||||
|
||||
def test_delete(self):
|
||||
self.client.call = Mock()
|
||||
group = oca.Group(self.xml, self.client)
|
||||
group.delete()
|
||||
self.client.call.assert_called_once_with('group.delete', '1')
|
||||
|
||||
def test_repr(self):
|
||||
self.client.call = Mock()
|
||||
group = oca.Group(self.xml, self.client)
|
||||
assert repr(group) == '<oca.Group("users")>'
|
||||
|
||||
def test_convert_types(self):
|
||||
group = oca.Group(self.xml, None)
|
||||
group._convert_types()
|
||||
assert group.id == 1
|
||||
assert group.name == "users"
|
||||
assert group.template.hello == "world"
|
||||
assert group.users == [1, 2]
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
|
||||
import oca
|
||||
|
||||
|
||||
class TestGroupPool(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/grouppool.xml')).read()
|
||||
|
||||
def test_info(self):
|
||||
self.client.call = Mock(return_value=self.xml)
|
||||
pool = oca.GroupPool(self.client)
|
||||
pool.info()
|
||||
assert len(pool) == 2
|
|
@ -0,0 +1,80 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
from xml.etree import ElementTree as ET
|
||||
from parameterized import parameterized_class
|
||||
|
||||
import oca
|
||||
|
||||
|
||||
@parameterized_class([
|
||||
{'one_version': '4.10.0'},
|
||||
{'one_version': '5.4.0'},
|
||||
{'one_version': '6.0.0'},
|
||||
])
|
||||
class TestHost(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.client.call = Mock(return_value=self.one_version)
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/host.xml')).read()
|
||||
|
||||
if self.one_version >= '5':
|
||||
xml_v5 = ET.fromstring(self.xml)
|
||||
[xml_v5.remove(vn_mad) for vn_mad in xml_v5.findall('VN_MAD')]
|
||||
self.xml = ET.tostring(xml_v5).decode('utf-8')
|
||||
|
||||
def tearDown(self):
|
||||
version = self.client.one_version
|
||||
if version is not None and version >= '5':
|
||||
xml_types = oca.Host.XML_TYPES
|
||||
xml_types['vn_mad'] = oca.pool.extractString
|
||||
|
||||
def test_instantiate(self):
|
||||
h = oca.Host(self.xml, self.client)
|
||||
self.client.call.assert_called_once_with('system.version')
|
||||
expected = 'vn_dummy' if self.one_version == '4.10.0' else None
|
||||
assert (getattr(h, 'vn_mad', None) == expected)
|
||||
|
||||
def test_allocate(self):
|
||||
self.client.call = Mock(return_value=7)
|
||||
host_id = oca.Host.allocate(self.client, 'host', 'im_xen',
|
||||
'vmm_xen', 'tm_nfs')
|
||||
assert host_id == 7
|
||||
|
||||
def test_enable(self):
|
||||
h = oca.Host(self.xml, self.client)
|
||||
self.client.call = Mock(return_value='')
|
||||
h.enable()
|
||||
self.client.call.assert_called_once_with('host.enable', '7', True)
|
||||
|
||||
def test_disable(self):
|
||||
h = oca.Host(self.xml, self.client)
|
||||
self.client.call = Mock(return_value='')
|
||||
h.disable()
|
||||
self.client.call.assert_called_once_with('host.enable', '7', False)
|
||||
|
||||
def test_states(self):
|
||||
for i in range(len(oca.Host.HOST_STATES)):
|
||||
h = oca.Host('<HOST><ID>2</ID><STATE>{0}</STATE></HOST>'.format(i),
|
||||
self.client)
|
||||
assert h.str_state == oca.Host.HOST_STATES[i]
|
||||
assert h.short_state == oca.Host.SHORT_HOST_STATES[oca.Host.HOST_STATES[i]]
|
||||
|
||||
def test_repr(self):
|
||||
h = oca.Host(self.xml, self.client)
|
||||
assert h.__repr__() == '<oca.Host("dummyhost")>'
|
||||
|
||||
def test_host_share_repr(self):
|
||||
h = oca.Host(self.xml, self.client)
|
||||
h._convert_types()
|
||||
share = h.host_share
|
||||
assert repr(share) == '<oca.vm.HostShare()>'
|
||||
|
||||
def test_host_vm_ids(self):
|
||||
h = oca.Host(self.xml, self.client)
|
||||
h._convert_types()
|
||||
vm_ids = list(h.vm_ids)
|
||||
assert vm_ids == [82, 84, 85, 95, 96]
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
|
||||
import oca
|
||||
|
||||
|
||||
class TestHostPool(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/hostpool.xml')).read()
|
||||
|
||||
def test_info(self):
|
||||
self.client.call = Mock(return_value=self.xml)
|
||||
pool = oca.HostPool(self.client)
|
||||
pool.info()
|
||||
assert len(pool) == 2
|
|
@ -0,0 +1,109 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
|
||||
import oca
|
||||
import oca.pool
|
||||
|
||||
IMAGE_TEMPLATE = """NAME = "Ubuntu Desktop"
|
||||
PATH = /home/cloud/images/ubuntu-desktop/disk.0
|
||||
PUBLIC = YES
|
||||
DESCRIPTION = "Ubuntu 10.04 desktop for students.\""""
|
||||
|
||||
DEFAULT_IMG_DATASTORE = 1
|
||||
|
||||
|
||||
class TestImage(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/image.xml')).read()
|
||||
|
||||
def test_allocate(self):
|
||||
self.client.call = Mock(return_value=2)
|
||||
assert oca.Image.allocate(self.client, IMAGE_TEMPLATE, DEFAULT_IMG_DATASTORE) == 2
|
||||
|
||||
def test_enable(self):
|
||||
self.client.call = Mock(return_value='')
|
||||
h = oca.Image(self.xml, self.client)
|
||||
h.enable()
|
||||
self.client.call.assert_called_once_with('image.enable', '1', True)
|
||||
|
||||
def test_disable(self):
|
||||
self.client.call = Mock(return_value='')
|
||||
h = oca.Image(self.xml, self.client)
|
||||
h.disable()
|
||||
self.client.call.assert_called_once_with('image.enable', '1', False)
|
||||
|
||||
def test_update(self):
|
||||
self.client.call = Mock(return_value='')
|
||||
h = oca.Image(self.xml, self.client)
|
||||
new_content = 'DEV_PREFIX=hd\nNAME=Debian\nTYPE=OS'
|
||||
h.update(new_content)
|
||||
self.client.call.assert_called_once_with('image.update', '1',
|
||||
new_content)
|
||||
|
||||
def test_publish(self):
|
||||
self.client.call = Mock(return_value='')
|
||||
h = oca.Image(self.xml, self.client)
|
||||
assert h.publish() is None
|
||||
|
||||
def test_unpublish(self):
|
||||
self.client.call = Mock(return_value='')
|
||||
h = oca.Image(self.xml, self.client)
|
||||
assert h.unpublish() is None
|
||||
|
||||
def test_set_persistent(self):
|
||||
self.client.call = Mock(return_value='')
|
||||
h = oca.Image(self.xml, self.client)
|
||||
h.set_persistent()
|
||||
self.client.call.assert_called_once_with('image.persistent',
|
||||
'1', True)
|
||||
|
||||
def test_set_nonpersistent(self):
|
||||
self.client.call = Mock(return_value='')
|
||||
h = oca.Image(self.xml, self.client)
|
||||
h.set_nonpersistent()
|
||||
self.client.call.assert_called_once_with('image.persistent',
|
||||
'1', False)
|
||||
|
||||
def test_states(self):
|
||||
for i in range(len(oca.Image.IMAGE_STATES)):
|
||||
h = oca.Image('<IMAGE><ID>2</ID><STATE>%s</STATE></IMAGE>' % i,
|
||||
self.client)
|
||||
assert h.str_state == oca.Image.IMAGE_STATES[i]
|
||||
short_image_state = oca.Image.SHORT_IMAGE_STATES[oca.Image.IMAGE_STATES[i]]
|
||||
assert h.short_state == short_image_state
|
||||
|
||||
def test_repr(self):
|
||||
h = oca.Image(self.xml, self.client)
|
||||
assert h.__repr__() == '<oca.Image("MATLAB install CD")>'
|
||||
|
||||
def test_types(self):
|
||||
for i in range(len(oca.Image.IMAGE_TYPES)):
|
||||
h = oca.Image('<IMAGE><ID>2</ID><TYPE>%s</TYPE></IMAGE>' % i,
|
||||
self.client)
|
||||
assert h.str_type == oca.Image.IMAGE_TYPES[i]
|
||||
short_image_type = oca.Image.SHORT_IMAGE_TYPES[oca.Image.IMAGE_TYPES[i]]
|
||||
assert h.short_type == short_image_type
|
||||
|
||||
def test_template(self):
|
||||
i = oca.Image(self.xml, self.client)
|
||||
i._convert_types()
|
||||
assert isinstance(i.template, oca.pool.Template)
|
||||
|
||||
def test_chown(self):
|
||||
self.client.call = Mock(return_value='')
|
||||
h = oca.Image(self.xml, self.client)
|
||||
h.chown(10, 10)
|
||||
self.client.call.assert_called_once_with('image.chown',
|
||||
'1', 10, 10)
|
||||
|
||||
def test_chmod(self):
|
||||
self.client.call = Mock(return_value='')
|
||||
h = oca.Image(self.xml, self.client)
|
||||
h.chmod(1, 0, 0, -1, -1, -1, -1, -1, -1)
|
||||
self.client.call.assert_called_once_with('image.chmod',
|
||||
'1', 1, 0, 0, -1, -1, -1, -1, -1, -1)
|
|
@ -0,0 +1,22 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
|
||||
import oca
|
||||
|
||||
|
||||
class TestImagePool(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/imagepool.xml')).read()
|
||||
|
||||
def test_info(self):
|
||||
self.xml = self.xml.replace('\n', '')
|
||||
self.xml = self.xml.replace(' ', '')
|
||||
self.client.call = Mock(return_value=self.xml)
|
||||
pool = oca.ImagePool(self.client)
|
||||
pool.info()
|
||||
assert len(pool) == 3
|
|
@ -0,0 +1,12 @@
|
|||
class TestIntegration:
|
||||
# def setUp(self):
|
||||
# self.client = oca.Client("oneadmin:one", "http://localhost:2633/RPC2")
|
||||
# cp = oca.ClusterPool(self.client)
|
||||
# cp.info()
|
||||
# for cluster in cp:
|
||||
# cluster.delete()
|
||||
|
||||
# def test_integration(self):
|
||||
# self.cluster_id = oca.Cluster.allocate(self.client, "IT-Cluster")
|
||||
# #self.datastore_id = oca.
|
||||
pass
|
|
@ -0,0 +1,85 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
|
||||
import oca
|
||||
|
||||
|
||||
class TestVmTemplate(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/template.xml')).read()
|
||||
|
||||
def test_allocate(self):
|
||||
self.client.call = Mock(return_value=3)
|
||||
assert oca.VmTemplate.allocate(self.client, 'name=a') == 3
|
||||
|
||||
def test_delete(self):
|
||||
self.client.call = Mock()
|
||||
template = oca.VmTemplate(self.xml, self.client)
|
||||
template.delete()
|
||||
self.client.call.assert_called_once_with('template.delete', '1')
|
||||
|
||||
def test_update(self):
|
||||
self.client.call = Mock()
|
||||
template = oca.VmTemplate(self.xml, self.client)
|
||||
template.update('name=b')
|
||||
self.client.call.assert_called_once_with('template.update',
|
||||
'1', 'name=b', 0)
|
||||
|
||||
def test_publish(self):
|
||||
self.client.call = Mock()
|
||||
template = oca.VmTemplate(self.xml, self.client)
|
||||
template.publish()
|
||||
self.client.call.assert_called_once_with('template.publish',
|
||||
'1', True)
|
||||
|
||||
def test_unpublish(self):
|
||||
self.client.call = Mock()
|
||||
template = oca.VmTemplate(self.xml, self.client)
|
||||
template.unpublish()
|
||||
self.client.call.assert_called_once_with('template.publish',
|
||||
'1', False)
|
||||
|
||||
def test_chown(self):
|
||||
self.client.call = Mock()
|
||||
template = oca.VmTemplate(self.xml, self.client)
|
||||
template.chown(2, 3)
|
||||
self.client.call.assert_called_once_with('template.chown',
|
||||
'1', 2, 3)
|
||||
|
||||
def test_instantiate_with_default_name(self):
|
||||
self.client.call = Mock(return_value=4)
|
||||
template = oca.VmTemplate(self.xml, self.client)
|
||||
assert template.instantiate() == 4
|
||||
self.client.call.assert_called_once_with('template.instantiate',
|
||||
'1', '', False, '')
|
||||
|
||||
def test_instantiate_with_custom_name(self):
|
||||
self.client.call = Mock(return_value=5)
|
||||
template = oca.VmTemplate(self.xml, self.client)
|
||||
assert template.instantiate('asd') == 5
|
||||
self.client.call.assert_called_once_with('template.instantiate',
|
||||
'1', 'asd', False, '')
|
||||
|
||||
def test_instantiate_with_default_name_and_context(self):
|
||||
self.client.call = Mock(return_value=6)
|
||||
template = oca.VmTemplate(self.xml, self.client)
|
||||
assert template.instantiate('', False, 'VCPU=4') == 6
|
||||
self.client.call.assert_called_once_with('template.instantiate',
|
||||
'1', '', False, 'VCPU=4')
|
||||
|
||||
def test_instantiate_with_custom_name_and_context(self):
|
||||
self.client.call = Mock(return_value=7)
|
||||
template = oca.VmTemplate(self.xml, self.client)
|
||||
assert template.instantiate('asd', False, 'VCPU=4') == 7
|
||||
self.client.call.assert_called_once_with('template.instantiate',
|
||||
'1', 'asd', False, 'VCPU=4')
|
||||
|
||||
def test_repr(self):
|
||||
self.client.call = Mock()
|
||||
template = oca.VmTemplate(self.xml, self.client)
|
||||
assert repr(template) == '<oca.VmTemplate("test1")>'
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
|
||||
import oca
|
||||
|
||||
|
||||
class TestVmTemplatePool(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/templatepool.xml')).read()
|
||||
|
||||
def test_info(self):
|
||||
self.client.call = Mock(return_value=self.xml)
|
||||
pool = oca.VmTemplatePool(self.client)
|
||||
pool.info()
|
||||
assert len(pool) == 2
|
|
@ -0,0 +1,40 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
|
||||
import oca
|
||||
|
||||
|
||||
class TestUser(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/user.xml')).read()
|
||||
|
||||
def test_allocate(self):
|
||||
self.client.call = Mock(return_value=1)
|
||||
assert oca.User.allocate(self.client, 'jon', 'secret') == 1
|
||||
|
||||
def test_repr(self):
|
||||
u = oca.User(self.xml, self.client)
|
||||
assert u.__repr__() == '<oca.User("dan")>'
|
||||
|
||||
def test_change_passwd(self):
|
||||
self.client.call = Mock(return_value='')
|
||||
u = oca.User(self.xml, self.client)
|
||||
u.change_passwd('secret2')
|
||||
self.client.call.assert_called_once_with('user.passwd', '3', 'secret2')
|
||||
|
||||
def test_delete(self):
|
||||
self.client.call = Mock(return_value='')
|
||||
vm = oca.User(self.xml, self.client)
|
||||
vm.delete()
|
||||
self.client.call.assert_called_once_with('user.delete', '3')
|
||||
|
||||
def test_change_group(self):
|
||||
self.client.call = Mock(return_value='')
|
||||
vm = oca.User(self.xml, self.client)
|
||||
vm.chgrp(3)
|
||||
self.client.call.assert_called_once_with('user.chgrp', '3', 3)
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
|
||||
import oca
|
||||
|
||||
|
||||
class TestUserPool(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/userpool.xml')).read()
|
||||
|
||||
def test_info(self):
|
||||
self.client.call = Mock(return_value=self.xml)
|
||||
pool = oca.UserPool(self.client)
|
||||
pool.info()
|
||||
assert len(pool) == 2
|
|
@ -0,0 +1,92 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
from xml.etree import ElementTree as ET
|
||||
from parameterized import parameterized_class
|
||||
|
||||
import oca
|
||||
|
||||
VN_TEMPLATE = """NAME = "Red LAN"
|
||||
TYPE = RANGED
|
||||
PUBLIC = NO
|
||||
BRIDGE = vbr0
|
||||
NETWORK_SIZE = C
|
||||
NETWORK_ADDRESS = 192.168.0.0"""
|
||||
|
||||
|
||||
@parameterized_class([
|
||||
{'one_version': '4.10.0'},
|
||||
{'one_version': '5.4.0'},
|
||||
{'one_version': '6.0.0'},
|
||||
])
|
||||
class TestVirtualNetwork(unittest.TestCase):
|
||||
# one_version = '4.10.0'
|
||||
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.client.call = Mock(return_value=self.one_version)
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/vnet.xml')).read()
|
||||
|
||||
if self.one_version >= '5':
|
||||
xml_v5 = ET.fromstring(self.xml)
|
||||
vn_mad = ET.Element('VN_MAD')
|
||||
vn_mad.text = 'vn_dummy'
|
||||
xml_v5.append(vn_mad)
|
||||
self.xml = ET.tostring(xml_v5).decode('utf-8')
|
||||
|
||||
def tearDown(self):
|
||||
version = self.client.one_version
|
||||
if version is not None and version >= '5':
|
||||
xml_types = oca.VirtualNetwork.XML_TYPES
|
||||
del xml_types['vn_mad']
|
||||
|
||||
def test_instantiate(self):
|
||||
h = oca.VirtualNetwork(self.xml, self.client)
|
||||
self.client.call.assert_called_once_with('system.version')
|
||||
expected = None if self.one_version == '4.10.0' else 'vn_dummy'
|
||||
assert (getattr(h, 'vn_mad', None) == expected)
|
||||
|
||||
def test_allocate(self):
|
||||
self.client.call = Mock(return_value=2)
|
||||
assert oca.VirtualNetwork.allocate(self.client, VN_TEMPLATE) == 2
|
||||
|
||||
def test_publish(self):
|
||||
h = oca.VirtualNetwork(self.xml, self.client)
|
||||
self.client.call = Mock(return_value='')
|
||||
h._convert_types()
|
||||
h.publish()
|
||||
self.client.call.assert_called_once_with('vn.publish', 3, True)
|
||||
|
||||
def test_unpublish(self):
|
||||
h = oca.VirtualNetwork(self.xml, self.client)
|
||||
self.client.call = Mock(return_value='')
|
||||
h._convert_types()
|
||||
h.unpublish()
|
||||
self.client.call.assert_called_once_with('vn.publish', 3, False)
|
||||
|
||||
def test_repr(self):
|
||||
h = oca.VirtualNetwork(self.xml, self.client)
|
||||
h._convert_types()
|
||||
assert h.__repr__() == '<oca.VirtualNetwork("Red LAN")>'
|
||||
|
||||
def test_chown(self):
|
||||
h = oca.VirtualNetwork(self.xml, self.client)
|
||||
self.client.call = Mock(return_value='')
|
||||
h._convert_types()
|
||||
h.chown(2, 2)
|
||||
self.client.call.assert_called_once_with('vn.chown', 3, 2, 2)
|
||||
|
||||
def test_address_ranges(self):
|
||||
h = oca.VirtualNetwork(self.xml, self.client)
|
||||
h._convert_types()
|
||||
assert (2 == len(h.address_ranges))
|
||||
assert (1 == h.address_ranges[1].id)
|
||||
assert (0 == h.address_ranges[0].id)
|
||||
assert (" 0 68719479930 1 68719545020" == h.address_ranges[0].allocated)
|
||||
assert ("10.1.0.10" == h.address_ranges[0].ip)
|
||||
assert ("00:22:44:66:88:aa" == h.address_ranges[0].mac)
|
||||
assert (507 == h.address_ranges[0].size)
|
||||
assert ("IP4" == h.address_ranges[0].type)
|
|
@ -0,0 +1,21 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
|
||||
import oca
|
||||
|
||||
|
||||
class TestVirtualNetworkPool(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.client.one_version = '4.10.0'
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/vnetpool.xml')).read()
|
||||
|
||||
def test_info(self):
|
||||
self.client.call = Mock(return_value=self.xml)
|
||||
pool = oca.VirtualNetworkPool(self.client)
|
||||
pool.info()
|
||||
assert len(list(pool)) == 2
|
|
@ -0,0 +1,147 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
from nose.tools import raises
|
||||
|
||||
import oca
|
||||
import oca.pool
|
||||
|
||||
|
||||
class TestVirtualMachine(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/vm.xml')).read()
|
||||
|
||||
def test_new_with_id(self):
|
||||
vm = oca.VirtualMachine.new_with_id(self.client, 1)
|
||||
assert vm.id == 1
|
||||
|
||||
def test_acces_items_using_brackets(self):
|
||||
vm = oca.VirtualMachine(self.xml, self.client)
|
||||
assert vm['name'] == 'vm-example'
|
||||
assert vm['ID'] == '6'
|
||||
assert vm['last_poll'] == '1277729095'
|
||||
assert vm['state'] == '3'
|
||||
assert vm['lcm_state'] == '3'
|
||||
assert vm['stime'] == '1277375180'
|
||||
assert vm['etime'] == '0'
|
||||
assert vm['deploy_id'] == 'dummy'
|
||||
|
||||
def test_acces_items_not_using_brackets(self):
|
||||
vm = oca.VirtualMachine(self.xml, self.client)
|
||||
assert vm.name == 'vm-example'
|
||||
assert vm.ID == '6'
|
||||
assert vm.last_poll == '1277729095'
|
||||
assert vm.state == '3'
|
||||
assert vm.lcm_state == '3'
|
||||
assert vm.stime == '1277375180'
|
||||
assert vm.etime == '0'
|
||||
assert vm.deploy_id == 'dummy'
|
||||
|
||||
@raises(IndexError)
|
||||
def test_raise_exception_Index_Error_when_using_brackets(self):
|
||||
vm = oca.VirtualMachine(self.xml, self.client)
|
||||
vm['wrong_name']
|
||||
|
||||
def test_convert_types(self):
|
||||
vm = oca.VirtualMachine(self.xml, self.client)
|
||||
vm._convert_types()
|
||||
assert vm.name == 'vm-example'
|
||||
assert vm.id == 6
|
||||
assert vm.last_poll == 1277729095
|
||||
assert vm.state == 3
|
||||
assert vm.lcm_state == 3
|
||||
assert vm.stime == 1277375180
|
||||
assert vm.etime == 0
|
||||
assert vm.deploy_id == 'dummy'
|
||||
assert isinstance(vm.template, oca.pool.Template)
|
||||
|
||||
def test_allocate(self):
|
||||
self.client.call = Mock(return_value=3)
|
||||
assert oca.VirtualMachine.allocate(self.client, '<VM></VM>') == 3
|
||||
|
||||
def test_deploy(self):
|
||||
self.client.call = Mock(return_value='')
|
||||
vm = oca.VirtualMachine(self.xml, self.client)
|
||||
vm.deploy(3)
|
||||
self.client.call.assert_called_once_with('vm.deploy', '6', 3)
|
||||
|
||||
def test_migrate(self):
|
||||
self.client.call = Mock(return_value='')
|
||||
vm = oca.VirtualMachine(self.xml, self.client)
|
||||
vm.migrate(3)
|
||||
self.client.call.assert_called_once_with('vm.migrate', '6', 3, False)
|
||||
|
||||
def test_live_migrate(self):
|
||||
self.client.call = Mock(return_value='')
|
||||
vm = oca.VirtualMachine(self.xml, self.client)
|
||||
vm.live_migrate(3)
|
||||
self.client.call.assert_called_once_with('vm.migrate', '6', 3, True)
|
||||
|
||||
def test_save_disk(self):
|
||||
self.client.call = Mock(return_value='')
|
||||
vm = oca.VirtualMachine(self.xml, self.client)
|
||||
vm.save_disk(1, 2)
|
||||
self.client.call.assert_called_once_with('vm.savedisk', '6', 1, 2)
|
||||
|
||||
def test_actions(self):
|
||||
oca.client = oca.Client('test:test')
|
||||
vm = oca.VirtualMachine(self.xml, self.client)
|
||||
for action in ['shutdown', 'shutdown_hard', 'poweroff', 'poweroff_hard',
|
||||
'hold', 'release', 'stop', 'cancel', 'suspend', 'resume',
|
||||
'reboot', 'finalize', 'delete', 'resched', 'unresched']:
|
||||
self.client.call = Mock(return_value='')
|
||||
getattr(vm, action)()
|
||||
if action in ('shutdown_hard', 'poweroff_hard', 'undeploy_hard'):
|
||||
action = action.replace("_", "-")
|
||||
self.client.call.assert_called_once_with('vm.action', action, '6')
|
||||
|
||||
def test_repr(self):
|
||||
vm = oca.VirtualMachine(self.xml, self.client)
|
||||
assert vm.__repr__() == '<oca.VirtualMachine("vm-example")>'
|
||||
|
||||
def test_states(self):
|
||||
for i in range(len(oca.VirtualMachine.VM_STATE)):
|
||||
vm = oca.VirtualMachine('<VM><ID>2</ID><STATE>%s</STATE></VM>' % i,
|
||||
self.client)
|
||||
assert vm.str_state == oca.VirtualMachine.VM_STATE[i]
|
||||
state = oca.VirtualMachine.SHORT_VM_STATES[oca.VirtualMachine.VM_STATE[i]]
|
||||
assert vm.short_state == state
|
||||
|
||||
def test_lcm_states(self):
|
||||
for i in range(len(oca.VirtualMachine.LCM_STATE)):
|
||||
xml = '<VM><ID>2</ID><LCM_STATE>%s</LCM_STATE></VM>' % i
|
||||
vm = oca.VirtualMachine(xml, self.client)
|
||||
assert vm.str_lcm_state == oca.VirtualMachine.LCM_STATE[i]
|
||||
lcm = oca.VirtualMachine.SHORT_LCM_STATES[oca.VirtualMachine.LCM_STATE[i]]
|
||||
assert vm.short_lcm_state == lcm
|
||||
|
||||
def test_resubmit(self):
|
||||
self.client.call = Mock(return_value='')
|
||||
vm = oca.VirtualMachine(self.xml, self.client)
|
||||
vm.resubmit()
|
||||
self.client.call.assert_called_once_with('vm.action', 'resubmit', '6')
|
||||
|
||||
def test_History_repr(self):
|
||||
vm = oca.VirtualMachine(self.xml, self.client)
|
||||
vm._convert_types()
|
||||
history = vm.history_records[0]
|
||||
assert repr(history) == '<oca.vm.History("seq=0")>'
|
||||
|
||||
def test_no_history_records_element(self):
|
||||
vm = oca.VirtualMachine(self.xml, self.client)
|
||||
vm.xml.remove(vm.xml.find('HISTORY_RECORDS'))
|
||||
vm._convert_types()
|
||||
assert vm.history_records == []
|
||||
|
||||
def test_user_template_variables(self):
|
||||
vm = oca.VirtualMachine(self.xml, self.client)
|
||||
vm._convert_types()
|
||||
greeting = vm.user_template.greeting
|
||||
assert greeting == "Hello World"
|
||||
|
||||
def test_update(self):
|
||||
pass
|
|
@ -0,0 +1,52 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
from nose.tools import raises
|
||||
|
||||
import oca
|
||||
import oca.pool
|
||||
|
||||
|
||||
class TestVirtualMachinePool(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = oca.Client('test:test')
|
||||
self.xml = open(os.path.join(os.path.dirname(oca.__file__),
|
||||
'tests/fixtures/vmpool.xml')).read()
|
||||
|
||||
def test_vm_pool_info(self):
|
||||
self.client.call = Mock(return_value=self.xml)
|
||||
pool = oca.VirtualMachinePool(self.client)
|
||||
pool.info()
|
||||
assert len(list(pool)) == 3
|
||||
|
||||
def test_iterate_before_info(self):
|
||||
pool = oca.VirtualMachinePool(self.client)
|
||||
assert list(pool) == []
|
||||
|
||||
def test_get_by_id(self):
|
||||
self.client.call = Mock(return_value=self.xml)
|
||||
pool = oca.VirtualMachinePool(self.client)
|
||||
pool.info()
|
||||
assert pool.get_by_id(8).id == 8
|
||||
|
||||
def test_get_by_name(self):
|
||||
self.client.call = Mock(return_value=self.xml)
|
||||
pool = oca.VirtualMachinePool(self.client)
|
||||
pool.info()
|
||||
assert pool.get_by_name('vm-in').name == 'vm-in'
|
||||
|
||||
@raises(oca.pool.WrongIdError)
|
||||
def test_wrong_get_by_id(self):
|
||||
self.client.call = Mock(return_value=self.xml)
|
||||
pool = oca.VirtualMachinePool(self.client)
|
||||
pool.info()
|
||||
pool.get_by_id(1010011010)
|
||||
|
||||
@raises(oca.pool.WrongNameError)
|
||||
def test_wrong_get_by_name(self):
|
||||
self.client.call = Mock(return_value=self.xml)
|
||||
pool = oca.VirtualMachinePool(self.client)
|
||||
pool.info()
|
||||
pool.get_by_name('wrong-vm-name')
|
|
@ -0,0 +1,150 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
from .pool import Pool, PoolElement, Template, extractString, XMLElement
|
||||
|
||||
|
||||
class Quota(XMLElement):
|
||||
def __init__(self, xml):
|
||||
super(Quota, self).__init__(xml)
|
||||
self._convert_types()
|
||||
|
||||
|
||||
class VMQuota(Quota):
|
||||
XML_TYPES = {
|
||||
'cpu': int,
|
||||
'cpu_used': int,
|
||||
'memory': int,
|
||||
'memory_used': int,
|
||||
'system_disk_size': int,
|
||||
'system_disk_size_used': int,
|
||||
'vms': int,
|
||||
'vms_used': int,
|
||||
}
|
||||
|
||||
|
||||
class DatastoreQuota(Quota):
|
||||
XML_TYPES = {
|
||||
'images': int,
|
||||
'images_used': int,
|
||||
'size': int,
|
||||
'size_used': int,
|
||||
}
|
||||
|
||||
|
||||
class NetworkQuota(Quota):
|
||||
XML_TYPES = {
|
||||
'leases': int,
|
||||
'leases_used': int,
|
||||
}
|
||||
|
||||
|
||||
class VMQuotaList(Quota):
|
||||
XML_TYPES = {
|
||||
'vm': VMQuota,
|
||||
}
|
||||
|
||||
|
||||
class DatastoreQuotaList(Quota):
|
||||
XML_TYPES = {
|
||||
'datastore': DatastoreQuota,
|
||||
}
|
||||
|
||||
|
||||
class NetworkQuotaList(Quota):
|
||||
XML_TYPES = {
|
||||
'network': NetworkQuota,
|
||||
}
|
||||
|
||||
|
||||
class User(PoolElement):
|
||||
METHODS = {
|
||||
'info': 'user.info',
|
||||
'allocate': 'user.allocate',
|
||||
'delete': 'user.delete',
|
||||
'passwd': 'user.passwd',
|
||||
'chgrp': 'user.chgrp'
|
||||
}
|
||||
|
||||
XML_TYPES = {
|
||||
'id': int,
|
||||
'gid': int,
|
||||
'group_ids': ['GROUPS', lambda group_ids: [int(group_id.text) for group_id in group_ids]],
|
||||
'gname': extractString,
|
||||
'name': extractString,
|
||||
'password': extractString,
|
||||
'auth_driver': extractString,
|
||||
'enabled': bool,
|
||||
'template': ['TEMPLATE', Template],
|
||||
# 'network_quota': handled separately # see http://dev.opennebula.org/issues/3849
|
||||
# 'image_quota' # see http://dev.opennebula.org/issues/3849
|
||||
# 'default_user_quotas' # see http://dev.opennebula.org/issues/3849
|
||||
}
|
||||
|
||||
ELEMENT_NAME = 'USER'
|
||||
|
||||
@staticmethod
|
||||
def allocate(client, user, password):
|
||||
"""
|
||||
allocates a new user in OpenNebula
|
||||
|
||||
``user``
|
||||
username for the new user
|
||||
|
||||
``password``
|
||||
password for the new user
|
||||
"""
|
||||
user_id = client.call(User.METHODS['allocate'], user, password)
|
||||
return user_id
|
||||
|
||||
def __init__(self, xml, client):
|
||||
super(User, self).__init__(xml, client)
|
||||
self.id = self['ID'] if self['ID'] else None
|
||||
|
||||
def change_passwd(self, new_password):
|
||||
"""
|
||||
Changes the password for the given user.
|
||||
|
||||
``new_password``
|
||||
The new password
|
||||
"""
|
||||
self.client.call(User.METHODS['passwd'], self.id, new_password)
|
||||
|
||||
def chgrp(self, gid):
|
||||
"""
|
||||
Changes the main group
|
||||
|
||||
``gid``
|
||||
New group id. Set to -1 to leave the current one
|
||||
"""
|
||||
self.client.call(User.METHODS['chgrp'], self.id, gid)
|
||||
|
||||
@property
|
||||
def vm_quota(self):
|
||||
self.info()
|
||||
return VMQuotaList(self.xml.find('VM_QUOTA')).vm
|
||||
|
||||
@property
|
||||
def datastore_quota(self):
|
||||
self.info()
|
||||
return DatastoreQuotaList(self.xml.find('DATASTORE_QUOTA')).datastore
|
||||
|
||||
@property
|
||||
def network_quota(self):
|
||||
self.info()
|
||||
return NetworkQuotaList(self.xml.find('NETWORK_QUOTA')).network
|
||||
|
||||
def __repr__(self):
|
||||
return '<oca.User("%s")>' % self.name
|
||||
|
||||
|
||||
class UserPool(Pool):
|
||||
METHODS = {
|
||||
'info': 'userpool.info',
|
||||
}
|
||||
|
||||
def __init__(self, client):
|
||||
super(UserPool, self).__init__('USER_POOL', 'USER', client)
|
||||
|
||||
def _factory(self, xml):
|
||||
u = User(xml, self.client)
|
||||
u._convert_types()
|
||||
return u
|
|
@ -0,0 +1,458 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
from .pool import Pool, PoolElement, Template, extractString
|
||||
|
||||
|
||||
class History(Template):
|
||||
def __repr__(self):
|
||||
return '<oca.vm.History("seq={0}")>'.format(self.seq)
|
||||
|
||||
|
||||
class VirtualMachine(PoolElement):
|
||||
METHODS = {
|
||||
'info': 'vm.info',
|
||||
'allocate': 'vm.allocate',
|
||||
'action': 'vm.action',
|
||||
'migrate': 'vm.migrate',
|
||||
'deploy': 'vm.deploy',
|
||||
'savedisk': 'vm.savedisk',
|
||||
'delete': 'vm.delete',
|
||||
'chown': 'vm.chown',
|
||||
'update': 'vm.update',
|
||||
}
|
||||
|
||||
INIT = 0
|
||||
PENDING = 1
|
||||
HOLD = 2
|
||||
ACTIVE = 3
|
||||
STOPPED = 4
|
||||
SUSPENDED = 5
|
||||
DONE = 6
|
||||
FAILED = 7
|
||||
POWEROFF = 8
|
||||
UNDEPLOYED = 9
|
||||
VM_STATE = ['INIT', 'PENDING', 'HOLD', 'ACTIVE', 'STOPPED',
|
||||
'SUSPENDED', 'DONE', 'FAILED', 'POWEROFF', 'UNDEPLOYED']
|
||||
|
||||
SHORT_VM_STATES = {
|
||||
'INIT': 'init',
|
||||
'PENDING': 'pend',
|
||||
'HOLD': 'hold',
|
||||
'ACTIVE': 'actv',
|
||||
'STOPPED': 'stop',
|
||||
'SUSPENDED': 'susp',
|
||||
'DONE': 'done',
|
||||
'FAILED': 'fail',
|
||||
'POWEROFF': 'poff',
|
||||
'UNDEPLOYED': 'udep'
|
||||
}
|
||||
|
||||
LCM_STATE = ['LCM_INIT', 'PROLOG', 'BOOT', 'RUNNING', 'MIGRATE', 'SAVE_STOP', 'SAVE_SUSPEND',
|
||||
'SAVE_MIGRATE', 'PROLOG_MIGRATE', 'PROLOG_RESUME', 'EPILOG_STOP', 'EPILOG',
|
||||
'SHUTDOWN', 'CANCEL', 'FAILURE', 'CLEANUP_RESUBMIT', 'UNKNOWN', 'HOTPLUG',
|
||||
'SHUTDOWN_POWEROFF', 'BOOT_UNKNOWN', 'BOOT_POWEROFF', 'BOOT_SUSPENDED',
|
||||
'BOOT_STOPPED', 'CLEANUP_DELETE', 'HOTPLUG_SNAPSHOT', 'HOTPLUG_NIC',
|
||||
'HOTPLUG_SAVEAS', 'HOTPLUG_SAVEAS_POWEROFF', 'HOTPLUG_SAVEAS_SUSPENDED',
|
||||
'SHUTDOWN_UNDEPLOY', 'EPILOG_UNDEPLOY', 'PROLOG_UNDEPLOY', 'BOOT_UNDEPLOY',
|
||||
'HOTPLUG_PROLOG_POWEROFF', 'HOTPLUG_EPILOG_POWEROFF', 'BOOT_MIGRATE',
|
||||
'BOOT_FAILURE', 'BOOT_MIGRATE_FAILURE', 'PROLOG_MIGRATE_FAILURE',
|
||||
'PROLOG_FAILURE', 'EPILOG_FAILURE', 'EPILOG_STOP_FAILURE',
|
||||
'EPILOG_UNDEPLOY_FAILURE', 'PROLOG_MIGRATE_POWEROFF',
|
||||
'PROLOG_MIGRATE_POWEROFF_FAILURE', 'PROLOG_MIGRATE_SUSPEND',
|
||||
'PROLOG_MIGRATE_SUSPEND_FAILURE', 'BOOT_UNDEPLOY_FAILURE',
|
||||
'BOOT_STOPPED_FAILURE', 'PROLOG_RESUME_FAILURE', 'PROLOG_UNDEPLOY_FAILURE',
|
||||
'DISK_SNAPSHOT_POWEROFF', 'DISK_SNAPSHOT_REVERT_POWEROFF',
|
||||
'DISK_SNAPSHOT_DELETE_POWEROFF', 'DISK_SNAPSHOT_SUSPENDED',
|
||||
'DISK_SNAPSHOT_REVERT_SUSPENDED', 'DISK_SNAPSHOT_DELETE_SUSPENDED',
|
||||
'DISK_SNAPSHOT', 'DISK_SNAPSHOT_REVERT', 'DISK_SNAPSHOT_DELETE']
|
||||
|
||||
SHORT_LCM_STATES = {
|
||||
'LCM_INIT': 'lcm_i',
|
||||
'PROLOG': 'prolo',
|
||||
'BOOT': 'boot',
|
||||
'RUNNING': 'running',
|
||||
'MIGRATE': 'migrate',
|
||||
'SAVE_STOP': 'save_stop',
|
||||
'SAVE_SUSPEND': 'save_suspend',
|
||||
'SAVE_MIGRATE': 'save_mig',
|
||||
'PROLOG_MIGRATE': 'prolo',
|
||||
'PROLOG_RESUME': 'prolo',
|
||||
'EPILOG_STOP': 'epilo',
|
||||
'EPILOG': 'epilo',
|
||||
'SHUTDOWN': 'shutd',
|
||||
'CANCEL': 'cance',
|
||||
'FAILURE': 'failu',
|
||||
'CLEANUP_RESUBMIT': 'clean',
|
||||
'UNKNOWN': 'unkno',
|
||||
'HOTPLUG': 'hotpl',
|
||||
'SHUTDOWN_POWEROFF': 'shutd',
|
||||
'BOOT_UNKNOWN': ':boot_u',
|
||||
'BOOT_POWEROFF': 'boot_p',
|
||||
'BOOT_SUSPENDED': 'boot_su',
|
||||
'BOOT_STOPPED': 'boot_st',
|
||||
'CLEANUP_DELETE': 'clean',
|
||||
'HOTPLUG_SNAPSHOT': 'hotp_sn',
|
||||
'HOTPLUG_NIC': 'hotp_n',
|
||||
'HOTPLUG_SAVEAS': 'hot_sav',
|
||||
'HOTPLUG_SAVEAS_POWEROFF': 'hot_sav_p',
|
||||
'HOTPLUG_SAVEAS_SUSPENDED': 'hot_sav_sus',
|
||||
'SHUTDOWN_UNDEPLOY': 'shut_un',
|
||||
'EPILOG_UNDEPLOY': 'epi_und',
|
||||
'PROLOG_UNDEPLOY': 'pro_und',
|
||||
'BOOT_UNDEPLOY': 'boot_und',
|
||||
'HOTPLUG_PROLOG_POWEROFF': 'hot_pro_pow',
|
||||
'HOTPLUG_EPILOG_POWEROFF': 'hot_epi_pow',
|
||||
'BOOT_MIGRATE': 'boot_mig',
|
||||
'BOOT_FAILURE': 'boot_fail',
|
||||
'BOOT_MIGRATE_FAILURE': 'boot_mig_fail',
|
||||
'PROLOG_MIGRATE_FAILURE': 'pro_mig_fail',
|
||||
'PROLOG_FAILURE': 'prolog_fail',
|
||||
'EPILOG_FAILURE': 'epilog_fail',
|
||||
'EPILOG_STOP_FAILURE': 'epilog_stop_fail',
|
||||
'EPILOG_UNDEPLOY_FAILURE': 'epilog_undep_fail',
|
||||
'PROLOG_MIGRATE_POWEROFF': 'prolog_migrate_power',
|
||||
'PROLOG_MIGRATE_POWEROFF_FAILURE': 'prolog_migrate_power_fail',
|
||||
'PROLOG_MIGRATE_SUSPEND': 'prolog_migrate_sus',
|
||||
'PROLOG_MIGRATE_SUSPEND_FAILURE': 'prolog_migrate_sus_fail',
|
||||
'BOOT_UNDEPLOY_FAILURE': 'boot_und_fail',
|
||||
'BOOT_STOPPED_FAILURE': 'boot_stop_fail',
|
||||
'PROLOG_RESUME_FAILURE': 'prolog_resume_fail',
|
||||
'PROLOG_UNDEPLOY_FAILURE': 'prolog_unde_fail',
|
||||
'DISK_SNAPSHOT_POWEROFF': 'disk_snap_poweroff',
|
||||
'DISK_SNAPSHOT_REVERT_POWEROFF': 'disk_snap_rever_poweroff',
|
||||
'DISK_SNAPSHOT_DELETE_POWEROFF': 'disk_snap_delete_poweroff',
|
||||
'DISK_SNAPSHOT_SUSPENDED': 'disk_snap_suspend',
|
||||
'DISK_SNAPSHOT_REVERT_SUSPENDED': 'disk_snap_revert_suspended',
|
||||
'DISK_SNAPSHOT_DELETE_SUSPENDED': 'disk_snap_del_suspend',
|
||||
'DISK_SNAPSHOT': 'disk_snap',
|
||||
'DISK_SNAPSHOT_REVERT': 'disk_snap_revert',
|
||||
'DISK_SNAPSHOT_DELETE': 'disk_snap_delete',
|
||||
}
|
||||
|
||||
MIGRATE_REASON = ['NONE', 'ERROR', 'STOP_RESUME', 'USER', 'CANCEL']
|
||||
|
||||
SHORT_MIGRATE_REASON = {
|
||||
'NONE': 'none',
|
||||
'ERROR': 'erro',
|
||||
'STOP_RESUME': 'stop',
|
||||
'USER': 'user',
|
||||
'CANCEL': 'canc'
|
||||
}
|
||||
|
||||
XML_TYPES = {
|
||||
'id': int,
|
||||
'uid': int,
|
||||
'gid': int,
|
||||
'uname': extractString,
|
||||
'gname': extractString,
|
||||
'name': extractString,
|
||||
# 'permissions': ???,
|
||||
# 'last_poll': int,
|
||||
'state': int,
|
||||
'lcm_state': int,
|
||||
'resched': int,
|
||||
'stime': int,
|
||||
'etime': int,
|
||||
'deploy_id': extractString,
|
||||
'template': ['TEMPLATE', Template, ['NIC', 'DISK']],
|
||||
'user_template': ['USER_TEMPLATE', Template],
|
||||
'history_records': ['HISTORY_RECORDS', lambda x: [History(i)
|
||||
for i in x] if x is not None else []],
|
||||
}
|
||||
|
||||
ELEMENT_NAME = 'VM'
|
||||
|
||||
@staticmethod
|
||||
def allocate(client, template):
|
||||
"""
|
||||
allocates a virtual machine description from the given template string
|
||||
|
||||
Arguments
|
||||
|
||||
``template``
|
||||
a string containing the template of the vm
|
||||
"""
|
||||
vm_id = client.call(VirtualMachine.METHODS['allocate'], template)
|
||||
return vm_id
|
||||
|
||||
def __init__(self, xml, client):
|
||||
super(VirtualMachine, self).__init__(xml, client)
|
||||
self.id = self['ID'] if self['ID'] else None
|
||||
|
||||
def deploy(self, host_id):
|
||||
"""
|
||||
initiates the instance of the given vmid on the target host
|
||||
|
||||
Arguments
|
||||
|
||||
``host_id``
|
||||
the host id (hid) of the target host where the VM will be
|
||||
instantiated.
|
||||
"""
|
||||
self.client.call(self.METHODS['deploy'], self.id, host_id)
|
||||
|
||||
def migrate(self, dest_host):
|
||||
"""
|
||||
migrates virtual machine to the target host
|
||||
|
||||
Arguments
|
||||
|
||||
``dest_host``
|
||||
the target host id
|
||||
"""
|
||||
self.client.call(self.METHODS['migrate'], self.id, dest_host, False)
|
||||
|
||||
def live_migrate(self, dest_host):
|
||||
"""
|
||||
live migrates virtual machine to the target host
|
||||
|
||||
Arguments
|
||||
|
||||
``dest_host``
|
||||
the target host id
|
||||
"""
|
||||
self.client.call(self.METHODS['migrate'], self.id, dest_host, True)
|
||||
|
||||
def save_disk(self, disk_id, dest_disk):
|
||||
"""
|
||||
Sets the disk to be saved in the given image
|
||||
|
||||
Arguments
|
||||
|
||||
``disk_id``
|
||||
disk id of the disk we want to save
|
||||
``dest_disk``
|
||||
image id where the disk will be saved.
|
||||
"""
|
||||
self.client.call(self.METHODS['savedisk'], self.id, disk_id, dest_disk)
|
||||
|
||||
def shutdown(self):
|
||||
"""
|
||||
Shutdowns an already deployed VM
|
||||
"""
|
||||
self._action('shutdown')
|
||||
|
||||
def shutdown_hard(self):
|
||||
"""
|
||||
Shutdown hard an already deployed VM
|
||||
"""
|
||||
self._action('shutdown-hard')
|
||||
|
||||
def poweroff(self):
|
||||
"""
|
||||
Power off an running vm
|
||||
"""
|
||||
self._action('poweroff')
|
||||
|
||||
def poweroff_hard(self):
|
||||
"""
|
||||
Power off hard an running vm
|
||||
"""
|
||||
self._action('poweroff-hard')
|
||||
|
||||
def cancel(self):
|
||||
"""
|
||||
Cancels a running VM
|
||||
"""
|
||||
self._action('cancel')
|
||||
|
||||
def hold(self):
|
||||
"""
|
||||
Sets a VM to hold state, scheduler will not deploy it
|
||||
"""
|
||||
self._action('hold')
|
||||
|
||||
def release(self):
|
||||
"""
|
||||
Releases a VM from hold state
|
||||
"""
|
||||
self._action('release')
|
||||
|
||||
def stop(self):
|
||||
"""
|
||||
Stops a running VM
|
||||
"""
|
||||
self._action('stop')
|
||||
|
||||
def suspend(self):
|
||||
"""
|
||||
Saves a running VM
|
||||
"""
|
||||
self._action('suspend')
|
||||
|
||||
def resume(self):
|
||||
"""
|
||||
Resumes the execution of a saved VM
|
||||
"""
|
||||
self._action('resume')
|
||||
|
||||
def finalize(self):
|
||||
"""
|
||||
Deletes a VM from the pool and DB
|
||||
"""
|
||||
self._action('finalize')
|
||||
|
||||
def reboot(self, hard=False):
|
||||
"""
|
||||
Reboot the VM. Optionally perform a hard reboot
|
||||
"""
|
||||
self._action('reboot-hard' if hard else 'reboot')
|
||||
|
||||
def resubmit(self):
|
||||
"""
|
||||
Redeploy the VM.
|
||||
"""
|
||||
self._action('resubmit')
|
||||
|
||||
def delete(self):
|
||||
"""
|
||||
Delete the VM.
|
||||
"""
|
||||
self._action('delete')
|
||||
|
||||
def resched(self):
|
||||
"""
|
||||
Set the rescheduling flag of the VM.
|
||||
"""
|
||||
self._action('resched')
|
||||
|
||||
def unresched(self):
|
||||
"""
|
||||
Remove the rescheduling flag of the VM.
|
||||
"""
|
||||
self._action('unresched')
|
||||
|
||||
def _action(self, action):
|
||||
self.client.call(self.METHODS['action'], action, self.id)
|
||||
|
||||
def __repr__(self):
|
||||
return '<oca.VirtualMachine("%s")>' % self.name
|
||||
|
||||
@property
|
||||
def str_state(self):
|
||||
"""
|
||||
String representation of virtual machine state.
|
||||
One of: INIT, PENDING, HOLD, ACTIVE, STOPPED, SUSPENDED,
|
||||
DONE, FAILED, POWEROFF, UNDEPLOYED
|
||||
"""
|
||||
return self.VM_STATE[int(self.state)]
|
||||
|
||||
@property
|
||||
def short_state(self):
|
||||
"""
|
||||
Short string representation of virtual machine state.
|
||||
One of: init, pend, hold, actv, stop, susp, done, fail, poff, udep
|
||||
"""
|
||||
return self.SHORT_VM_STATES[self.str_state]
|
||||
|
||||
@property
|
||||
def str_lcm_state(self):
|
||||
"""
|
||||
String representation of virtual machine LCM state.
|
||||
One of: LCM_INIT, PROLOG, BOOT, RUNNING, MIGRATE,
|
||||
SAVE_STOP, SAVE_SUSPEND, SAVE_MIGRATE, PROLOG_MIGRATE,
|
||||
PROLOG_RESUME, EPILOG_STOP, EPILOG, SHUTDOWN, CANCEL,
|
||||
FAILURE, DELETE, UNKNOWN and others. See:
|
||||
http://docs.opennebula.org/4.14/integration/system_interfaces/api.html#schemas-for-virtual-machine
|
||||
"""
|
||||
return self.LCM_STATE[int(self.lcm_state)]
|
||||
|
||||
@property
|
||||
def short_lcm_state(self):
|
||||
"""
|
||||
Short string representation of virtual machine LCM state.
|
||||
One of: init, prol, boot, runn, migr, save, save,
|
||||
save, migr, prol, epil, shut, shut, fail,
|
||||
dele, unkn
|
||||
"""
|
||||
return self.SHORT_LCM_STATES[self.str_lcm_state]
|
||||
|
||||
def update(self, template, merge=False):
|
||||
"""
|
||||
Update the template of this host. If merge is false (default),
|
||||
the existing template is replaced.
|
||||
"""
|
||||
self.client.call(self.METHODS['update'], self.id, template, 1 if merge else 0)
|
||||
|
||||
|
||||
class VirtualMachinePool(Pool):
|
||||
METHODS = {
|
||||
'info': 'vmpool.info',
|
||||
'infoextended': 'vmpool.infoextended',
|
||||
}
|
||||
|
||||
def __init__(self, client):
|
||||
super(VirtualMachinePool, self).__init__('VM_POOL', 'VM', client)
|
||||
|
||||
def _factory(self, xml):
|
||||
vm = VirtualMachine(xml, self.client)
|
||||
vm._convert_types()
|
||||
return vm
|
||||
|
||||
def info(self, filter=-3, range_start=-1, range_end=-1, vm_state=-1):
|
||||
"""
|
||||
Retrives/Refreshes virtual machine pool information
|
||||
|
||||
``filter``
|
||||
Filter flag. By defaults retrives only connected user reources.
|
||||
|
||||
``range_start``
|
||||
Range start ID. -1 for all
|
||||
|
||||
``range_end``
|
||||
Range end ID. -1 for all
|
||||
|
||||
``vm_state``
|
||||
|
||||
VM state to filter by.
|
||||
|
||||
* \-2 Any state, including DONE
|
||||
* \-1 Any state, except DONE (Defualt)
|
||||
* 0 INIT
|
||||
* 1 PENDING
|
||||
* 2 HOLD
|
||||
* 3 ACTIVE
|
||||
* 4 STOPPED
|
||||
* 5 SUSPENDED
|
||||
* 6 DONE
|
||||
* 7 FAILED
|
||||
* 8 POWEROFF
|
||||
* 9 UNDEPLYED
|
||||
|
||||
"""
|
||||
super(VirtualMachinePool, self).info(filter, range_start,
|
||||
range_end, vm_state)
|
||||
|
||||
def infoextended(self, filter=-3, range_start=-1, range_end=-1,
|
||||
vm_state =-2, filter_key_value_str=''):
|
||||
"""
|
||||
Retrives/Refreshes extended resource pool information
|
||||
|
||||
Note: Opennebula 5.8 curtailed the amount of info that can be obtained
|
||||
via `one.vmpool.info`. The detailed info of a VM is now available via
|
||||
`one.vmpool.infoextended` xml-rpc call.
|
||||
|
||||
http://docs.opennebula.org/5.8/intro_release_notes/release_notes/compatibility.html#xmlrpc-api-changes
|
||||
https://github.com/OpenNebula/one/issues/3076
|
||||
|
||||
``filter``
|
||||
Filter flag. By defaults retrieves only connected user resources.
|
||||
|
||||
``range_start``
|
||||
Range start ID. -1 for all
|
||||
|
||||
``range_end``
|
||||
Range end ID. -1 for all
|
||||
|
||||
``filter_key_value_str``
|
||||
String that needs to be searched for in the vmpool. Default search
|
||||
everything
|
||||
e.g.: ID=3023
|
||||
"""
|
||||
self[:] = []
|
||||
data = self.client.call(
|
||||
self.METHODS['infoextended'], filter, range_start, range_end,
|
||||
vm_state, filter_key_value_str
|
||||
)
|
||||
self._initialize_xml(data, self.pool_name)
|
||||
for element in self.xml.findall(self.element_name):
|
||||
self.append(self._factory(element))
|
|
@ -0,0 +1,173 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
from .pool import XMLElement, Pool, PoolElement, Template, extractString
|
||||
|
||||
|
||||
class Lease(XMLElement):
|
||||
XML_TYPES = {
|
||||
'ip': str,
|
||||
'mac': str,
|
||||
}
|
||||
|
||||
def __init__(self, xml):
|
||||
super(Lease, self).__init__(xml)
|
||||
self._convert_types()
|
||||
|
||||
|
||||
class LeasesList(list):
|
||||
def __init__(self, xml):
|
||||
if xml is None:
|
||||
return
|
||||
self.xml = xml
|
||||
for element in self.xml:
|
||||
self.append(self._factory(element))
|
||||
|
||||
def _factory(self, xml):
|
||||
v = Lease(xml)
|
||||
v._convert_types()
|
||||
return v
|
||||
|
||||
|
||||
class AddressRange(XMLElement):
|
||||
XML_TYPES = {
|
||||
'id': ["AR_ID", lambda xml: int(xml.text)],
|
||||
'size': int,
|
||||
'leases': ['LEASES', LeasesList],
|
||||
# 'template' : ['TEMPLATE', Template],
|
||||
}
|
||||
|
||||
def __init__(self, xml):
|
||||
super(AddressRange, self).__init__(xml)
|
||||
self._convert_types()
|
||||
self.id = self['AR_ID'] if self['AR_ID'] else None
|
||||
|
||||
|
||||
class AddressRangeList(list):
|
||||
def __init__(self, xml):
|
||||
self.xml = xml
|
||||
for element in self.xml:
|
||||
self.append(self._factory(element))
|
||||
|
||||
def _factory(self, xml):
|
||||
v = AddressRange(xml)
|
||||
v._convert_types()
|
||||
return v
|
||||
|
||||
|
||||
class VirtualNetwork(PoolElement):
|
||||
METHODS = {
|
||||
'info': 'vn.info',
|
||||
'allocate': 'vn.allocate',
|
||||
'delete': 'vn.delete',
|
||||
'publish': 'vn.publish',
|
||||
'chown': 'vn.chown',
|
||||
'hold': 'vn.hold',
|
||||
'release': 'vn.release',
|
||||
}
|
||||
|
||||
XML_TYPES = {
|
||||
'id': int,
|
||||
'uid': int,
|
||||
'gid': int,
|
||||
'uname': str,
|
||||
'gname': str,
|
||||
'name': str,
|
||||
# 'type' : int,
|
||||
'bridge': str,
|
||||
# 'public' : bool,
|
||||
'used_leases': int,
|
||||
'template': ['TEMPLATE', Template],
|
||||
'address_ranges': ['AR_POOL', AddressRangeList],
|
||||
}
|
||||
|
||||
ELEMENT_NAME = 'VNET'
|
||||
|
||||
@staticmethod
|
||||
def allocate(client, template):
|
||||
"""
|
||||
allocates a new virtual network in OpenNebula
|
||||
|
||||
Arguments
|
||||
|
||||
``template``
|
||||
a string containing the template of the virtual network
|
||||
"""
|
||||
vn_id = client.call(VirtualNetwork.METHODS['allocate'], template)
|
||||
return vn_id
|
||||
|
||||
def __init__(self, xml, client):
|
||||
# add 'vn_mad' attribute in OpenNebula >= 5
|
||||
xml_types = VirtualNetwork.XML_TYPES
|
||||
if client.one_version is None:
|
||||
client.version()
|
||||
if client.one_version >= '5' and 'vn_mad' not in xml_types:
|
||||
xml_types['vn_mad'] = extractString
|
||||
|
||||
super(VirtualNetwork, self).__init__(xml, client)
|
||||
self.id = self['ID'] if self['ID'] else None
|
||||
|
||||
def publish(self):
|
||||
"""
|
||||
Publishes a virtual network.
|
||||
"""
|
||||
self.client.call(self.METHODS['publish'], self.id, True)
|
||||
|
||||
def unpublish(self):
|
||||
"""
|
||||
Unpublishes a virtual network.
|
||||
"""
|
||||
self.client.call(self.METHODS['publish'], self.id, False)
|
||||
|
||||
def chown(self, uid, gid):
|
||||
"""
|
||||
Changes the owner/group
|
||||
|
||||
Arguments
|
||||
|
||||
``uid``
|
||||
New owner id. Set to -1 to leave current value
|
||||
``gid``
|
||||
New group id. Set to -1 to leave current value
|
||||
"""
|
||||
self.client.call(self.METHODS['chown'], self.id, uid, gid)
|
||||
|
||||
def release(self, ip):
|
||||
"""
|
||||
Releases given IP
|
||||
|
||||
Arguments
|
||||
|
||||
``ip``
|
||||
IP to realse
|
||||
"""
|
||||
self.client.call(self.METHODS['release'], self.id, 'LEASES=[IP={}]'.format(ip))
|
||||
|
||||
def hold(self, ip):
|
||||
"""
|
||||
Holds given IP
|
||||
|
||||
Arguments
|
||||
|
||||
``ip``
|
||||
IP to hold
|
||||
"""
|
||||
self.client.call(self.METHODS['hold'], self.id, 'LEASES=[IP={}]'.format(ip))
|
||||
|
||||
def __repr__(self):
|
||||
return '<oca.VirtualNetwork("%s")>' % self.name
|
||||
|
||||
|
||||
class VirtualNetworkPool(Pool):
|
||||
METHODS = {
|
||||
'info': 'vnpool.info',
|
||||
}
|
||||
|
||||
def __init__(self, client, preload_info=False):
|
||||
self.preload_info = preload_info
|
||||
super(VirtualNetworkPool, self).__init__('VNET_POOL', 'VNET', client)
|
||||
|
||||
def _factory(self, xml):
|
||||
v = VirtualNetwork(xml, self.client)
|
||||
v._convert_types()
|
||||
if self.preload_info:
|
||||
v.info()
|
||||
return v
|
|
@ -0,0 +1,42 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
from setuptools import setup
|
||||
import setuptools
|
||||
import os
|
||||
import sys
|
||||
|
||||
__version__ = '4.15.0a1'
|
||||
|
||||
|
||||
# borrowed from Pylons project
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
try:
|
||||
README = open(os.path.join(here, 'README.rst')).read()
|
||||
CHANGES = open(os.path.join(here, 'CHANGES.txt')).read()
|
||||
except IOError:
|
||||
README = CHANGES = ''
|
||||
|
||||
EXTRAS_REQUIRE = {}
|
||||
INSTALL_REQUIRES = []
|
||||
|
||||
if int(setuptools.__version__.split(".", 1)[0]) < 18:
|
||||
if sys.version_info[0:2] < (3, 0):
|
||||
INSTALL_REQUIRES.append("future")
|
||||
else:
|
||||
EXTRAS_REQUIRE[":python_version<'3.0'"] = ['future']
|
||||
|
||||
setup(name='oca',
|
||||
version=__version__,
|
||||
description='Python Bindings for XMLRPC OpenNebula Cloud API',
|
||||
long_description=README + '\n\n' + CHANGES,
|
||||
test_suite='nose.collector',
|
||||
classifiers=['Development Status :: 3 - Alpha',
|
||||
'License :: OSI Approved :: Apache Software License',
|
||||
'License :: OSI Approved :: Apache Software License',
|
||||
'Operating System :: OS Independent'],
|
||||
keywords='opennebula cloud xmlrpc',
|
||||
author=u'Łukasz Oleś, Matthias Schmitz, Michael Schmidt',
|
||||
url='https://github.com/python-oca/python-oca',
|
||||
license='Apache License 2.0',
|
||||
extras_require=EXTRAS_REQUIRE,
|
||||
install_requires=INSTALL_REQUIRES,
|
||||
packages=['oca'])
|
|
@ -0,0 +1,30 @@
|
|||
[tox]
|
||||
envlist = py27-v4.{8,10,12,14}
|
||||
|
||||
[testenv]
|
||||
deps=nose
|
||||
mock
|
||||
coverage
|
||||
commands=nosetests
|
||||
passenv = OCA_INT_TESTS_ONE_AUTH
|
||||
|
||||
[testenv:py27-v4.8]
|
||||
setenv =
|
||||
OCA_INT_TESTS=4.8
|
||||
OCA_INT_TESTS_ONE_XMLRPC=http://192.168.122.204:2633/RPC2
|
||||
|
||||
[testenv:py27-v4.10]
|
||||
setenv =
|
||||
OCA_INT_TESTS=4.10
|
||||
OCA_INT_TESTS_ONE_XMLRPC=http://192.168.122.41:2633/RPC2
|
||||
|
||||
[testenv:py27-v4.12]
|
||||
setenv =
|
||||
OCA_INT_TESTS=4.12
|
||||
OCA_INT_TESTS_ONE_XMLRPC=http://192.168.122.197:2633/RPC2
|
||||
|
||||
[testenv:py27-v4.14]
|
||||
setenv =
|
||||
OCA_INT_TESTS=4.14
|
||||
OCA_INT_TESTS_ONE_XMLRPC=http://192.168.122.10:2633/RPC2
|
||||
|
Loading…
Reference in New Issue