[PATCH] Removing extra word from kimchi description
by Christy Perez
Signed-off-by: Christy Perez <christy(a)linux.vnet.ibm.com>
---
contrib/kimchi.spec.fedora.in | 2 +-
contrib/kimchi.spec.suse.in | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/contrib/kimchi.spec.fedora.in b/contrib/kimchi.spec.fedora.in
index 44654f0..558bda2 100644
--- a/contrib/kimchi.spec.fedora.in
+++ b/contrib/kimchi.spec.fedora.in
@@ -50,7 +50,7 @@ BuildRequires: systemd-units
%endif
%description
-Web server application application to manage KVM/Qemu virtual machines
+Web server application to manage KVM/Qemu virtual machines
%prep
diff --git a/contrib/kimchi.spec.suse.in b/contrib/kimchi.spec.suse.in
index 978f6a5..97e66bc 100644
--- a/contrib/kimchi.spec.suse.in
+++ b/contrib/kimchi.spec.suse.in
@@ -31,7 +31,7 @@ Requires: python-ordereddict
%endif
%description
-Web server application application to manage KVM/Qemu virtual machines
+Web server application to manage KVM/Qemu virtual machines
%prep
%setup
--
1.8.5.3
10 years, 10 months
Kimchi bugs reduction plan
by Shu Ming
Hi,
In summary, Kimchi community get 22 open bugs in total and 15 bugs are
left unassigned. Especially Bug 22) was assigned to aglitke that should
be reassigned to someone else.
Bug reduction plans proposed:
1) All the open bugs should be assigned by the end of this week
2) All the bugs should be triaged to "NEEDINFO", "BLOCK" or "NORMAL"
after the bugs are assigned by next Wednesday. In github, the bugs only
get open or closed state, but we can tag them into 'NEEDINFO", "BLOCK"
or "NORMAL" state.
BTW: block means the bug block Kimchi shipment on hardware and the
software function is severely damaged
3) New bugs should be triaged and assigned within 48 hours
4) All block bugs should be fixed as soon as possible and the status of
them should be updated in daily until closed
5) Normal bugs should also have a fixing plan by the bug assignee
Here are all the open bugs in Kimchi community:
https://github.com/kimchi-project/kimchi/issues?labels=bug&page=1&state=open
1) LVM VG is left when removing logical storage pool #312
2) Creating a guest OS whose name contain spaces causes it to fail #306
3) No storage pool type could be selected when creating new storage pool
#304
4) The password of iSCSI Authentication should be masked #303 Meina
5) Remote ISO Image: Template creation fails due to gentoo path #301 Meina
6) Inactive storage pools are listed while editing template #299 Dingxin
7) debug report: kimchi automaticly logout while generate debug report
#295 (Hongliang)
8) The auto logout leaves action menu on page #294
9) kimchi report not enough arguments for format string when get
/host/partitions #290
10) Firefox 24 ESR: Can't display template edit in 2 columns #284
11) ImportError: cannot import name BackgroundTask #269
12) Should not be allowed to remove "default" storagepool and network #265
13) globalization: host tab does not translate into Chinese #249 UI
14) kimchi will report error whe it start/stop/display a VM whose name
with "?" in it #243 (Hongliang)
15) VNC connect fails #239
16) Translation changes are not updated by "make" #200
17) Mishandling of unsupported storage pool types #195 lvroyce
18) can not create a VM from a template with disks['volume'] parameters.
#181
19) autogen warning and suggest on fedora 19 #130
20) UI noVNC: Can't show Chinese VM name correctly #88
21) Error while runing test suite #81
22) [BUG] VM can not start which created in Redhat by kimchi #77 aglitke
10 years, 10 months
[PATCH] Pep8 for mockmodel.py
by Adam King
---
src/kimchi/mockmodel.py | 76 +++++++++++++++++++++++++++----------------------
1 file changed, 42 insertions(+), 34 deletions(-)
diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py
index ece016e..04a0a56 100644
--- a/src/kimchi/mockmodel.py
+++ b/src/kimchi/mockmodel.py
@@ -17,8 +17,10 @@
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc.
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
import cherrypy
import copy
@@ -41,7 +43,6 @@ except ImportError:
import ImageDraw
-
from kimchi import config
from kimchi.asynctask import AsyncTask
from kimchi.config import config as kconfig
@@ -53,7 +54,8 @@ from kimchi.model.utils import get_vm_name
from kimchi.model.vms import VM_STATIC_UPDATE_PARAMS
from kimchi.objectstore import ObjectStore
from kimchi.screenshot import VMScreenshot
-from kimchi.utils import pool_name_from_uri, run_command, template_name_from_uri
+from kimchi.utils import pool_name_from_uri, run_command
+from kimchi.utils import template_name_from_uri
from kimchi.vmtemplate import VMTemplate
@@ -64,7 +66,8 @@ class MockModel(object):
self.distros = self._get_distros()
def capabilities_lookup(self, *ident):
- return {'libvirt_stream_protocols': ['http', 'https', 'ftp', 'ftps', 'tftp'],
+ return {'libvirt_stream_protocols':
+ ['http', 'https', 'ftp', 'ftps', 'tftp'],
'qemu_stream': True,
'screenshot': True,
'system_report_tool': True}
@@ -135,8 +138,7 @@ class MockModel(object):
def vms_create(self, params):
t_name = template_name_from_uri(params['template'])
- name = get_vm_name(params.get('name'), t_name,
- self._mock_vms.keys())
+ name = get_vm_name(params.get('name'), t_name, self._mock_vms.keys())
if name in self._mock_vms:
raise InvalidOperation("KCHVM0001E", {'name': name})
@@ -350,15 +352,16 @@ class MockModel(object):
pool.info['source'] = params['source']
if not pool.info['source'].get('adapter_name'):
raise MissingParameter('KCHPOOL0004E',
- {'item': 'adapter_name', 'name': name})
- for vol in ['unit:0:0:1','unit:0:0:2',
- 'unit:0:0:3','unit:0:0:4']:
+ {'item': 'adapter_name',
+ 'name': name})
+ for vol in ['unit:0:0:1', 'unit:0:0:2',
+ 'unit:0:0:3', 'unit:0:0:4']:
mockvol = MockStorageVolume(name, vol,
- dict([('type','lun')]))
+ dict([('type', 'lun')]))
pool._volumes[vol] = mockvol
else:
pool.info['path'] = params['path']
- if params['type'] in ['dir','scsi']:
+ if params['type'] in ['dir', 'scsi']:
pool.info['autostart'] = True
else:
pool.info['autostart'] = False
@@ -436,7 +439,7 @@ class MockModel(object):
def storagevolume_lookup(self, pool, name):
if self._get_storagepool(pool).info['state'] != 'active':
raise InvalidOperation("KCHVOL0005E", {'pool': pool,
- 'volume': name})
+ 'volume': name})
storagevolume = self._get_storagevolume(pool, name)
return storagevolume.info
@@ -461,7 +464,7 @@ class MockModel(object):
return res._volumes.keys()
def devices_get_list(self, _cap=None):
- return ['scsi_host3', 'scsi_host4','scsi_host5']
+ return ['scsi_host3', 'scsi_host4', 'scsi_host5']
def device_lookup(self, nodedev_name):
return {
@@ -493,7 +496,7 @@ class MockModel(object):
return iso_volumes
def storageservers_get_list(self, _target_type=None):
- # FIXME: When added new storage server support, this needs to be updated
+ # FIXME: This needs to be updted when adding new storage server support
target_type = STORAGE_SOURCES.keys() \
if not _target_type else [_target_type]
pools = self.storagepools_get_list()
@@ -514,10 +517,12 @@ class MockModel(object):
for pool in pools:
try:
pool_info = self.storagepool_lookup(pool)
- if pool_info['source'] and pool_info['source']['addr'] == server:
- return dict(host=server)
+ if pool_info['source'] and
+ pool_info['source']['addr'] == server:
+ return dict(host=server)
except NotFoundError:
- # Avoid inconsistent pool result because of lease between list and lookup
+ # Avoid inconsistent pool result because
+ # of lease between list and lookup
pass
raise NotFoundError("KCHSR0001E", {'server': server})
@@ -562,7 +567,7 @@ class MockModel(object):
try:
net = ipaddr.IPNetwork(subnet)
except ValueError:
- msg_args = {'subnet':subnet, 'network': name}
+ msg_args = {'subnet': subnet, 'network': name}
raise InvalidParameter("KCHNET0003E", msg_args)
network.info['dhcp'] = {
@@ -581,8 +586,8 @@ class MockModel(object):
def _get_vms_attach_to_a_network(self, network):
vms = []
for name, dom in self._mock_vms.iteritems():
- if network in dom.networks:
- vms.append(name)
+ if network in dom.networks:
+ vms.append(name)
return vms
def network_lookup(self, name):
@@ -650,7 +655,7 @@ class MockModel(object):
def vmifaces_create(self, vm, params):
if (params["type"] == "network" and
- params["network"] not in self.networks_get_list()):
+ params["network"] not in self.networks_get_list()):
msg_args = {'network': params["network"], 'name': vm}
raise InvalidParameter("KCHVMIF0002E", msg_args)
@@ -679,7 +684,7 @@ class MockModel(object):
def vmiface_delete(self, vm, mac):
dom = self._get_vm(vm)
try:
- del dom.ifaces[mac]
+ del dom.ifaces[mac]
except KeyError:
raise NotFoundError("KCHVMIF0001E", {'iface': mac, 'name': vm})
@@ -835,7 +840,7 @@ class MockModel(object):
raise OperationFailed("KCHREPOS0007E", {'repo_id': repo_id})
def repository_disable(self, repo_id):
- if not self._mock_host_repositories.disableRepository(repo_id):
+ if not self._mock_host_repositories.disableRepository(repo_id):
raise OperationFailed("KCHREPOS0008E", {'repo_id': repo_id})
def repository_update(self, repo_id, params):
@@ -895,7 +900,8 @@ class MockVMIface(object):
self.__class__.counter += 1
self.info = {'type': 'network',
'model': 'virtio',
- 'network': network if network else "net-%s" % self.counter,
+ 'network': network if network
+ else "net-%s" % self.counter,
'mac': self.get_mac()
}
@@ -915,17 +921,18 @@ class MockVM(object):
ifaces = [MockVMIface(net) for net in self.networks]
self.storagedevices = {}
self.ifaces = dict([(iface.info['mac'], iface) for iface in ifaces])
-
- stats = {'cpu_utilization': 20, 'net_throughput' : 35,
- 'net_throughput_peak': 100, 'io_throughput': 45,
- 'io_throughput_peak': 100}
+
+ stats = {'cpu_utilization': 20, 'net_throughput': 35,
+ 'net_throughput_peak': 100, 'io_throughput': 45,
+ 'io_throughput_peak': 100}
self.info = {'state': 'shutoff',
'stats': stats,
'uuid': self.uuid,
'memory': template_info['memory'],
'cpus': template_info['cpus'],
'icon': None,
- 'graphics': {'type': 'vnc', 'listen': '0.0.0.0', 'port': None}
+ 'graphics': {'type': 'vnc', 'listen': '0.0.0.0',
+ 'port': None}
}
self.info['graphics'].update(template_info['graphics'])
@@ -976,6 +983,7 @@ class MockTask(object):
def __init__(self, id):
self.id = id
+
class MockStorageVolume(object):
def __init__(self, pool, name, params={}):
self.name = name
@@ -985,9 +993,9 @@ class MockStorageVolume(object):
params = self._def_lun(name)
fmt = params.get('format', 'raw')
capacity = params.get('capacity', 1024)
- self.info = {'type': params.get('type','disk'),
+ self.info = {'type': params.get('type', 'disk'),
'capacity': capacity << 20,
- 'allocation': params.get('allocation','512'),
+ 'allocation': params.get('allocation', '512'),
'path': params.get('path'),
'format': fmt}
if fmt == 'iso':
@@ -1002,10 +1010,10 @@ class MockStorageVolume(object):
return {
"capacity": capacity,
"name": name,
- "format": random.choice(['dos','unknown']),
+ "format": random.choice(['dos', 'unknown']),
"allocation": capacity,
"path": path + name[-1],
- "type": "block" }
+ "type": "block"}
class MockVMScreenshot(VMScreenshot):
--
1.8.1.4
10 years, 10 months
[PATCH 0/5] Implement and use jQuery circleGauge on guests tab
by Adam King
This patch set improves the guest tab implementation by:
Implementing the circle gauge as a fully reusable jQuery widget
Using DOM updates to update the guests tab rather than string manipulation
Improving the usability of the guest livetile
Adam King (5):
Update VM (mock)model to produce valid JSON for /vms
Update tests to account for proper JSON being returned in vm stats.
Morphed the old circle implementation into a reusable jquery
circleGaude widget.
Update the guest.html.tmpl to use the new circleGauge widget
Update guests tab to update the VM List by DOM manipulation
src/kimchi/mockmodel.py | 8 +-
src/kimchi/model/vms.py | 2 +-
tests/test_mockmodel.py | 2 +-
tests/test_model.py | 2 +-
ui/css/theme-default/circle.css | 26 ---
ui/css/theme-default/circleGauge.css | 26 +++
ui/css/theme-default/list.css | 25 ++-
ui/js/src/kimchi.circle.js | 88 ---------
ui/js/src/kimchi.guest_main.js | 366 +++++++++++++++++++----------------
ui/js/widgets/circleGauge.js | 104 ++++++++++
ui/pages/guest.html.tmpl | 39 ++--
ui/pages/tabs/guests.html.tmpl | 2 +-
12 files changed, 386 insertions(+), 304 deletions(-)
delete mode 100644 ui/css/theme-default/circle.css
create mode 100644 ui/css/theme-default/circleGauge.css
delete mode 100644 ui/js/src/kimchi.circle.js
create mode 100644 ui/js/widgets/circleGauge.js
--
1.8.1.4
10 years, 10 months
[PATCH 0/4] Implement integrity verification: verify template integrity
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
Implement integrity verification: verify template integrity, update API.md
Sometimes, user create a template, but networks, cdrom, disks or
storagepool will change later.
So users can not create a vm from this template successfully.
It is necessary to check some paramenters of template.
ShaoHe Feng (4):
Implement integrity verification: verify template integrity, update
API.md
add a new method to get iso info for VMTemplate class
Implement integrity verification: verify template integrity in backend
Implement integrity verification: update test case
docs/API.md | 4 +++
src/kimchi/control/templates.py | 1 +
src/kimchi/mockmodel.py | 5 +++-
src/kimchi/model/templates.py | 8 ++++--
src/kimchi/vmtemplate.py | 54 ++++++++++++++++++++++++++++++++---------
tests/test_model.py | 33 +++++++++++++++++++++++++
tests/test_rest.py | 40 ++++++++++++++++++++++++++++++
7 files changed, 131 insertions(+), 14 deletions(-)
--
1.8.4.2
10 years, 10 months
[PATCH] add libxml2 to BuildRequires list
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
91bab78 import libxml2 when generate index.html during build time.
Need add libxml2 to BuildRequires list.
Signed-off-by: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
---
contrib/DEBIAN/control.in | 3 ++-
contrib/kimchi.spec.fedora.in | 3 ++-
contrib/kimchi.spec.suse.in | 3 ++-
3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/contrib/DEBIAN/control.in b/contrib/DEBIAN/control.in
index 0952490..1b03fc7 100644
--- a/contrib/DEBIAN/control.in
+++ b/contrib/DEBIAN/control.in
@@ -22,6 +22,7 @@ Depends: python-cherrypy3 (>= 3.2.0),
python-lxml,
open-iscsi,
firewalld
-Build-Depends: libxslt
+Build-Depends: libxslt,
+ python-libxml2
Maintainer: Aline Manera <alinefm(a)br.ibm.com>
Description: Kimchi web server
diff --git a/contrib/kimchi.spec.fedora.in b/contrib/kimchi.spec.fedora.in
index 0511527..44654f0 100644
--- a/contrib/kimchi.spec.fedora.in
+++ b/contrib/kimchi.spec.fedora.in
@@ -28,7 +28,8 @@ Requires: python-ipaddr
Requires: python-lxml
Requires: nfs-utils
Requires: iscsi-initiator-utils
-BuildRequires: libxslt
+BuildRequires: libxslt
+BuildRequires: libxml2-python
%if 0%{?rhel} == 6
Requires: python-ordereddict
diff --git a/contrib/kimchi.spec.suse.in b/contrib/kimchi.spec.suse.in
index cbb7b67..978f6a5 100644
--- a/contrib/kimchi.spec.suse.in
+++ b/contrib/kimchi.spec.suse.in
@@ -23,7 +23,8 @@ Requires: python-ipaddr
Requires: python-lxml
Requires: nfs-client
Requires: open-iscsi
-BuildRequires: libxslt-tools
+BuildRequires: libxslt-tools
+BuildRequires: python-libxml2
%if 0%{?sles_version} == 11
Requires: python-ordereddict
--
1.8.4.2
10 years, 10 months
[PATCH 0/6 V6] Host's repositories management support
by Paulo Vital
V5 -> V6:
* Updated AptRepo()
V4 -> V5:
* Updated test_rest.py
* Fixed wrong dict declaration on mockmodel.py
V3 -> V4:
* PEP8 compatibility
* Fixed bugs regarding exception error system code in mockmodel.py, model/host.py and repository.py
* Removed the "enabled" parameter from update_params' list.
V2 -> V3:
* PEP8 compatibility
* Improved mockmodel.py and model/host.py
* Updated API.json and backend files to use new exception error system code
V1 -> V2:
* Removed the enable/disable from docs/API.md and src/kimchi/API.json
* fixed wrong URI on test_rest.py
* PEP8 compatibility
* Updated repositories.py to make consistent with docs/API.md
* Raised correct exceptions
* Changed model/host.py and mockmodel.py to generate repo_id if not provided
* Changed mockmodel.py to declare MockRepositories class
V1:
This patch set provides support to host's repositories management operations.
At this point, an agnostic class is providing support to backend and
REST API operations. In addition, YUM (for RHEL, Fedora, SLES and OpenSuse)
and APT (for Debian and Ubuntu) specific classes are provided to support the
operation os each software update system.
To test the backend execute the following commands:
$ cd tests
$ sudo ./run_tests.sh test_model.ModelTests.test_repository_create
$ sudo ./run_tests.sh test_model.ModelTests.test_repository_update
$ sudo ./run_tests.sh test_model.ModelTests.test_repository_disable_enable
To test the REST API, execute the following commands (all them are agnostic of the
host's distro):
1) Get list of all repositories enabled in the host:
$ curl -u <USER> -H 'Content-type: application/json' -H 'Accept: application/json' http://localhost:8000/host/repositories/ -X GET
2) Create a new repository:
$ curl -u <USER> -H 'Content-type: application/json' -H 'Accept: application/json' http://localhost:8000/host/repositories/ -X POST -d'
{
"repo_id": "fedora-fake",
"baseurl": "http://www.fedora.org",
"gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-fake-19"
}
'
3) Get information from a specific repository:
$ curl -u <USER> -H 'Content-type: application/json' -H 'Accept: application/json' http://localhost:8000/host/repositories/fedora-fake
4) Update a specific repository:
$ curl -u <USER> -H 'Content-type: application/json' -H 'Accept: application/json' http://localhost:8000/host/repositories/fedora-fake -X PUT -d'
{
"repo_id":"fedora-fake",
"repo_name":"Fedora 19 FAKEs",
"baseurl": "http://www.fedora.org/downloads"
}
'
5) Disable a specific repository:
$ curl -u <USER> -H 'Content-type: application/json' -H 'Accept: application/json' http://localhost:8000/host/repositories/fedora-fake/disable -X POST -d ''
6) Enable a specific repository:
$ curl -u <USER> -H 'Content-type: application/json' -H 'Accept: application/json' http://localhost:8000/host/repositories/fedora-fake/enable -X POST -d ''
7) Delete a specific repository:
$ curl -u <USER> -H 'Content-type: application/json' -H 'Accept: application/json' http://localhost:8000/host/repositories/fedora-fake -X DELETE
Paulo Vital (6):
Host's repositories management: Update API.md
Host's repositories management: Update REST API
Host's repositories management: Update backend.
Host's repositories management: Update Makefile
Host's repositories management: Update test-cases.
Host's repositories management: Update error exception messages.
Makefile.am | 1 +
docs/API.md | 77 ++++++
src/kimchi/API.json | 72 ++++++
src/kimchi/Makefile.am | 1 +
src/kimchi/control/host.py | 21 ++
src/kimchi/i18n.py | 19 ++
src/kimchi/mockmodel.py | 135 ++++++++++
src/kimchi/model/host.py | 54 +++-
src/kimchi/repositories.py | 600 +++++++++++++++++++++++++++++++++++++++++++++
tests/test_model.py | 100 ++++++++
tests/test_rest.py | 38 +++
11 files changed, 1117 insertions(+), 1 deletion(-)
create mode 100644 src/kimchi/repositories.py
--
1.8.3.1
10 years, 10 months
[RFC V2 0/3] Implement integrity verification: verify template integrity
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
Implement integrity verification: verify template integrity, update API.md
Sometimes, user create a template, but networks, cdrom, disks or
storagepool will change later.
So users can not create a vm from this template successfully.
It is necessary to check some paramenters of template.
ShaoHe Feng (3):
Implement integrity verification: verify template integrity, update
API.md
Implement integrity verification: verify template integrity in backend
add a new method to get iso info for VMTemplate class
docs/API.md | 4 ++++
src/kimchi/control/templates.py | 1 +
src/kimchi/mockmodel.py | 2 +-
src/kimchi/model/templates.py | 32 +++++++++++++++++++++++++++++++-
src/kimchi/vmtemplate.py | 22 +++++++++++-----------
5 files changed, 48 insertions(+), 13 deletions(-)
--
1.8.4.2
10 years, 10 months
[PATCH] Block access for non-root users
by Aline Manera
From: Aline Manera <alinefm(a)br.ibm.com>
Non-root users must have restricted access to Kimchi.
This patch block non-root urser to:
- get or create debug reports;
- reboot or shutdown host system;
- create, activate/deactivate or delete networks;
- create, activate/deactivate or delete storage pools;
- update or delete templates;
- create, start/stop/connect or delete vms.
It also updates the tests cases to always run as a root user.
And add authorization tests to make sure non-root users have restricted
access to kimchi.
Signed-off-by: Aline Manera <alinefm(a)br.ibm.com>
---
src/kimchi/control/debugreports.py | 2 +-
src/kimchi/control/host.py | 2 +-
src/kimchi/control/networks.py | 2 +-
src/kimchi/control/storagepools.py | 2 +-
src/kimchi/control/templates.py | 2 +-
src/kimchi/control/vms.py | 2 +-
tests/Makefile.am | 1 +
tests/test_authorization.py | 124 ++++++++++++++++++++++++++++++++++++
tests/utils.py | 23 ++++++-
9 files changed, 153 insertions(+), 7 deletions(-)
create mode 100644 tests/test_authorization.py
diff --git a/src/kimchi/control/debugreports.py b/src/kimchi/control/debugreports.py
index 324d826..57dc0f3 100644
--- a/src/kimchi/control/debugreports.py
+++ b/src/kimchi/control/debugreports.py
@@ -26,7 +26,7 @@ from kimchi.control.utils import internal_redirect
from kimchi.control.utils import UrlSubNode
-@UrlSubNode("debugreports", True)
+@UrlSubNode("debugreports", True, ['GET', 'POST'])
class DebugReports(AsyncCollection):
def __init__(self, model):
super(DebugReports, self).__init__(model)
diff --git a/src/kimchi/control/host.py b/src/kimchi/control/host.py
index 0852bd0..41e0040 100644
--- a/src/kimchi/control/host.py
+++ b/src/kimchi/control/host.py
@@ -31,7 +31,7 @@ from kimchi.exception import OperationFailed
from kimchi.template import render
-@UrlSubNode("host", True)
+@UrlSubNode("host", True, ['POST'])
class Host(Resource):
def __init__(self, model, id=None):
super(Host, self).__init__(model, id)
diff --git a/src/kimchi/control/networks.py b/src/kimchi/control/networks.py
index 8510e49..3a02f60 100644
--- a/src/kimchi/control/networks.py
+++ b/src/kimchi/control/networks.py
@@ -25,7 +25,7 @@ from kimchi.control.base import Collection, Resource
from kimchi.control.utils import UrlSubNode
-@UrlSubNode("networks", True)
+@UrlSubNode("networks", True, ['POST', 'DELETE'])
class Networks(Collection):
def __init__(self, model):
super(Networks, self).__init__(model)
diff --git a/src/kimchi/control/storagepools.py b/src/kimchi/control/storagepools.py
index ea19609..7e6bdd7 100644
--- a/src/kimchi/control/storagepools.py
+++ b/src/kimchi/control/storagepools.py
@@ -34,7 +34,7 @@ from kimchi.model.storagepools import ISO_POOL_NAME
from kimchi.control.utils import UrlSubNode
-@UrlSubNode("storagepools", True)
+@UrlSubNode("storagepools", True, ['POST', 'DELETE'])
class StoragePools(Collection):
def __init__(self, model):
super(StoragePools, self).__init__(model)
diff --git a/src/kimchi/control/templates.py b/src/kimchi/control/templates.py
index 58dafcc..8135e32 100644
--- a/src/kimchi/control/templates.py
+++ b/src/kimchi/control/templates.py
@@ -25,7 +25,7 @@ from kimchi.control.base import Collection, Resource
from kimchi.control.utils import UrlSubNode
-@UrlSubNode("templates", True)
+@UrlSubNode("templates", True, ['PUT', 'DELETE'])
class Templates(Collection):
def __init__(self, model):
super(Templates, self).__init__(model)
diff --git a/src/kimchi/control/vms.py b/src/kimchi/control/vms.py
index 60fc8ff..a74ce27 100644
--- a/src/kimchi/control/vms.py
+++ b/src/kimchi/control/vms.py
@@ -27,7 +27,7 @@ from kimchi.control.utils import internal_redirect, UrlSubNode
from kimchi.control.vm import sub_nodes
-@UrlSubNode("vms", True)
+@UrlSubNode("vms", True, ['POST', 'PUT', 'DELETE'])
class VMs(Collection):
def __init__(self, model):
super(VMs, self).__init__(model)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0487ffc..e8db05c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -24,6 +24,7 @@ EXTRA_DIST = \
Makefile.am \
run_tests.sh.in \
iso_gen.py \
+ test_authorization.py \
test_config.py.in \
test_exception.py \
test_mockmodel.py \
diff --git a/tests/test_authorization.py b/tests/test_authorization.py
new file mode 100644
index 0000000..7f939a8
--- /dev/null
+++ b/tests/test_authorization.py
@@ -0,0 +1,124 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# Authors:
+# Aline Manera <alinefm(a)linux.vnet.ibm.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import unittest
+
+
+from functools import partial
+
+
+import kimchi.mockmodel
+from utils import get_free_port, patch_auth, request
+from utils import run_server
+
+
+test_server = None
+model = None
+host = None
+port = None
+ssl_port = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port
+
+ patch_auth(sudo = False)
+ model = kimchi.mockmodel.MockModel('/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ test_server = run_server(host, port, None, test_mode=True, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+
+class AuthorizationTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, port)
+ model.reset()
+
+ def test_nonroot_access(self):
+ # Non-root users can access static host information
+ resp = self.request('/host', '{}', 'GET')
+ self.assertEquals(200, resp.status)
+
+ # Non-root users can access host stats
+ resp = self.request('/host/stats', '{}', 'GET')
+ self.assertEquals(200, resp.status)
+
+ # Non-root users can not reboot/shutdown host system
+ resp = self.request('/host/reboot', '{}', 'POST')
+ self.assertEquals(401, resp.status)
+ resp = self.request('/host/shutdown', '{}', 'POST')
+ self.assertEquals(401, resp.status)
+
+ # Non-root users can not get or debug reports
+ resp = self.request('/debugreports', '{}', 'GET')
+ self.assertEquals(401, resp.status)
+ resp = self.request('/debugreports', '{}', 'POST')
+ self.assertEquals(401, resp.status)
+
+ # Non-root users can not create or delete network (only get)
+ resp = self.request('/networks', '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/networks', '{}', 'POST')
+ self.assertEquals(401, resp.status)
+ resp = self.request('/networks/default/activate', '{}', 'POST')
+ self.assertEquals(401, resp.status)
+ resp = self.request('/networks/default', '{}', 'DELETE')
+ self.assertEquals(401, resp.status)
+
+ # Non-root users can not create or delete storage pool (only get)
+ resp = self.request('/storagepools', '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/storagepools', '{}', 'POST')
+ self.assertEquals(401, resp.status)
+ resp = self.request('/storagepools/default/activate', '{}', 'POST')
+ self.assertEquals(401, resp.status)
+ resp = self.request('/storagepools/default', '{}', 'DELETE')
+ self.assertEquals(401, resp.status)
+
+ # Non-root users can not update or delete a template
+ # but he can get and create a new one
+ resp = self.request('/templates', '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ req = json.dumps({'name': 'test', 'cdrom': '/nonexistent.iso'})
+ resp = self.request('/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+ resp = self.request('/templates/test', '{}', 'PUT')
+ self.assertEquals(401, resp.status)
+ resp = self.request('/templates/test', '{}', 'DELETE')
+ self.assertEquals(401, resp.status)
+
+ # Non-root users can only get vms
+ resp = self.request('/vms', '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/vms', req, 'POST')
+ self.assertEquals(401, resp.status)
+ resp = self.request('/vms', '{}', 'PUT')
+ self.assertEquals(401, resp.status)
+ resp = self.request('/vms', '{}', 'DELETE')
+ self.assertEquals(401, resp.status)
diff --git a/tests/utils.py b/tests/utils.py
index 14c57d4..18b707c 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -147,11 +147,31 @@ def https_request(host, port, path, data=None, method='GET', headers=None):
return _request(conn, path, data, method, headers)
-def patch_auth():
+def patch_auth(sudo=True):
"""
Override the authenticate function with a simple test against an
internal dict of users and passwords.
"""
+ USER_ID = 'userid'
+ USER_GROUPS = 'groups'
+ USER_SUDO = 'sudo'
+
+ class _User(object):
+ def __init__(self, userid):
+ self.user = {}
+ self.user[USER_ID] = userid
+ self.user[USER_GROUPS] = None
+ self.user[USER_SUDO] = sudo
+
+ def get_groups(self):
+ return self.user[USER_GROUPS]
+
+ def has_sudo(self):
+ return self.user[USER_SUDO]
+
+ def get_user(self):
+ return self.user
+
def _authenticate(username, password, service="passwd"):
try:
return fake_user[username] == password
@@ -161,6 +181,7 @@ def patch_auth():
import kimchi.auth
kimchi.auth.authenticate = _authenticate
+ kimchi.auth.User = _User
def normalize_xml(xml_str):
--
1.7.10.4
10 years, 10 months
[PATCH 0/2] Bug Fix #318 - Kimchi fails creating new network
by Ramon Medeiros
Test attached
Ramon Medeiros (2):
Bug fix #318 Kimchi fails creating new network
Add one more case to network tests
src/kimchi/model/networks.py | 14 +++++++-------
tests/test_model.py | 36 ++++++++++++++++++++++++++++++++----
2 files changed, 39 insertions(+), 11 deletions(-)
--
1.8.3.1
10 years, 10 months