Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
snf-ganeti
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
itminedu
snf-ganeti
Commits
4cbd4462
Commit
4cbd4462
authored
Jul 11, 2008
by
Oleksiy Mishchenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Copy the rest of the Restful-API files to trunk
Reviewed-by: imsnah
parent
df4c2628
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
336 additions
and
1 deletion
+336
-1
Makefile.am
Makefile.am
+11
-1
doc/build-rapi-resources-doc
doc/build-rapi-resources-doc
+87
-0
doc/rapi.sgml
doc/rapi.sgml
+94
-0
test/ganeti.rapi.resources_unittest.py
test/ganeti.rapi.resources_unittest.py
+144
-0
No files found.
Makefile.am
View file @
4cbd4462
...
...
@@ -99,6 +99,7 @@ docsgml = \
doc/hooks.sgml
\
doc/install.sgml
\
doc/admin.sgml
\
doc/rapi.sgml
\
doc/iallocator.sgml
doc_DATA
=
\
...
...
@@ -131,6 +132,7 @@ EXTRA_DIST = \
autotools/docbook-wrapper
\
devel/upload.in
\
$(docsgml)
\
doc/build-rapi-resources-doc
\
doc/examples/ganeti.initd.in
\
doc/examples/ganeti.cron.in
\
doc/examples/dumb-allocator
\
...
...
@@ -186,6 +188,7 @@ dist_TESTS = \
test
/ganeti.locking_unittest.py
\
test
/ganeti.serializer_unittest.py
\
test
/ganeti.workerpool_unittest.py
\
test
/ganeti.rapi.resources_unittest.py
\
test
/ganeti.constants_unittest.py
nodist_TESTS
=
...
...
@@ -218,6 +221,13 @@ doc/%.pdf: doc/%.in $(DOCBOOK_WRAPPER)
doc/%.html
:
doc/%.in $(DOCBOOK_WRAPPER)
$(DOCBOOK_WRAPPER)
$<
$@
doc/rapi.pdf doc/rapi.html
:
doc/rapi-resources.sgml
doc/rapi-resources.sgml
:
doc/build-rapi-resources-doc lib/rapi/resources.py
PYTHONPATH
=
.:
$(top_builddir)
$<
>
$@
||
rm
-f
$@
.INTERMEDIATE
:
doc/rapi-resources.sgml
man/%.7
:
man/%.in man/footer.sgml $(DOCBOOK_WRAPPER)
$(DOCBOOK_WRAPPER)
$<
$@
...
...
@@ -226,7 +236,7 @@ man/%.8: man/%.in man/footer.sgml $(DOCBOOK_WRAPPER)
man/footer.sgml $(TESTS)
:
srclinks
$(TESTS)
:
ganeti
$(TESTS)
doc/build-rapi-resources-doc
:
ganeti lib/_autoconf.py
lib/_autoconf.py
:
Makefile stamp-directories
set
-e
;
\
...
...
doc/build-rapi-resources-doc
0 → 100755
View file @
4cbd4462
#!/usr/bin/python
#
# Copyright (C) 2008 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
"""Script to generate documentation for remote API resources.
"""
import
re
import
cgi
import
inspect
from
ganeti.rapi
import
resources
CHECKED_COMMANDS
=
[
"GET"
,
"POST"
,
"PUT"
,
"DELETE"
]
def
main
():
# Get list of all resources
all
=
list
(
resources
.
_CONNECTOR
.
itervalues
())
# Sort resources by URI
all
.
sort
(
cmp
=
lambda
a
,
b
:
cmp
(
a
.
DOC_URI
,
b
.
DOC_URI
))
print
"<!-- Automatically generated, do not edit -->"
for
cls
in
all
:
print
"<sect2>"
print
"<title>%s</title>"
%
cgi
.
escape
(
cls
.
DOC_URI
)
# Class docstring
description
=
inspect
.
getdoc
(
cls
)
if
description
:
print
(
"<literallayout>%s</literallayout>"
%
cgi
.
escape
(
description
.
strip
()))
print
'<informaltable><tgroup cols="2">'
print
'<colspec colwidth="1*">'
print
'<colspec colwidth="5*">'
print
"<thead>"
print
" <row>"
print
" <entry>Method</entry>"
print
" <entry>Description</entry>"
print
" </row>"
print
"</thead>"
print
'<tbody valign="top">'
for
cmd
in
CHECKED_COMMANDS
:
if
not
hasattr
(
cls
,
cmd
):
continue
# Get docstring
text
=
inspect
.
getdoc
(
getattr
(
cls
,
cmd
))
if
not
text
:
text
=
""
print
"<row>"
print
" <entry>%s</entry>"
%
cgi
.
escape
(
cmd
)
print
(
" <entry><literallayout>%s</literallayout></entry>"
%
cgi
.
escape
(
text
.
strip
()))
print
"</row>"
print
"</tbody>"
print
"</tgroup></informaltable>"
print
"</sect2>"
if
__name__
==
"__main__"
:
main
()
doc/rapi.sgml
0 → 100644
View file @
4cbd4462
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.2//EN" [
<!ENTITY JsonLink "http://www.json.org/">
<!ENTITY WikipediaRESTLink
"http://en.wikipedia.org/wiki/Representational_State_Transfer">
<!ENTITY IncludeResources SYSTEM "doc/rapi-resources.sgml">
]>
<article
class=
"specification"
>
<articleinfo>
<title>
Ganeti remote API
</title>
</articleinfo>
<para>
Documents Ganeti version 1.2
</para>
<sect1>
<title>
Introduction
</title>
<para>
Ganeti supports a remote API for enable external tools to easily
retrieve information about a cluster's state. The remote API daemon,
<computeroutput>
ganeti-rapi
</computeroutput>
, is automatically started on
the master node if the
<computeroutput>
--enable-rapi
</computeroutput>
parameter is passed to the
<computeroutput>
configure
</computeroutput>
script. Alternatively you can start it manually. By default it runs on TCP
port 5080, but this can be changed either in
<filename>
…
/constants.py
</filename>
or via the command line
parameter
<computeroutput>
-p
</computeroutput>
. SSL support can also be
enabled by passing command line parameters.
</para>
<note>
<para>
Ganeti 1.2 only supports a limited set of calls, all of them
read-only. The next major version will have support for write
operations.
</para>
</note>
</sect1>
<sect1>
<title>
Protocol
</title>
<para>
The protocol used is
<ulink
url=
"&JsonLink;"
>
JSON
</ulink>
over HTTP
designed after the
<ulink
url=
"&WikipediaRESTLink;"
>
REST
</ulink>
principle.
</para>
</sect1>
<sect1>
<title>
Usage examples
</title>
<para>
You can access the API using your favorite programming language as long
as it supports network connections.
</para>
<sect2>
<title>
Shell
</title>
<screen>
wget -q -O - http://
<replaceable>
CLUSTERNAME
</replaceable>
:5080/info
</screen>
</sect2>
<sect2>
<title>
Python
</title>
<screen>
import urllib2
f = urllib2.urlopen('http://
<replaceable>
CLUSTERNAME
</replaceable>
:5080/info')
print f.read()
</screen>
</sect2>
<sect2>
<title>
JavaScript
</title>
<note>
<para>
While it's possible to use JavaScript, it poses several potential
problems, including browser blocking request due to non-standard ports
or different domain names. Fetching the data on the webserver is
easier.
</para>
</note>
<screen>
var url = 'http://
<replaceable>
CLUSTERNAME
</replaceable>
:5080/info';
var info;
var xmlreq = new XMLHttpRequest();
xmlreq.onreadystatechange = function () {
if (xmlreq.readyState != 4) return;
if (xmlreq.status == 200) {
info = eval("(" + xmlreq.responseText + ")");
alert(info);
} else {
alert('Error fetching cluster info');
}
xmlreq = null;
};
xmlreq.open('GET', url, true);
xmlreq.send(null);
</screen>
</sect2>
</sect1>
<sect1>
<title>
Resources
</title>
&IncludeResources;
</sect1>
</article>
test/ganeti.rapi.resources_unittest.py
0 → 100755
View file @
4cbd4462
#!/usr/bin/python
#
# Copyright (C) 2007, 2008 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
"""Script for unittesting the rapi.resources module"""
import
os
import
unittest
import
tempfile
import
time
from
ganeti
import
errors
from
ganeti.rapi
import
httperror
from
ganeti.rapi
import
resources
from
ganeti.rapi
import
RESTHTTPServer
class
MapperTests
(
unittest
.
TestCase
):
"""Tests for remote API URI mapper."""
def
setUp
(
self
):
self
.
map
=
resources
.
Mapper
()
def
_TestUri
(
self
,
uri
,
result
):
self
.
assertEquals
(
self
.
map
.
getController
(
uri
),
result
)
def
_TestFailingUri
(
self
,
uri
):
self
.
failUnlessRaises
(
httperror
.
HTTPNotFound
,
self
.
map
.
getController
,
uri
)
def
testMapper
(
self
):
"""Testing resources.Mapper"""
self
.
_TestUri
(
"/tags"
,
(
resources
.
R_tags
,
[],
{}))
self
.
_TestUri
(
'/instances/www.test.com'
,
(
resources
.
R_instances_name
,
[
'www.test.com'
],
{}))
self
.
_TestUri
(
'/instances/www.test.com/tags?f=5&f=6&alt=html'
,
(
resources
.
R_instances_name_tags
,
[
'www.test.com'
],
{
'alt'
:
[
'html'
],
'f'
:
[
'5'
,
'6'
],
}))
self
.
_TestFailingUri
(
"/tag"
)
self
.
_TestFailingUri
(
"/instances/does/not/exist"
)
class
R_RootTests
(
unittest
.
TestCase
):
"""Testing for R_root class."""
def
setUp
(
self
):
self
.
root
=
resources
.
R_root
(
None
,
None
,
None
)
def
testGet
(
self
):
expected
=
[
{
'name'
:
'info'
,
'uri'
:
'/info'
},
{
'name'
:
'instances'
,
'uri'
:
'/instances'
},
{
'name'
:
'nodes'
,
'uri'
:
'/nodes'
},
{
'name'
:
'os'
,
'uri'
:
'/os'
},
{
'name'
:
'tags'
,
'uri'
:
'/tags'
},
{
'name'
:
'version'
,
'uri'
:
'/version'
},
]
self
.
assertEquals
(
self
.
root
.
GET
(),
expected
)
class
HttpLogfileTests
(
unittest
.
TestCase
):
"""Rests for HttpLogfile class."""
class
FakeRequest
:
FAKE_ADDRESS
=
"1.2.3.4"
def
address_string
(
self
):
return
self
.
FAKE_ADDRESS
def
setUp
(
self
):
self
.
tmpfile
=
tempfile
.
NamedTemporaryFile
()
self
.
logfile
=
RESTHTTPServer
.
HttpLogfile
(
self
.
tmpfile
.
name
)
def
testFormatLogTime
(
self
):
self
.
_TestInTimezone
(
1208646123.0
,
"Europe/London"
,
"19/Apr/2008:23:02:03 +0000"
)
self
.
_TestInTimezone
(
1208646123
,
"Europe/Zurich"
,
"19/Apr/2008:23:02:03 +0000"
)
self
.
_TestInTimezone
(
1208646123
,
"Australia/Sydney"
,
"19/Apr/2008:23:02:03 +0000"
)
def
_TestInTimezone
(
self
,
seconds
,
timezone
,
expected
):
"""Tests HttpLogfile._FormatLogTime with a specific timezone
"""
# Preserve environment
old_TZ
=
os
.
environ
.
get
(
"TZ"
,
None
)
try
:
os
.
environ
[
"TZ"
]
=
timezone
time
.
tzset
()
result
=
self
.
logfile
.
_FormatLogTime
(
seconds
)
finally
:
# Restore environment
if
old_TZ
is
not
None
:
os
.
environ
[
"TZ"
]
=
old_TZ
elif
"TZ"
in
os
.
environ
:
del
os
.
environ
[
"TZ"
]
time
.
tzset
()
self
.
assertEqual
(
result
,
expected
)
def
testClose
(
self
):
self
.
logfile
.
Close
()
def
testCloseAndWrite
(
self
):
request
=
self
.
FakeRequest
()
self
.
logfile
.
Close
()
self
.
assertRaises
(
errors
.
ProgrammerError
,
self
.
logfile
.
LogRequest
,
request
,
"Message"
)
def
testLogRequest
(
self
):
request
=
self
.
FakeRequest
()
self
.
logfile
.
LogRequest
(
request
,
"This is only a %s"
,
"test"
)
self
.
logfile
.
Close
()
if
__name__
==
'__main__'
:
unittest
.
main
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment