Commit 6f04d079 authored by Stavros Sachtouris's avatar Stavros Sachtouris
Browse files

Merge branch 'feature-osv2-compatibility' into develop

parents f0415090 4abb3f7e
......@@ -54,6 +54,9 @@ Changes:
- server: firewall, metadata
- Add a _format_image_headers method and use it in image_register and get_meta
for uniform image meta output [#3797]
- Rename meta-->metadata and remove values @lib [#3633]
- Adjust astakos authenticate to the new url shchem of synnefo >= 0.14
Features:
......
......@@ -98,30 +98,12 @@ class server_list(_init_cyclades, _optional_json):
enum=FlagArgument('Enumerate results', '--enumerate')
)
def _make_results_pretty(self, servers):
for server in servers:
addr_dict = {}
if 'attachments' in server:
for addr in server['attachments']['values']:
ips = addr.pop('values', [])
for ip in ips:
addr['IPv%s' % ip['version']] = ip['addr']
if 'firewallProfile' in addr:
addr['firewall'] = addr.pop('firewallProfile')
addr_dict[addr.pop('id')] = addr
server['attachments'] = addr_dict if addr_dict else None
if 'metadata' in server:
server['metadata'] = server['metadata']['values']
@errors.generic.all
@errors.cyclades.connection
@errors.cyclades.date
def _run(self):
servers = self.client.list_servers(self['detail'], self['since'])
if self['detail'] and not self['json_output']:
self._make_results_pretty(servers)
kwargs = dict(with_enumeration=self['enum'])
if self['more']:
kwargs['page_size'] = self['limit'] if self['limit'] else 10
......@@ -144,27 +126,11 @@ class server_info(_init_cyclades, _optional_json):
- hardware flavor and os image ids
"""
def _pretty(self, server):
addr_dict = {}
if 'attachments' in server:
atts = server.pop('attachments')
for addr in atts['values']:
ips = addr.pop('values', [])
for ip in ips:
addr['IPv%s' % ip['version']] = ip['addr']
if 'firewallProfile' in addr:
addr['firewall'] = addr.pop('firewallProfile')
addr_dict[addr.pop('id')] = addr
server['attachments'] = addr_dict if addr_dict else None
if 'metadata' in server:
server['metadata'] = server['metadata']['values']
print_dict(server, ident=1)
@errors.generic.all
@errors.cyclades.connection
@errors.cyclades.server_id
def _run(self, server_id):
self._print(self.client.get_server_details(server_id), self._pretty)
self._print(self.client.get_server_details(server_id), print_dict)
def main(self, server_id):
super(self.__class__, self)._run()
......@@ -224,8 +190,10 @@ class server_create(_init_cyclades, _optional_json):
@errors.plankton.id
@errors.cyclades.flavor_id
def _run(self, name, flavor_id, image_id):
self._print([self.client.create_server(
name, int(flavor_id), image_id, self['personality'])])
self._print(
self.client.create_server(
name, int(flavor_id), image_id, self['personality']),
print_dict)
def main(self, name, flavor_id, image_id):
super(self.__class__, self)._run()
......@@ -328,7 +296,8 @@ class server_console(_init_cyclades, _optional_json):
@errors.cyclades.connection
@errors.cyclades.server_id
def _run(self, server_id):
self._print([self.client.get_server_console(int(server_id))])
self._print(
self.client.get_server_console(int(server_id)), print_dict)
def main(self, server_id):
super(self.__class__, self)._run()
......@@ -413,7 +382,7 @@ class server_metadata_list(_init_cyclades, _optional_json):
@errors.cyclades.metadata
def _run(self, server_id, key=''):
self._print(
[self.client.get_server_metadata(int(server_id), key)], title=())
self.client.get_server_metadata(int(server_id), key), print_dict)
def main(self, server_id, key=''):
super(self.__class__, self)._run()
......@@ -448,8 +417,8 @@ class server_metadata_set(_init_cyclades, _optional_json):
'/server metadata set <server id>'
'key1=value1 key2=value2'])
self._print(
[self.client.update_server_metadata(int(server_id), **metadata)],
title=())
self.client.update_server_metadata(int(server_id), **metadata),
print_dict)
def main(self, server_id, *key_equals_val):
super(self.__class__, self)._run()
......@@ -481,7 +450,7 @@ class server_stats(_init_cyclades, _optional_json):
@errors.cyclades.connection
@errors.cyclades.server_id
def _run(self, server_id):
self._print([self.client.get_server_stats(int(server_id))])
self._print(self.client.get_server_stats(int(server_id)), print_dict)
def main(self, server_id):
super(self.__class__, self)._run()
......@@ -566,7 +535,8 @@ class flavor_info(_init_cyclades, _optional_json):
@errors.cyclades.connection
@errors.cyclades.flavor_id
def _run(self, flavor_id):
self._print([self.client.get_flavor_details(int(flavor_id))])
self._print(
self.client.get_flavor_details(int(flavor_id)), print_dict)
def main(self, flavor_id):
super(self.__class__, self)._run()
......@@ -579,20 +549,11 @@ class network_info(_init_cyclades, _optional_json):
To get a list of available networks and network ids, try /network list
"""
@classmethod
def _make_result_pretty(self, net):
if 'attachments' in net:
att = net['attachments']['values']
count = len(att)
net['attachments'] = att if count else None
@errors.generic.all
@errors.cyclades.connection
@errors.cyclades.network_id
def _run(self, network_id):
network = self.client.get_network_details(int(network_id))
self._make_result_pretty(network)
#print_dict(network, exclude=('id'))
self._print(network, print_dict, exclude=('id'))
def main(self, network_id):
......@@ -613,16 +574,10 @@ class network_list(_init_cyclades, _optional_json):
enum=FlagArgument('Enumerate results', '--enumerate')
)
def _make_results_pretty(self, nets):
for net in nets:
network_info._make_result_pretty(net)
@errors.generic.all
@errors.cyclades.connection
def _run(self):
networks = self.client.list_networks(self['detail'])
if self['detail']:
self._make_results_pretty(networks)
kwargs = dict(with_enumeration=self['enum'])
if self['more']:
kwargs['page_size'] = self['limit'] or 10
......@@ -654,12 +609,12 @@ class network_create(_init_cyclades, _optional_json):
@errors.cyclades.connection
@errors.cyclades.network_max
def _run(self, name):
self._print([self.client.create_network(
self._print(self.client.create_network(
name,
cidr=self['cidr'],
gateway=self['gateway'],
dhcp=self['dhcp'],
type=self['type'])])
type=self['type']), print_dict)
def main(self, name):
super(self.__class__, self)._run()
......
......@@ -533,21 +533,14 @@ class image_compute_list(_init_cyclades, _optional_json):
enum=FlagArgument('Enumerate results', '--enumerate')
)
def _make_results_pretty(self, images):
for img in images:
if 'metadata' in img:
img['metadata'] = img['metadata']['values']
@errors.generic.all
@errors.cyclades.connection
def _run(self):
images = self.client.list_images(self['detail'])
if self['detail'] and not self['json_output']:
self._make_results_pretty(images)
kwargs = dict(with_enumeration=self['enum'])
if self['more']:
kwargs['page_size'] = self['limit'] or 10
else:
elif self['limit']:
images = images[:self['limit']]
self._print(images, **kwargs)
......@@ -565,9 +558,7 @@ class image_compute_info(_init_cyclades, _optional_json):
@errors.plankton.id
def _run(self, image_id):
image = self.client.get_image_details(image_id)
if (not self['json_output']) and 'metadata' in image:
image['metadata'] = image['metadata']['values']
self._print([image])
self._print(image, print_dict)
def main(self, image_id):
super(self.__class__, self)._run()
......
......@@ -51,7 +51,7 @@ class AstakosClient(Client):
:returns: (dict) authentication information
"""
self.token = token or self.token
self._cache[self.token] = self.get('/im/authenticate').json
self._cache[self.token] = self.get('/astakos/api/authenticate').json
return self._cache[self.token]
def list(self):
......
......@@ -81,7 +81,7 @@ class AstakosClient(TestCase):
@patch('%s.get' % astakos_pkg, return_value=FR())
def _authenticate(self, get):
r = self.client.authenticate()
self.assertEqual(get.mock_calls[-1], call('/im/authenticate'))
self.assertEqual(get.mock_calls[-1], call('/astakos/api/authenticate'))
self.cached = True
return r
......
......@@ -47,7 +47,7 @@ class ComputeClient(ComputeRestClient):
"""
detail = 'detail' if detail else ''
r = self.servers_get(command=detail)
return r.json['servers']['values']
return r.json['servers']
def get_server_details(self, server_id, **kwargs):
"""Return detailed info for a server
......@@ -83,7 +83,7 @@ class ComputeClient(ComputeRestClient):
metadata = {}
for key in ('os', 'users'):
try:
metadata[key] = image['metadata']['values'][key]
metadata[key] = image['metadata'][key]
except KeyError:
pass
if metadata:
......@@ -151,9 +151,9 @@ class ComputeClient(ComputeRestClient):
:returns: a key:val dict of requests metadata
"""
command = path4url('meta', key)
command = path4url('metadata', key)
r = self.servers_get(server_id, command)
return r.json['meta'] if key else r.json['metadata']['values']
return r.json['metadata']
def create_server_metadata(self, server_id, key, val):
"""
......@@ -165,13 +165,13 @@ class ComputeClient(ComputeRestClient):
:returns: dict of updated key:val metadata
"""
req = {'meta': {key: val}}
req = {'metadata': {key: val}}
r = self.servers_put(
server_id,
'meta/' + key,
'metadata/' + key,
json_data=req,
success=201)
return r.json['meta']
return r.json['metadata']
def update_server_metadata(self, server_id, **metadata):
"""
......@@ -182,7 +182,9 @@ class ComputeClient(ComputeRestClient):
:returns: dict of updated key:val metadata
"""
req = {'metadata': metadata}
r = self.servers_post(server_id, 'meta', json_data=req, success=201)
r = self.servers_post(
server_id, 'metadata',
json_data=req, success=201)
return r.json['metadata']
def delete_server_metadata(self, server_id, key):
......@@ -193,17 +195,17 @@ class ComputeClient(ComputeRestClient):
:returns: (dict) response headers
"""
r = self.servers_delete(server_id, 'meta/' + key)
r = self.servers_delete(server_id, 'metadata/' + key)
return r.headers
def list_flavors(self, detail=False):
"""
:param detail: (bool) detailed flavor info if set, short if not
:returns: (dict) flavor info
:returns: (list) flavor info
"""
r = self.flavors_get(command='detail' if detail else '')
return r.json['flavors']['values']
return r.json['flavors']
def get_flavor_details(self, flavor_id):
"""
......@@ -222,7 +224,7 @@ class ComputeClient(ComputeRestClient):
"""
detail = 'detail' if detail else ''
r = self.images_get(command=detail)
return r.json['images']['values']
return r.json['images']
def get_image_details(self, image_id, **kwargs):
"""
......@@ -254,9 +256,9 @@ class ComputeClient(ComputeRestClient):
:returns (dict) metadata if key not set, specific metadatum otherwise
"""
command = path4url('meta', key)
command = path4url('metadata', key)
r = self.images_get(image_id, command)
return r.json['meta'] if key else r.json['metadata']['values']
return r.json['metadata']
def create_image_metadata(self, image_id, key, val):
"""
......@@ -268,9 +270,9 @@ class ComputeClient(ComputeRestClient):
:returns: (dict) updated metadata
"""
req = {'meta': {key: val}}
r = self.images_put(image_id, 'meta/' + key, json_data=req)
return r.json['meta']
req = {'metadata': {key: val}}
r = self.images_put(image_id, 'metadata/' + key, json_data=req)
return r.json['metadata']
def update_image_metadata(self, image_id, **metadata):
"""
......@@ -281,7 +283,7 @@ class ComputeClient(ComputeRestClient):
:returns: updated metadata
"""
req = {'metadata': metadata}
r = self.images_post(image_id, 'meta', json_data=req)
r = self.images_post(image_id, 'metadata', json_data=req)
return r.json['metadata']
def delete_image_metadata(self, image_id, key):
......@@ -292,6 +294,6 @@ class ComputeClient(ComputeRestClient):
:returns: (dict) response headers
"""
command = path4url('meta', key)
command = path4url('metadata', key)
r = self.images_delete(image_id, command)
return r.headers
......@@ -62,7 +62,7 @@ vm_recv = dict(server=dict(
suspended=False,
progress=0,
id=31173,
metadata=dict(values=dict(os="debian", users="root"))))
metadata=dict(os="debian", users="root")))
img_recv = dict(image=dict(
status="ACTIVE",
updated="2013-02-26T11:10:14+00:00",
......@@ -70,7 +70,7 @@ img_recv = dict(image=dict(
created="2013-02-26T11:03:29+00:00",
progress=100,
id=img_ref,
metadata=dict(values=dict(
metadata=dict(
partition_table="msdos",
kernel="2.6.32",
osfamily="linux",
......@@ -79,15 +79,15 @@ img_recv = dict(image=dict(
sortorder="1",
os="debian",
root_partition="1",
description="Debian 6.0.7 (Squeeze) Base System"))))
vm_list = dict(servers=dict(values=[
description="Debian 6.0.7 (Squeeze) Base System")))
vm_list = dict(servers=[
dict(name='n1', id=1),
dict(name='n2', id=2)]))
flavor_list = dict(flavors=dict(values=[
dict(name='n2', id=2)])
flavor_list = dict(flavors=[
dict(id=41, name="C1R1024D20"),
dict(id=42, name="C1R1024D40"),
dict(id=43, name="C1R1028D20")]))
img_list = dict(images=dict(values=[
dict(id=43, name="C1R1028D20")])
img_list = dict(images=[
dict(name="maelstrom", id="0fb03e45-7d5a-4515-bd4e-e6bbf6457f06"),
dict(name="edx_saas", id="1357163d-5fd8-488e-a117-48734c526206"),
dict(name="Debian_Wheezy_Base", id="1f8454f0-8e3e-4b6c-ab8e-5236b728dffe"),
......@@ -95,7 +95,7 @@ img_list = dict(images=dict(values=[
dict(name="Ubuntu Desktop", id="37bc522c-c479-4085-bfb9-464f9b9e2e31"),
dict(name="Ubuntu 12.10", id="3a24fef9-1a8c-47d1-8f11-e07bd5e544fd"),
dict(name="Debian Base", id="40ace203-6254-4e17-a5cb-518d55418a7d"),
dict(name="ubuntu_bundled", id="5336e265-5c7c-4127-95cb-2bf832a79903")]))
dict(name="ubuntu_bundled", id="5336e265-5c7c-4127-95cb-2bf832a79903")])
class FR(object):
......@@ -282,7 +282,7 @@ class ComputeClient(TestCase):
r = self.client.list_servers(detail)
self.assertEqual(SG.mock_calls[-1], call(
command='detail' if detail else ''))
for i, vm in enumerate(vm_list['servers']['values']):
for i, vm in enumerate(vm_list['servers']):
self.assert_dicts_are_equal(r[i], vm)
self.assertEqual(i + 1, len(r))
......@@ -314,28 +314,29 @@ class ComputeClient(TestCase):
def test_create_server_metadata(self, SP):
vm_id = vm_recv['server']['id']
metadata = dict(m1='v1', m2='v2', m3='v3')
FR.json = dict(meta=vm_recv['server'])
FR.json = dict(metadata=vm_recv['server'])
for k, v in metadata.items():
r = self.client.create_server_metadata(vm_id, k, v)
self.assert_dicts_are_equal(r, vm_recv['server'])
self.assertEqual(SP.mock_calls[-1], call(
vm_id, 'meta/%s' % k,
json_data=dict(meta={k: v}), success=201))
vm_id, 'metadata/%s' % k,
json_data=dict(metadata={k: v}), success=201))
@patch('%s.servers_get' % compute_pkg, return_value=FR())
def test_get_server_metadata(self, SG):
vm_id = vm_recv['server']['id']
metadata = dict(m1='v1', m2='v2', m3='v3')
FR.json = dict(metadata=dict(values=metadata))
FR.json = dict(metadata=metadata)
r = self.client.get_server_metadata(vm_id)
SG.assert_called_once_with(vm_id, '/meta')
SG.assert_called_once_with(vm_id, '/metadata')
self.assert_dicts_are_equal(r, metadata)
for k, v in metadata.items():
FR.json = dict(meta={k: v})
FR.json = dict(metadata={k: v})
r = self.client.get_server_metadata(vm_id, k)
self.assert_dicts_are_equal(r, {k: v})
self.assertEqual(SG.mock_calls[-1], call(vm_id, '/meta/%s' % k))
self.assertEqual(
SG.mock_calls[-1], call(vm_id, '/metadata/%s' % k))
@patch('%s.servers_post' % compute_pkg, return_value=FR())
def test_update_server_metadata(self, SP):
......@@ -345,7 +346,7 @@ class ComputeClient(TestCase):
r = self.client.update_server_metadata(vm_id, **metadata)
self.assert_dicts_are_equal(r, metadata)
SP.assert_called_once_with(
vm_id, 'meta',
vm_id, 'metadata',
json_data=dict(metadata=metadata), success=201)
@patch('%s.servers_delete' % compute_pkg, return_value=FR())
......@@ -353,7 +354,7 @@ class ComputeClient(TestCase):
vm_id = vm_recv['server']['id']
key = 'metakey'
self.client.delete_server_metadata(vm_id, key)
SD.assert_called_once_with(vm_id, 'meta/' + key)
SD.assert_called_once_with(vm_id, 'metadata/' + key)
@patch('%s.flavors_get' % compute_pkg, return_value=FR())
def test_list_flavors(self, FG):
......@@ -361,14 +362,14 @@ class ComputeClient(TestCase):
for cmd in ('', 'detail'):
r = self.client.list_flavors(detail=(cmd == 'detail'))
self.assertEqual(FG.mock_calls[-1], call(command=cmd))
self.assert_dicts_are_equal(dict(values=r), flavor_list['flavors'])
self.assertEqual(r, flavor_list['flavors'])
@patch('%s.flavors_get' % compute_pkg, return_value=FR())
def test_get_flavor_details(self, FG):
FR.json = dict(flavor=flavor_list['flavors'])
FR.json = dict(flavor=flavor_list['flavors'][0])
r = self.client.get_flavor_details(fid)
FG.assert_called_once_with(fid)
self.assert_dicts_are_equal(r, flavor_list['flavors'])
self.assert_dicts_are_equal(r, flavor_list['flavors'][0])
@patch('%s.images_get' % compute_pkg, return_value=FR())
def test_list_images(self, IG):
......@@ -376,7 +377,7 @@ class ComputeClient(TestCase):
for cmd in ('', 'detail'):
r = self.client.list_images(detail=(cmd == 'detail'))
self.assertEqual(IG.mock_calls[-1], call(command=cmd))
expected = img_list['images']['values']
expected = img_list['images']
for i in range(len(r)):
self.assert_dicts_are_equal(expected[i], r[i])
......@@ -390,12 +391,12 @@ class ComputeClient(TestCase):
@patch('%s.images_get' % compute_pkg, return_value=FR())
def test_get_image_metadata(self, IG):
for key in ('', '50m3k3y'):
FR.json = dict(meta=img_recv['image']) if (
key) else dict(metadata=dict(values=img_recv['image']))
FR.json = dict(metadata=img_recv['image']) if (
key) else dict(metadata=img_recv['image'])
r = self.client.get_image_metadata(img_ref, key)
self.assertEqual(IG.mock_calls[-1], call(
'%s' % img_ref,
'/meta%s' % (('/%s' % key) if key else '')))
'/metadata%s' % (('/%s' % key) if key else '')))
self.assert_dicts_are_equal(img_recv['image'], r)
@patch('%s.servers_delete' % compute_pkg, return_value=FR())
......@@ -412,11 +413,11 @@ class ComputeClient(TestCase):
@patch('%s.images_put' % compute_pkg, return_value=FR())
def test_create_image_metadata(self, IP):
(key, val) = ('k1', 'v1')
FR.json = dict(meta=img_recv['image'])
FR.json = dict(metadata=img_recv['image'])
r = self.client.create_image_metadata(img_ref, key, val)
IP.assert_called_once_with(
img_ref, 'meta/%s' % key,
json_data=dict(meta={key: val}))
img_ref, 'metadata/%s' % key,
json_data=dict(metadata={key: val}))
self.assert_dicts_are_equal(r, img_recv['image'])
@patch('%s.images_post' % compute_pkg, return_value=FR())
......@@ -425,7 +426,7 @@ class ComputeClient(TestCase):
FR.json = dict(metadata=metadata)
r = self.client.update_image_metadata(img_ref, **metadata)
IP.assert_called_once_with(
img_ref, 'meta',
img_ref, 'metadata',
json_data=dict(metadata=metadata))
self.assert_dicts_are_equal(r, metadata)
......@@ -433,7 +434,7 @@ class ComputeClient(TestCase):
def test_delete_image_metadata(self, ID):
key = 'metakey'
self.client.delete_image_metadata(img_ref, key)
ID.assert_called_once_with(img_ref, '/meta/%s' % key)
ID.assert_called_once_with(img_ref, '/metadata/%s' % key)
if __name__ == '__main__':
......
......@@ -83,7 +83,7 @@ class CycladesClient(CycladesRestClient):
"""
r = self.get_server_details(server_id)
try:
return r['attachments']['values'][0]['firewallProfile']
return r['attachments'][0]['firewallProfile']
except KeyError:
raise ClientError(
'No Firewall Profile',
......@@ -112,7 +112,7 @@ class CycladesClient(CycladesRestClient):
"""
detail = 'detail' if detail else ''
r = self.servers_get(command=detail, changes_since=changes_since)
return r.json['servers']['values']
return r.json['servers']
def list_server_nics(self, server_id):
"""
......@@ -121,7 +121,7 @@ class CycladesClient(CycladesRestClient):
:returns: (dict) network interface connections
"""
r = self.servers_get(server_id, 'ips')
return r.json['addresses']['values']
return r.json['addresses']
def get_server_stats(self, server_id):
"""
......@@ -140,7 +140,7 @@ class CycladesClient(CycladesRestClient):
"""
detail = 'detail' if detail else ''
r = self.networks_get(command=detail)
return r.json['networks']['values']
return r.json['networks']
def list_network_nics(self, network_id):
"""
......@@ -149,7 +149,7 @@ class CycladesClient(CycladesRestClient):
:returns: (list)
"""
r = self.networks_get(network_id=network_id)
return r.json['network']['attachments']['values']
return r.json['network']['attachments']
def create_network(
self, name,
......
......@@ -52,10 +52,10 @@ vm_recv = dict(server=dict(
suspended=False,
progress=0,
id=31173,
metadata=dict(values=dict(os="debian", users="root"))))
vm_list = dict(servers=dict(values=[
metadata=dict(os="debian", users="root")))
vm_list = dict(servers=[
dict(name='n1', id=1),
dict(name='n2', id=2)]))