1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
3
# Copyright 2010-2011 OpenStack LLC.
4
# Copyright 2011 Piston Cloud Computing, Inc.
7
# Licensed under the Apache License, Version 2.0 (the "License"); you may
8
# not use this file except in compliance with the License. You may obtain
9
# a copy of the License at
11
# http://www.apache.org/licenses/LICENSE-2.0
13
# Unless required by applicable law or agreed to in writing, software
14
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16
# License for the specific language governing permissions and limitations
23
from lxml import etree
26
import nova.api.openstack.compute
27
from nova.api.openstack.compute import ips
28
from nova.api.openstack.compute import servers
29
from nova.api.openstack.compute import views
30
from nova.api.openstack import xmlutil
31
import nova.compute.api
32
from nova.compute import instance_types
33
from nova.compute import task_states
34
from nova.compute import vm_states
36
from nova.db.sqlalchemy.models import InstanceMetadata
37
from nova import flags
38
import nova.image.fake
40
import nova.scheduler.api
42
from nova.tests.api.openstack import fakes
43
from nova import utils
47
FAKE_UUID = fakes.FAKE_UUID
48
FAKE_UUIDS = {0: FAKE_UUID}
49
NS = "{http://docs.openstack.org/compute/api/v1.1}"
50
ATOMNS = "{http://www.w3.org/2005/Atom}"
52
'atom': 'http://www.w3.org/2005/Atom',
53
'ns': 'http://docs.openstack.org/compute/api/v1.1'
57
def get_fake_uuid(token=0):
58
if not token in FAKE_UUIDS:
59
FAKE_UUIDS[token] = str(utils.gen_uuid())
60
return FAKE_UUIDS[token]
67
def return_server_by_id(context, id):
68
return fakes.stub_instance(id)
71
def return_server_by_uuid(context, uuid):
73
return fakes.stub_instance(id, uuid=uuid)
76
def return_server_with_attributes(**kwargs):
77
def _return_server(context, instance_id):
78
return fakes.stub_instance(instance_id, **kwargs)
82
def return_server_with_attributes_by_uuid(**kwargs):
83
def _return_server(context, uuid):
84
return fakes.stub_instance(1, uuid=uuid, **kwargs)
88
def return_server_with_state(vm_state, task_state=None):
89
def _return_server(context, uuid):
90
return fakes.stub_instance(1, uuid=uuid, vm_state=vm_state,
91
task_state=task_state)
95
def return_server_with_uuid_and_state(vm_state, task_state):
96
def _return_server(context, id):
97
return fakes.stub_instance(id,
100
task_state=task_state)
101
return _return_server
104
def return_servers(context, *args, **kwargs):
107
server = fakes.stub_instance(i, 'fake', 'fake', uuid=get_fake_uuid(i))
108
servers_list.append(server)
112
def return_servers_by_reservation(context, reservation_id=""):
113
return [fakes.stub_instance(i, reservation_id) for i in xrange(5)]
116
def return_servers_by_reservation_empty(context, reservation_id=""):
120
def return_servers_from_child_zones_empty(*args, **kwargs):
124
def return_servers_from_child_zones(*args, **kwargs):
125
class Server(object):
129
for zone in xrange(3):
131
for server_id in xrange(5):
133
server._info = fakes.stub_instance(
134
server_id, reservation_id="child")
135
servers_list.append(server)
137
zones.append(("Zone%d" % zone, servers_list))
141
def return_security_group(context, instance_id, security_group_id):
145
def instance_update(context, instance_id, values):
146
return fakes.stub_instance(instance_id, name=values.get('display_name'))
149
def fake_compute_api(cls, req, id):
153
def find_host(self, context, instance_id):
157
class MockSetAdminPassword(object):
159
self.instance_id = None
162
def __call__(self, context, instance_id, password):
163
self.instance_id = instance_id
164
self.password = password
167
class ServersControllerTest(test.TestCase):
170
super(ServersControllerTest, self).setUp()
171
self.flags(verbose=True, use_ipv6=False)
172
fakes.stub_out_networking(self.stubs)
173
fakes.stub_out_rate_limiting(self.stubs)
174
fakes.stub_out_key_pair_funcs(self.stubs)
175
fakes.stub_out_image_service(self.stubs)
176
fakes.stub_out_nw_api(self.stubs)
177
self.stubs.Set(nova.db, 'instance_get_all_by_filters',
179
self.stubs.Set(nova.db, 'instance_get', return_server_by_id)
180
self.stubs.Set(nova.db, 'instance_get_by_uuid',
181
return_server_by_uuid)
182
self.stubs.Set(nova.db, 'instance_get_all_by_project',
184
self.stubs.Set(nova.db, 'instance_add_security_group',
185
return_security_group)
186
self.stubs.Set(nova.db, 'instance_update', instance_update)
188
self.config_drive = None
190
self.controller = servers.Controller()
191
self.ips_controller = ips.Controller()
193
def nw_info(*args, **kwargs):
197
fakes.stub_out_nw_api_get_instance_nw_info(self.stubs, nw_info)
198
fakes.stub_out_nw_api_get_floating_ips_by_fixed_address(self.stubs,
201
def test_get_server_by_uuid(self):
203
The steps involved with resolving a UUID are pretty complicated;
204
here's what's happening in this scenario:
206
1. Show is calling `routing_get`
208
2. `routing_get` is wrapped by `reroute_compute` which does the work
209
of resolving requests to child zones.
211
3. `reroute_compute` looks up the UUID by hitting the stub
212
(returns_server_by_uuid)
214
4. Since the stub return that the record exists, `reroute_compute`
215
considers the request to be 'zone local', so it replaces the UUID
216
in the argument list with an integer ID and then calls the inner
219
5. The call to `get` hits the other stub 'returns_server_by_id` which
220
has the UUID set to FAKE_UUID
222
So, counterintuitively, we call `get` twice on the `show` command.
224
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
225
res_dict = self.controller.show(req, FAKE_UUID)
226
self.assertEqual(res_dict['server']['id'], FAKE_UUID)
228
def test_get_server_by_id(self):
229
self.flags(use_ipv6=True)
230
image_bookmark = "http://localhost/fake/images/10"
231
flavor_bookmark = "http://localhost/fake/flavors/1"
234
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % uuid)
235
res_dict = self.controller.show(req, uuid)
241
"updated": "2010-11-11T11:00:00Z",
242
"created": "2010-10-10T12:00:00Z",
255
"href": image_bookmark,
264
"href": flavor_bookmark,
273
"config_drive": None,
277
"href": "http://localhost/v2/fake/servers/%s" % uuid,
281
"href": "http://localhost/fake/servers/%s" % uuid,
287
self.assertDictMatch(res_dict, expected_server)
289
def test_get_server_with_active_status_by_id(self):
290
image_bookmark = "http://localhost/fake/images/10"
291
flavor_bookmark = "http://localhost/fake/flavors/1"
293
new_return_server = return_server_with_attributes(
294
vm_state=vm_states.ACTIVE, progress=100)
295
self.stubs.Set(nova.db, 'instance_get', new_return_server)
298
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % uuid)
299
res_dict = self.controller.show(req, uuid)
305
"updated": "2010-11-11T11:00:00Z",
306
"created": "2010-10-10T12:00:00Z",
319
"href": image_bookmark,
328
"href": flavor_bookmark,
337
"config_drive": None,
341
"href": "http://localhost/v2/fake/servers/%s" % uuid,
345
"href": "http://localhost/fake/servers/%s" % uuid,
351
self.assertDictMatch(res_dict, expected_server)
353
def test_get_server_with_id_image_ref_by_id(self):
355
image_bookmark = "http://localhost/fake/images/10"
357
flavor_bookmark = "http://localhost/fake/flavors/1"
359
new_return_server = return_server_with_attributes(
360
vm_state=vm_states.ACTIVE, image_ref=image_ref,
361
flavor_id=flavor_id, progress=100)
362
self.stubs.Set(nova.db, 'instance_get', new_return_server)
365
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % uuid)
366
res_dict = self.controller.show(req, uuid)
372
"updated": "2010-11-11T11:00:00Z",
373
"created": "2010-10-10T12:00:00Z",
386
"href": image_bookmark,
395
"href": flavor_bookmark,
404
"config_drive": None,
408
"href": "http://localhost/v2/fake/servers/%s" % uuid,
412
"href": "http://localhost/fake/servers/%s" % uuid,
418
self.assertDictMatch(res_dict, expected_server)
420
# NOTE(bcwaldon): lp830817
421
def test_get_server_by_id_malformed_networks(self):
422
def fake_instance_get(context, instance_uuid):
423
instance = return_server_by_uuid(context, instance_uuid)
424
instance['fixed_ips'] = [dict(network=None, address='1.2.3.4')]
427
self.stubs.Set(nova.db, 'instance_get_by_uuid', fake_instance_get)
429
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
430
res_dict = self.controller.show(req, FAKE_UUID)
432
self.assertEqual(res_dict['server']['id'], FAKE_UUID)
433
self.assertEqual(res_dict['server']['name'], 'server1')
435
def test_get_server_by_id_malformed_vif(self):
436
def fake_instance_get(context, uuid):
437
instance = return_server_by_uuid(context, uuid)
438
instance['fixed_ips'] = [dict(network={'label': 'meow'},
439
address='1.2.3.4', virtual_interface=None)]
442
self.stubs.Set(nova.db, 'instance_get_by_uuid', fake_instance_get)
444
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
445
res_dict = self.controller.show(req, FAKE_UUID)
447
self.assertEqual(res_dict['server']['id'], FAKE_UUID)
448
self.assertEqual(res_dict['server']['name'], 'server1')
450
def test_get_server_by_id_with_addresses(self):
451
self.flags(use_ipv6=True)
452
privates = ['192.168.0.3', '192.168.0.4']
453
publics = ['172.19.0.1', '172.19.0.2']
454
public6s = ['b33f::fdee:ddff:fecc:bbaa']
456
def nw_info(*args, **kwargs):
457
return [(None, {'label': 'public',
458
'ips': [dict(ip=ip) for ip in publics],
459
'ip6s': [dict(ip=ip) for ip in public6s]}),
460
(None, {'label': 'private',
461
'ips': [dict(ip=ip) for ip in privates]})]
463
def floaters(*args, **kwargs):
466
new_return_server = return_server_with_attributes()
467
fakes.stub_out_nw_api_get_instance_nw_info(self.stubs, nw_info)
468
fakes.stub_out_nw_api_get_floating_ips_by_fixed_address(self.stubs,
470
self.stubs.Set(nova.db, 'instance_get', new_return_server)
472
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
473
res_dict = self.controller.show(req, FAKE_UUID)
475
self.assertEqual(res_dict['server']['id'], FAKE_UUID)
476
self.assertEqual(res_dict['server']['name'], 'server1')
477
addresses = res_dict['server']['addresses']
480
{'addr': '192.168.0.3', 'version': 4},
481
{'addr': '192.168.0.4', 'version': 4},
484
{'addr': '172.19.0.1', 'version': 4},
485
{'addr': '172.19.0.2', 'version': 4},
486
{'addr': 'b33f::fdee:ddff:fecc:bbaa', 'version': 6},
489
self.assertDictMatch(addresses, expected)
491
def test_get_server_addresses_from_nwinfo(self):
492
self.flags(use_ipv6=True)
494
privates = ['192.168.0.3', '192.168.0.4']
495
publics = ['172.19.0.1', '1.2.3.4', '172.19.0.2']
497
public6s = ['b33f::fdee:ddff:fecc:bbaa']
499
def nw_info(*args, **kwargs):
500
return [(None, {'label': 'public',
501
'ips': [dict(ip=ip) for ip in publics],
502
'ip6s': [dict(ip=ip) for ip in public6s]}),
503
(None, {'label': 'private',
504
'ips': [dict(ip=ip) for ip in privates]})]
506
def floaters(*args, **kwargs):
509
new_return_server = return_server_with_attributes_by_uuid()
510
fakes.stub_out_nw_api_get_instance_nw_info(self.stubs, nw_info)
511
fakes.stub_out_nw_api_get_floating_ips_by_fixed_address(self.stubs,
513
self.stubs.Set(nova.db, 'instance_get_by_uuid', new_return_server)
515
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s/ips' % FAKE_UUID)
516
res_dict = self.ips_controller.index(req, FAKE_UUID)
521
{'version': 4, 'addr': '192.168.0.3'},
522
{'version': 4, 'addr': '192.168.0.4'},
525
{'version': 4, 'addr': '172.19.0.1'},
526
{'version': 4, 'addr': '1.2.3.4'},
527
{'version': 4, 'addr': '172.19.0.2'},
528
{'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
532
self.assertDictMatch(res_dict, expected)
534
def test_get_server_addresses_from_cache(self):
535
pub0 = ('172.19.0.1', '172.19.0.2',)
537
pub2 = ('b33f::fdee:ddff:fecc:bbaa',)
538
priv0 = ('192.168.0.3', '192.168.0.4',)
541
return {'address': ip, 'type': 'fixed'}
544
{'address': 'aa:aa:aa:aa:aa:aa',
546
'network': {'bridge': 'br0',
549
'subnets': [{'cidr': '172.19.0.0/24',
550
'ips': [_ip(ip) for ip in pub0]},
551
{'cidr': '1.2.3.0/16',
552
'ips': [_ip(ip) for ip in pub1]},
553
{'cidr': 'b33f::/64',
554
'ips': [_ip(ip) for ip in pub2]}]}},
555
{'address': 'bb:bb:bb:bb:bb:bb',
557
'network': {'bridge': 'br1',
560
'subnets': [{'cidr': '192.168.0.0/24',
561
'ips': [_ip(ip) for ip in priv0]}]}}]
563
kwargs = {'nw_cache': nw_cache}
564
new_return_server = return_server_with_attributes_by_uuid(**kwargs)
565
self.stubs.Set(nova.db, 'instance_get_by_uuid', new_return_server)
567
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s/ips' % FAKE_UUID)
568
res_dict = self.ips_controller.index(req, FAKE_UUID)
573
{'version': 4, 'addr': '192.168.0.3'},
574
{'version': 4, 'addr': '192.168.0.4'},
577
{'version': 4, 'addr': '172.19.0.1'},
578
{'version': 4, 'addr': '172.19.0.2'},
579
{'version': 4, 'addr': '1.2.3.4'},
580
{'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
584
self.assertDictMatch(res_dict, expected)
586
def test_get_server_addresses_with_floating_from_nwinfo(self):
587
ips = dict(privates=['192.168.0.3', '192.168.0.4'],
588
publics=['172.19.0.1', '1.2.3.4', '172.19.0.2'])
590
def nw_info(*args, **kwargs):
591
return [(None, {'label': 'private',
593
for ip in ips['privates']]})]
595
def floaters(*args, **kwargs):
596
# NOTE(jkoelker) floaters will get called multiple times
597
# this makes sure it will only return data
599
pubs = list(ips['publics'])
603
new_return_server = return_server_with_attributes_by_uuid()
604
fakes.stub_out_nw_api_get_instance_nw_info(self.stubs, nw_info)
605
fakes.stub_out_nw_api_get_floating_ips_by_fixed_address(self.stubs,
607
self.stubs.Set(nova.db, 'instance_get_by_uuid', new_return_server)
609
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s/ips' % FAKE_UUID)
610
res_dict = self.ips_controller.index(req, FAKE_UUID)
615
{'version': 4, 'addr': '192.168.0.3'},
616
{'version': 4, 'addr': '192.168.0.4'},
617
{'version': 4, 'addr': '172.19.0.1'},
618
{'version': 4, 'addr': '1.2.3.4'},
619
{'version': 4, 'addr': '172.19.0.2'},
623
self.assertDictMatch(res_dict, expected)
625
def test_get_server_addresses_single_network_from_nwinfo(self):
626
self.flags(use_ipv6=True)
627
privates = ['192.168.0.3', '192.168.0.4']
628
publics = ['172.19.0.1', '1.2.3.4', '172.19.0.2']
629
public6s = ['b33f::fdee:ddff:fecc:bbaa']
631
def nw_info(*args, **kwargs):
632
return [(None, {'label': 'public',
633
'ips': [dict(ip=ip) for ip in publics],
634
'ip6s': [dict(ip=ip) for ip in public6s]}),
635
(None, {'label': 'private',
636
'ips': [dict(ip=ip) for ip in privates]})]
638
def floaters(*args, **kwargs):
641
new_return_server = return_server_with_attributes_by_uuid()
642
fakes.stub_out_nw_api_get_instance_nw_info(self.stubs, nw_info)
643
fakes.stub_out_nw_api_get_floating_ips_by_fixed_address(self.stubs,
645
self.stubs.Set(nova.db, 'instance_get_by_uuid', new_return_server)
647
url = '/v2/fake/servers/%s/ips/public' % FAKE_UUID
648
req = fakes.HTTPRequest.blank(url)
649
res_dict = self.ips_controller.show(req, FAKE_UUID, 'public')
653
{'version': 4, 'addr': '172.19.0.1'},
654
{'version': 4, 'addr': '1.2.3.4'},
655
{'version': 4, 'addr': '172.19.0.2'},
656
{'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
659
self.assertDictMatch(res_dict, expected)
661
def test_get_server_addresses_nonexistant_network(self):
662
url = '/v2/fake/servers/%s/ips/network_0' % FAKE_UUID
663
req = fakes.HTTPRequest.blank(url)
664
self.assertRaises(webob.exc.HTTPNotFound, self.ips_controller.show,
665
req, FAKE_UUID, 'network_0')
667
def test_get_server_addresses_nonexistant_server(self):
668
def fake_instance_get(*args, **kwargs):
669
raise nova.exception.InstanceNotFound()
671
self.stubs.Set(nova.db, 'instance_get_by_uuid', fake_instance_get)
673
server_id = str(utils.gen_uuid())
674
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s/ips' % server_id)
675
self.assertRaises(webob.exc.HTTPNotFound,
676
self.ips_controller.index, req, server_id)
678
def test_get_server_list_with_reservation_id(self):
679
self.stubs.Set(nova.db, 'instance_get_all_by_reservation',
680
return_servers_by_reservation)
681
self.stubs.Set(nova.scheduler.api, 'call_zone_method',
682
return_servers_from_child_zones)
684
req = fakes.HTTPRequest.blank('/v2/fake/servers?reservation_id=foo')
685
res_dict = self.controller.index(req)
688
for s in res_dict['servers']:
689
if '_is_precooked' in s:
690
self.assertEqual(s.get('reservation_id'), 'child')
693
self.assertEqual(s.get('name'), 'server%d' % i)
696
def test_get_server_list_with_reservation_id_empty(self):
697
self.stubs.Set(nova.db, 'instance_get_all_by_reservation',
698
return_servers_by_reservation_empty)
699
self.stubs.Set(nova.scheduler.api, 'call_zone_method',
700
return_servers_from_child_zones_empty)
702
req = fakes.HTTPRequest.blank('/v2/fake/servers/detail?'
703
'reservation_id=foo')
704
res_dict = self.controller.detail(req)
707
for s in res_dict['servers']:
708
if '_is_precooked' in s:
709
self.assertEqual(s.get('reservation_id'), 'child')
711
self.assertEqual(s.get('name'), 'server%d' % i)
714
def test_get_server_list_with_reservation_id_details(self):
715
self.stubs.Set(nova.db, 'instance_get_all_by_reservation',
716
return_servers_by_reservation)
717
self.stubs.Set(nova.scheduler.api, 'call_zone_method',
718
return_servers_from_child_zones)
720
req = fakes.HTTPRequest.blank('/v2/fake/servers/detail?'
721
'reservation_id=foo')
722
res_dict = self.controller.detail(req)
725
for s in res_dict['servers']:
726
if '_is_precooked' in s:
727
self.assertEqual(s.get('reservation_id'), 'child')
729
self.assertEqual(s.get('name'), 'server%d' % i)
732
def test_get_server_list(self):
733
req = fakes.HTTPRequest.blank('/v2/fake/servers')
734
res_dict = self.controller.index(req)
736
self.assertEqual(len(res_dict['servers']), 5)
737
for i, s in enumerate(res_dict['servers']):
738
self.assertEqual(s['id'], get_fake_uuid(i))
739
self.assertEqual(s['name'], 'server%d' % i)
740
self.assertEqual(s.get('image', None), None)
745
"href": "http://localhost/v2/fake/servers/%s" % s['id'],
749
"href": "http://localhost/fake/servers/%s" % s['id'],
753
self.assertEqual(s['links'], expected_links)
755
def test_get_servers_with_limit(self):
756
req = fakes.HTTPRequest.blank('/v2/fake/servers?limit=3')
757
res_dict = self.controller.index(req)
759
servers = res_dict['servers']
760
self.assertEqual([s['id'] for s in servers],
761
[get_fake_uuid(i) for i in xrange(len(servers))])
763
servers_links = res_dict['servers_links']
764
self.assertEqual(servers_links[0]['rel'], 'next')
765
href_parts = urlparse.urlparse(servers_links[0]['href'])
766
self.assertEqual('/v2/fake/servers', href_parts.path)
767
params = urlparse.parse_qs(href_parts.query)
768
expected_params = {'limit': ['3'], 'marker': [get_fake_uuid(2)]}
769
self.assertDictMatch(expected_params, params)
771
def test_get_servers_with_limit_bad_value(self):
772
req = fakes.HTTPRequest.blank('/v2/fake/servers?limit=aaa')
773
self.assertRaises(webob.exc.HTTPBadRequest,
774
self.controller.index, req)
776
def test_get_server_details_with_limit(self):
777
req = fakes.HTTPRequest.blank('/v2/fake/servers/detail?limit=3')
778
res = self.controller.detail(req)
780
servers = res['servers']
781
self.assertEqual([s['id'] for s in servers],
782
[get_fake_uuid(i) for i in xrange(len(servers))])
784
servers_links = res['servers_links']
785
self.assertEqual(servers_links[0]['rel'], 'next')
787
href_parts = urlparse.urlparse(servers_links[0]['href'])
788
self.assertEqual('/v2/fake/servers', href_parts.path)
789
params = urlparse.parse_qs(href_parts.query)
790
expected = {'limit': ['3'], 'marker': [get_fake_uuid(2)]}
791
self.assertDictMatch(expected, params)
793
def test_get_server_details_with_limit_bad_value(self):
794
req = fakes.HTTPRequest.blank('/v2/fake/servers/detail?limit=aaa')
795
self.assertRaises(webob.exc.HTTPBadRequest,
796
self.controller.detail, req)
798
def test_get_server_details_with_limit_and_other_params(self):
799
req = fakes.HTTPRequest.blank('/v2/fake/servers/detail'
801
res = self.controller.detail(req)
803
servers = res['servers']
804
self.assertEqual([s['id'] for s in servers],
805
[get_fake_uuid(i) for i in xrange(len(servers))])
807
servers_links = res['servers_links']
808
self.assertEqual(servers_links[0]['rel'], 'next')
810
href_parts = urlparse.urlparse(servers_links[0]['href'])
811
self.assertEqual('/v2/fake/servers', href_parts.path)
812
params = urlparse.parse_qs(href_parts.query)
814
self.assertDictMatch({'limit': ['3'], 'blah': ['2:t'],
815
'marker': [get_fake_uuid(2)]}, params)
817
def test_get_servers_with_too_big_limit(self):
818
req = fakes.HTTPRequest.blank('/v2/fake/servers?limit=30')
819
res_dict = self.controller.index(req)
820
self.assertTrue('servers_links' not in res_dict)
822
def test_get_servers_with_bad_limit(self):
823
req = fakes.HTTPRequest.blank('/v2/fake/servers?limit=asdf')
824
self.assertRaises(webob.exc.HTTPBadRequest,
825
self.controller.index, req)
827
def test_get_servers_with_marker(self):
828
url = '/v2/fake/servers?marker=%s' % get_fake_uuid(2)
829
req = fakes.HTTPRequest.blank(url)
830
servers = self.controller.index(req)['servers']
831
self.assertEqual([s['name'] for s in servers], ["server3", "server4"])
833
def test_get_servers_with_limit_and_marker(self):
834
url = '/v2/fake/servers?limit=2&marker=%s' % get_fake_uuid(1)
835
req = fakes.HTTPRequest.blank(url)
836
servers = self.controller.index(req)['servers']
837
self.assertEqual([s['name'] for s in servers], ['server2', 'server3'])
839
def test_get_servers_with_bad_marker(self):
840
req = fakes.HTTPRequest.blank('/v2/fake/servers?limit=2&marker=asdf')
841
self.assertRaises(webob.exc.HTTPBadRequest,
842
self.controller.index, req)
844
def test_get_servers_with_bad_option(self):
845
server_uuid = str(utils.gen_uuid())
847
def fake_get_all(compute_self, context, search_opts=None):
848
return [fakes.stub_instance(100, uuid=server_uuid)]
850
self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
852
req = fakes.HTTPRequest.blank('/v2/fake/servers?unknownoption=whee')
853
servers = self.controller.index(req)['servers']
855
self.assertEqual(len(servers), 1)
856
self.assertEqual(servers[0]['id'], server_uuid)
858
def test_get_servers_allows_image(self):
859
server_uuid = str(utils.gen_uuid())
861
def fake_get_all(compute_self, context, search_opts=None):
862
self.assertNotEqual(search_opts, None)
863
self.assertTrue('image' in search_opts)
864
self.assertEqual(search_opts['image'], '12345')
865
return [fakes.stub_instance(100, uuid=server_uuid)]
867
self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
868
self.flags(allow_admin_api=False)
870
req = fakes.HTTPRequest.blank('/v2/fake/servers?image=12345')
871
servers = self.controller.index(req)['servers']
873
self.assertEqual(len(servers), 1)
874
self.assertEqual(servers[0]['id'], server_uuid)
876
def test_tenant_id_filter_converts_to_project_id_for_admin(self):
877
def fake_get_all(context, filters=None, instances=None):
878
self.assertNotEqual(filters, None)
879
self.assertEqual(filters['project_id'], 'fake')
880
self.assertFalse(filters.get('tenant_id'))
881
return [fakes.stub_instance(100)]
883
self.stubs.Set(nova.db, 'instance_get_all_by_filters',
885
self.flags(allow_admin_api=True)
887
req = fakes.HTTPRequest.blank('/v2/fake/servers?tenant_id=fake',
888
use_admin_context=True)
889
res = self.controller.index(req)
891
self.assertTrue('servers' in res)
893
def test_get_servers_allows_flavor(self):
894
server_uuid = str(utils.gen_uuid())
896
def fake_get_all(compute_self, context, search_opts=None):
897
self.assertNotEqual(search_opts, None)
898
self.assertTrue('flavor' in search_opts)
899
# flavor is an integer ID
900
self.assertEqual(search_opts['flavor'], '12345')
901
return [fakes.stub_instance(100, uuid=server_uuid)]
903
self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
904
self.flags(allow_admin_api=False)
906
req = fakes.HTTPRequest.blank('/v2/fake/servers?flavor=12345')
907
servers = self.controller.index(req)['servers']
909
self.assertEqual(len(servers), 1)
910
self.assertEqual(servers[0]['id'], server_uuid)
912
def test_get_servers_allows_status(self):
913
server_uuid = str(utils.gen_uuid())
915
def fake_get_all(compute_self, context, search_opts=None):
916
self.assertNotEqual(search_opts, None)
917
self.assertTrue('vm_state' in search_opts)
918
self.assertEqual(search_opts['vm_state'], vm_states.ACTIVE)
919
return [fakes.stub_instance(100, uuid=server_uuid)]
921
self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
922
self.flags(allow_admin_api=False)
924
req = fakes.HTTPRequest.blank('/v2/fake/servers?status=active')
925
servers = self.controller.index(req)['servers']
927
self.assertEqual(len(servers), 1)
928
self.assertEqual(servers[0]['id'], server_uuid)
930
def test_get_servers_invalid_status(self):
931
"""Test getting servers by invalid status"""
932
self.flags(allow_admin_api=False)
933
req = fakes.HTTPRequest.blank('/v2/fake/servers?status=unknown')
934
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.index, req)
936
def test_get_servers_allows_name(self):
937
server_uuid = str(utils.gen_uuid())
939
def fake_get_all(compute_self, context, search_opts=None):
940
self.assertNotEqual(search_opts, None)
941
self.assertTrue('name' in search_opts)
942
self.assertEqual(search_opts['name'], 'whee.*')
943
return [fakes.stub_instance(100, uuid=server_uuid)]
945
self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
946
self.flags(allow_admin_api=False)
948
req = fakes.HTTPRequest.blank('/v2/fake/servers?name=whee.*')
949
servers = self.controller.index(req)['servers']
951
self.assertEqual(len(servers), 1)
952
self.assertEqual(servers[0]['id'], server_uuid)
954
def test_get_servers_allows_changes_since(self):
955
server_uuid = str(utils.gen_uuid())
957
def fake_get_all(compute_self, context, search_opts=None):
958
self.assertNotEqual(search_opts, None)
959
self.assertTrue('changes-since' in search_opts)
960
changes_since = datetime.datetime(2011, 1, 24, 17, 8, 1)
961
self.assertEqual(search_opts['changes-since'], changes_since)
962
self.assertTrue('deleted' not in search_opts)
963
return [fakes.stub_instance(100, uuid=server_uuid)]
965
self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
967
params = 'changes-since=2011-01-24T17:08:01Z'
968
req = fakes.HTTPRequest.blank('/v2/fake/servers?%s' % params)
969
servers = self.controller.index(req)['servers']
971
self.assertEqual(len(servers), 1)
972
self.assertEqual(servers[0]['id'], server_uuid)
974
def test_get_servers_allows_changes_since_bad_value(self):
975
params = 'changes-since=asdf'
976
req = fakes.HTTPRequest.blank('/v2/fake/servers?%s' % params)
977
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.index, req)
979
def test_get_servers_unknown_or_admin_options1(self):
980
"""Test getting servers by admin-only or unknown options.
981
This tests when admin_api is off. Make sure the admin and
982
unknown options are stripped before they get to
983
compute_api.get_all()
986
self.flags(allow_admin_api=False)
988
server_uuid = str(utils.gen_uuid())
990
def fake_get_all(compute_self, context, search_opts=None):
991
self.assertNotEqual(search_opts, None)
993
self.assertTrue('name' in search_opts)
994
self.assertTrue('status' in search_opts)
995
# Allowed only by admins with admin API on
996
self.assertFalse('ip' in search_opts)
997
self.assertFalse('unknown_option' in search_opts)
998
return [fakes.stub_instance(100, uuid=server_uuid)]
1000
self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1002
query_str = "name=foo&ip=10.*&status=active&unknown_option=meow"
1003
req = fakes.HTTPRequest.blank('/v2/fake/servers?%s' % query_str,
1004
use_admin_context=True)
1005
res = self.controller.index(req)
1007
servers = res['servers']
1008
self.assertEqual(len(servers), 1)
1009
self.assertEqual(servers[0]['id'], server_uuid)
1011
def test_get_servers_unknown_or_admin_options2(self):
1012
"""Test getting servers by admin-only or unknown options.
1013
This tests when admin_api is on, but context is a user.
1014
Make sure the admin and unknown options are stripped before
1015
they get to compute_api.get_all()
1018
self.flags(allow_admin_api=True)
1020
server_uuid = str(utils.gen_uuid())
1022
def fake_get_all(compute_self, context, search_opts=None):
1023
self.assertNotEqual(search_opts, None)
1025
self.assertTrue('name' in search_opts)
1026
self.assertTrue('status' in search_opts)
1027
# Allowed only by admins with admin API on
1028
self.assertFalse('ip' in search_opts)
1029
self.assertFalse('unknown_option' in search_opts)
1030
return [fakes.stub_instance(100, uuid=server_uuid)]
1032
self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1034
query_str = "name=foo&ip=10.*&status=active&unknown_option=meow"
1035
req = fakes.HTTPRequest.blank('/v2/fake/servers?%s' % query_str)
1036
res = self.controller.index(req)
1038
servers = res['servers']
1039
self.assertEqual(len(servers), 1)
1040
self.assertEqual(servers[0]['id'], server_uuid)
1042
def test_get_servers_unknown_or_admin_options3(self):
1043
"""Test getting servers by admin-only or unknown options.
1044
This tests when admin_api is on and context is admin.
1045
All options should be passed through to compute_api.get_all()
1048
self.flags(allow_admin_api=True)
1050
server_uuid = str(utils.gen_uuid())
1052
def fake_get_all(compute_self, context, search_opts=None):
1053
self.assertNotEqual(search_opts, None)
1055
self.assertTrue('name' in search_opts)
1056
self.assertTrue('status' in search_opts)
1057
# Allowed only by admins with admin API on
1058
self.assertTrue('ip' in search_opts)
1059
self.assertTrue('unknown_option' in search_opts)
1060
return [fakes.stub_instance(100, uuid=server_uuid)]
1062
self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1064
query_str = "name=foo&ip=10.*&status=active&unknown_option=meow"
1065
req = fakes.HTTPRequest.blank('/v2/fake/servers?%s' % query_str,
1066
use_admin_context=True)
1067
servers = self.controller.index(req)['servers']
1069
self.assertEqual(len(servers), 1)
1070
self.assertEqual(servers[0]['id'], server_uuid)
1072
def test_get_servers_admin_allows_ip(self):
1073
"""Test getting servers by ip with admin_api enabled and
1076
self.flags(allow_admin_api=True)
1078
server_uuid = str(utils.gen_uuid())
1080
def fake_get_all(compute_self, context, search_opts=None):
1081
self.assertNotEqual(search_opts, None)
1082
self.assertTrue('ip' in search_opts)
1083
self.assertEqual(search_opts['ip'], '10\..*')
1084
return [fakes.stub_instance(100, uuid=server_uuid)]
1086
self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1088
req = fakes.HTTPRequest.blank('/v2/fake/servers?ip=10\..*',
1089
use_admin_context=True)
1090
servers = self.controller.index(req)['servers']
1092
self.assertEqual(len(servers), 1)
1093
self.assertEqual(servers[0]['id'], server_uuid)
1095
def test_get_servers_admin_allows_ip6(self):
1096
"""Test getting servers by ip6 with admin_api enabled and
1099
self.flags(allow_admin_api=True)
1101
server_uuid = str(utils.gen_uuid())
1103
def fake_get_all(compute_self, context, search_opts=None):
1104
self.assertNotEqual(search_opts, None)
1105
self.assertTrue('ip6' in search_opts)
1106
self.assertEqual(search_opts['ip6'], 'ffff.*')
1107
return [fakes.stub_instance(100, uuid=server_uuid)]
1109
self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1111
req = fakes.HTTPRequest.blank('/v2/fake/servers?ip6=ffff.*',
1112
use_admin_context=True)
1113
servers = self.controller.index(req)['servers']
1115
self.assertEqual(len(servers), 1)
1116
self.assertEqual(servers[0]['id'], server_uuid)
1118
def test_update_server_no_body(self):
1119
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
1122
self.assertRaises(webob.exc.HTTPUnprocessableEntity,
1123
self.controller.update, req, FAKE_UUID, None)
1125
def test_update_server_all_attributes(self):
1126
self.stubs.Set(nova.db, 'instance_get',
1127
return_server_with_attributes(name='server_test',
1128
access_ipv4='0.0.0.0',
1129
access_ipv6='beef::0123'))
1130
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
1132
req.content_type = 'application/json'
1134
'name': 'server_test',
1135
'accessIPv4': '0.0.0.0',
1136
'accessIPv6': 'beef::0123',
1138
req.body = json.dumps(body)
1139
res_dict = self.controller.update(req, FAKE_UUID, body)
1141
self.assertEqual(res_dict['server']['id'], FAKE_UUID)
1142
self.assertEqual(res_dict['server']['name'], 'server_test')
1143
self.assertEqual(res_dict['server']['accessIPv4'], '0.0.0.0')
1144
self.assertEqual(res_dict['server']['accessIPv6'], 'beef::0123')
1146
def test_update_server_name(self):
1147
self.stubs.Set(nova.db, 'instance_get',
1148
return_server_with_attributes(name='server_test'))
1149
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
1151
req.content_type = 'application/json'
1152
body = {'server': {'name': 'server_test'}}
1153
req.body = json.dumps(body)
1154
res_dict = self.controller.update(req, FAKE_UUID, body)
1156
self.assertEqual(res_dict['server']['id'], FAKE_UUID)
1157
self.assertEqual(res_dict['server']['name'], 'server_test')
1159
def test_update_server_access_ipv4(self):
1160
self.stubs.Set(nova.db, 'instance_get',
1161
return_server_with_attributes(access_ipv4='0.0.0.0'))
1162
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
1164
req.content_type = 'application/json'
1165
body = {'server': {'accessIPv4': '0.0.0.0'}}
1166
req.body = json.dumps(body)
1167
res_dict = self.controller.update(req, FAKE_UUID, body)
1169
self.assertEqual(res_dict['server']['id'], FAKE_UUID)
1170
self.assertEqual(res_dict['server']['accessIPv4'], '0.0.0.0')
1172
def test_update_server_access_ipv4_bad_format(self):
1173
self.stubs.Set(nova.db, 'instance_get',
1174
return_server_with_attributes(access_ipv4='0.0.0.0'))
1175
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
1177
req.content_type = 'application/json'
1178
body = {'server': {'accessIPv4': 'bad_format'}}
1179
req.body = json.dumps(body)
1180
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
1181
req, FAKE_UUID, body)
1183
def test_update_server_access_ipv6(self):
1184
self.stubs.Set(nova.db, 'instance_get',
1185
return_server_with_attributes(access_ipv6='beef::0123'))
1186
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
1188
req.content_type = 'application/json'
1189
body = {'server': {'accessIPv6': 'beef::0123'}}
1190
req.body = json.dumps(body)
1191
res_dict = self.controller.update(req, FAKE_UUID, body)
1193
self.assertEqual(res_dict['server']['id'], FAKE_UUID)
1194
self.assertEqual(res_dict['server']['accessIPv6'], 'beef::0123')
1196
def test_update_server_access_ipv6_bad_format(self):
1197
self.stubs.Set(nova.db, 'instance_get',
1198
return_server_with_attributes(access_ipv6='beef::0123'))
1199
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
1201
req.content_type = 'application/json'
1202
body = {'server': {'accessIPv6': 'bad_format'}}
1203
req.body = json.dumps(body)
1204
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
1205
req, FAKE_UUID, body)
1207
def test_update_server_adminPass_ignored(self):
1208
inst_dict = dict(name='server_test', adminPass='bacon')
1209
body = dict(server=inst_dict)
1211
def server_update(context, id, params):
1213
'display_name': 'server_test',
1215
self.assertEqual(params, filtered_dict)
1216
return filtered_dict
1218
self.stubs.Set(nova.db, 'instance_update', server_update)
1219
self.stubs.Set(nova.db, 'instance_get',
1220
return_server_with_attributes(name='server_test'))
1222
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
1224
req.content_type = "application/json"
1225
req.body = json.dumps(body)
1226
res_dict = self.controller.update(req, FAKE_UUID, body)
1228
self.assertEqual(res_dict['server']['id'], FAKE_UUID)
1229
self.assertEqual(res_dict['server']['name'], 'server_test')
1231
def test_rebuild_instance_with_access_ipv4_bad_format(self):
1233
def fake_get_instance(*args, **kwargs):
1234
return fakes.stub_instance(1, vm_state=vm_states.ACTIVE)
1236
self.stubs.Set(nova.db, 'instance_get', fake_get_instance)
1237
# proper local hrefs must start with 'http://localhost/v2/'
1238
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
1239
image_href = 'http://localhost/v2/fake/images/%s' % image_uuid
1240
access_ipv4 = 'bad_format'
1241
access_ipv6 = 'fead::1234'
1245
'imageRef': image_href,
1246
'accessIPv4': access_ipv4,
1247
'accessIPv6': access_ipv6,
1254
"path": "/etc/banner.txt",
1261
req = fakes.HTTPRequest.blank('/v2/fake/servers/a/action')
1263
req.body = json.dumps(body)
1264
req.headers["content-type"] = "application/json"
1265
self.assertRaises(webob.exc.HTTPBadRequest,
1266
self.controller._action_rebuild, req, 1, body)
1268
def test_rebuild_instance_with_access_ipv6_bad_format(self):
1270
def fake_get_instance(*args, **kwargs):
1271
return fakes.stub_instance(1, vm_state=vm_states.ACTIVE)
1273
self.stubs.Set(nova.db, 'instance_get', fake_get_instance)
1274
# proper local hrefs must start with 'http://localhost/v2/'
1275
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
1276
image_href = 'http://localhost/v2/fake/images/%s' % image_uuid
1277
access_ipv4 = '1.2.3.4'
1278
access_ipv6 = 'bad_format'
1282
'imageRef': image_href,
1283
'accessIPv4': access_ipv4,
1284
'accessIPv6': access_ipv6,
1291
"path": "/etc/banner.txt",
1298
req = fakes.HTTPRequest.blank('/v2/fake/servers/a/action')
1300
req.body = json.dumps(body)
1301
req.headers["content-type"] = "application/json"
1302
self.assertRaises(webob.exc.HTTPBadRequest,
1303
self.controller._action_rebuild, req, 1, body)
1305
def test_get_all_server_details(self):
1311
"href": 'http://localhost/fake/flavors/1',
1320
"href": 'http://localhost/fake/images/10',
1324
req = fakes.HTTPRequest.blank('/v2/fake/servers/detail')
1325
res_dict = self.controller.detail(req)
1327
for i, s in enumerate(res_dict['servers']):
1328
self.assertEqual(s['id'], get_fake_uuid(i))
1329
self.assertEqual(s['hostId'], '')
1330
self.assertEqual(s['name'], 'server%d' % i)
1331
self.assertEqual(s['image'], expected_image)
1332
self.assertEqual(s['flavor'], expected_flavor)
1333
self.assertEqual(s['status'], 'BUILD')
1334
self.assertEqual(s['metadata']['seq'], str(i))
1336
def test_get_all_server_details_with_host(self):
1338
We want to make sure that if two instances are on the same host, then
1339
they return the same hostId. If two instances are on different hosts,
1340
they should return different hostId's. In this test, there are 5
1341
instances - 2 on one host and 3 on another.
1344
def return_servers_with_host(context, *args, **kwargs):
1345
return [fakes.stub_instance(i, 'fake', 'fake', i % 2,
1346
uuid=get_fake_uuid(i))
1349
self.stubs.Set(nova.db, 'instance_get_all_by_filters',
1350
return_servers_with_host)
1352
req = fakes.HTTPRequest.blank('/v2/fake/servers/detail')
1353
res_dict = self.controller.detail(req)
1355
server_list = res_dict['servers']
1356
host_ids = [server_list[0]['hostId'], server_list[1]['hostId']]
1357
self.assertTrue(host_ids[0] and host_ids[1])
1358
self.assertNotEqual(host_ids[0], host_ids[1])
1360
for i, s in enumerate(server_list):
1361
self.assertEqual(s['id'], get_fake_uuid(i))
1362
self.assertEqual(s['hostId'], host_ids[i % 2])
1363
self.assertEqual(s['name'], 'server%d' % i)
1365
def test_delete_server_instance(self):
1366
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
1367
req.method = 'DELETE'
1369
self.server_delete_called = False
1371
new_return_server = return_server_with_attributes(
1372
vm_state=vm_states.ACTIVE)
1373
self.stubs.Set(nova.db, 'instance_get', new_return_server)
1375
def instance_destroy_mock(context, id):
1376
self.server_delete_called = True
1377
self.stubs.Set(nova.db, 'instance_destroy', instance_destroy_mock)
1379
self.controller.delete(req, FAKE_UUID)
1381
self.assertEqual(self.server_delete_called, True)
1383
def test_delete_server_instance_while_building(self):
1384
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
1385
req.method = 'DELETE'
1387
self.server_delete_called = False
1389
new_return_server = return_server_with_attributes(
1390
vm_state=vm_states.BUILDING)
1391
self.stubs.Set(nova.db, 'instance_get', new_return_server)
1393
def instance_destroy_mock(context, id):
1394
self.server_delete_called = True
1395
self.stubs.Set(nova.db, 'instance_destroy', instance_destroy_mock)
1397
self.controller.delete(req, FAKE_UUID)
1399
self.assertEqual(self.server_delete_called, True)
1401
def test_delete_server_instance_while_resize(self):
1402
req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
1403
req.method = 'DELETE'
1405
self.server_delete_called = False
1407
new_return_server = return_server_with_attributes(
1408
vm_state=vm_states.RESIZING)
1409
self.stubs.Set(nova.db, 'instance_get', new_return_server)
1411
def instance_destroy_mock(context, id):
1412
self.server_delete_called = True
1413
self.stubs.Set(nova.db, 'instance_destroy', instance_destroy_mock)
1415
self.assertRaises(webob.exc.HTTPConflict,
1416
self.controller.delete,
1421
class ServerStatusTest(test.TestCase):
1424
super(ServerStatusTest, self).setUp()
1425
fakes.stub_out_nw_api(self.stubs)
1427
self.controller = servers.Controller()
1429
def _get_with_state(self, vm_state, task_state=None):
1430
new_server = return_server_with_state(vm_state, task_state)
1431
self.stubs.Set(nova.db, 'instance_get_by_uuid', new_server)
1432
self.stubs.Set(nova.db, 'instance_get', new_server)
1434
request = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
1435
return self.controller.show(request, FAKE_UUID)
1437
def test_active(self):
1438
response = self._get_with_state(vm_states.ACTIVE)
1439
self.assertEqual(response['server']['status'], 'ACTIVE')
1441
def test_reboot(self):
1442
response = self._get_with_state(vm_states.ACTIVE,
1443
task_states.REBOOTING)
1444
self.assertEqual(response['server']['status'], 'REBOOT')
1446
def test_reboot_hard(self):
1447
response = self._get_with_state(vm_states.ACTIVE,
1448
task_states.REBOOTING_HARD)
1449
self.assertEqual(response['server']['status'], 'HARD_REBOOT')
1451
def test_rebuild(self):
1452
response = self._get_with_state(vm_states.REBUILDING)
1453
self.assertEqual(response['server']['status'], 'REBUILD')
1455
def test_rebuild_error(self):
1456
response = self._get_with_state(vm_states.ERROR)
1457
self.assertEqual(response['server']['status'], 'ERROR')
1459
def test_resize(self):
1460
response = self._get_with_state(vm_states.RESIZING)
1461
self.assertEqual(response['server']['status'], 'RESIZE')
1463
def test_verify_resize(self):
1464
response = self._get_with_state(vm_states.ACTIVE,
1465
task_states.RESIZE_VERIFY)
1466
self.assertEqual(response['server']['status'], 'VERIFY_RESIZE')
1468
def test_password_update(self):
1469
response = self._get_with_state(vm_states.ACTIVE,
1470
task_states.UPDATING_PASSWORD)
1471
self.assertEqual(response['server']['status'], 'PASSWORD')
1473
def test_stopped(self):
1474
response = self._get_with_state(vm_states.STOPPED)
1475
self.assertEqual(response['server']['status'], 'STOPPED')
1478
class ServersControllerCreateTest(test.TestCase):
1481
"""Shared implementation for tests below that create instance"""
1482
super(ServersControllerCreateTest, self).setUp()
1485
self.flags(verbose=True)
1486
self.config_drive = None
1487
self.instance_cache_num = 0
1488
self.instance_cache = {}
1490
self.controller = servers.Controller()
1492
def instance_create(context, inst):
1493
inst_type = instance_types.get_instance_type_by_flavor_id(3)
1494
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
1495
def_image_ref = 'http://localhost/images/%s' % image_uuid
1496
self.instance_cache_num += 1
1498
'id': self.instance_cache_num,
1499
'display_name': inst['display_name'] or 'test',
1501
'instance_type': dict(inst_type),
1502
'access_ip_v4': '1.2.3.4',
1503
'access_ip_v6': 'fead::1234',
1504
'image_ref': inst.get('image_ref', def_image_ref),
1506
'project_id': 'fake',
1507
'reservation_id': inst['reservation_id'],
1508
"created_at": datetime.datetime(2010, 10, 10, 12, 0, 0),
1509
"updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0),
1510
"config_drive": self.config_drive,
1514
self.instance_cache[instance['id']] = instance
1517
def instance_get(context, instance_id):
1518
"""Stub for compute/api create() pulling in instance after
1521
return self.instance_cache[instance_id]
1523
def rpc_call_wrapper(context, topic, msg):
1524
"""Stub out the scheduler creating the instance entry"""
1525
if topic == FLAGS.scheduler_topic and \
1526
msg['method'] == 'run_instance':
1527
request_spec = msg['args']['request_spec']
1528
num_instances = request_spec.get('num_instances', 1)
1530
for x in xrange(num_instances):
1531
instances.append(instance_create(context,
1532
request_spec['instance_properties']))
1535
def server_update(context, instance_id, params):
1536
inst = self.instance_cache[instance_id]
1540
def fake_method(*args, **kwargs):
1543
def project_get_networks(context, user_id):
1544
return dict(id='1', host='localhost')
1546
def queue_get_for(context, *args):
1547
return 'network_topic'
1549
fakes.stub_out_networking(self.stubs)
1550
fakes.stub_out_rate_limiting(self.stubs)
1551
fakes.stub_out_key_pair_funcs(self.stubs)
1552
fakes.stub_out_image_service(self.stubs)
1553
fakes.stub_out_nw_api(self.stubs)
1554
self.stubs.Set(utils, 'gen_uuid', fake_gen_uuid)
1555
self.stubs.Set(nova.db, 'instance_add_security_group',
1556
return_security_group)
1557
self.stubs.Set(nova.db, 'project_get_networks',
1558
project_get_networks)
1559
self.stubs.Set(nova.db, 'instance_create', instance_create)
1560
self.stubs.Set(nova.db, 'instance_get', instance_get)
1561
self.stubs.Set(nova.rpc, 'cast', fake_method)
1562
self.stubs.Set(nova.rpc, 'call', rpc_call_wrapper)
1563
self.stubs.Set(nova.db, 'instance_update', server_update)
1564
self.stubs.Set(nova.db, 'queue_get_for', queue_get_for)
1565
self.stubs.Set(nova.network.manager.VlanManager, 'allocate_fixed_ip',
1567
self.stubs.Set(nova.compute.api.API, "_find_host", find_host)
1569
def _test_create_instance(self):
1570
image_uuid = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
1571
body = dict(server=dict(
1572
name='server_test', imageRef=image_uuid, flavorRef=2,
1573
metadata={'hello': 'world', 'open': 'stack'},
1575
req = fakes.HTTPRequest.blank('/v2/fake/servers')
1577
req.body = json.dumps(body)
1578
req.headers["content-type"] = "application/json"
1579
server = self.controller.create(req, body).obj['server']
1581
self.assertEqual(FLAGS.password_length, len(server['adminPass']))
1582
self.assertEqual(FAKE_UUID, server['id'])
1584
def test_create_multiple_instances(self):
1585
"""Test creating multiple instances but not asking for
1588
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
1589
flavor_ref = 'http://localhost/123/flavors/3'
1593
'name': 'server_test',
1594
'imageRef': image_href,
1595
'flavorRef': flavor_ref,
1596
'metadata': {'hello': 'world',
1602
req = fakes.HTTPRequest.blank('/v2/fake/servers')
1604
req.body = json.dumps(body)
1605
req.headers["content-type"] = "application/json"
1606
res = self.controller.create(req, body).obj
1608
self.assertEqual(FAKE_UUID, res["server"]["id"])
1609
self.assertEqual(12, len(res["server"]["adminPass"]))
1611
def test_create_multiple_instances_resv_id_return(self):
1612
"""Test creating multiple instances with asking for
1615
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
1616
flavor_ref = 'http://localhost/123/flavors/3'
1620
'name': 'server_test',
1621
'imageRef': image_href,
1622
'flavorRef': flavor_ref,
1623
'metadata': {'hello': 'world',
1626
'return_reservation_id': True
1630
req = fakes.HTTPRequest.blank('/v2/fake/servers')
1632
req.body = json.dumps(body)
1633
req.headers["content-type"] = "application/json"
1634
res = self.controller.create(req, body)
1636
reservation_id = res.get('reservation_id')
1637
self.assertNotEqual(reservation_id, "")
1638
self.assertNotEqual(reservation_id, None)
1639
self.assertTrue(len(reservation_id) > 1)
1641
def test_create_instance_with_user_supplied_reservation_id(self):
1642
"""Non-admin supplied reservation_id should be ignored."""
1643
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
1644
flavor_ref = 'http://localhost/123/flavors/3'
1647
'name': 'server_test',
1648
'imageRef': image_href,
1649
'flavorRef': flavor_ref,
1650
'metadata': {'hello': 'world',
1653
'reservation_id': 'myresid',
1654
'return_reservation_id': True
1658
req = fakes.HTTPRequest.blank('/v2/fake/servers')
1660
req.body = json.dumps(body)
1661
req.headers["content-type"] = "application/json"
1662
res = self.controller.create(req, body)
1664
self.assertIn('reservation_id', res)
1665
self.assertNotEqual(res['reservation_id'], 'myresid')
1667
def test_create_instance_with_admin_supplied_reservation_id(self):
1668
"""Admin supplied reservation_id should be honored."""
1669
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
1670
flavor_ref = 'http://localhost/123/flavors/3'
1673
'name': 'server_test',
1674
'imageRef': image_href,
1675
'flavorRef': flavor_ref,
1676
'metadata': {'hello': 'world',
1679
'reservation_id': 'myresid',
1680
'return_reservation_id': True
1684
req = fakes.HTTPRequest.blank('/v2/fake/servers',
1685
use_admin_context=True)
1687
req.body = json.dumps(body)
1688
req.headers["content-type"] = "application/json"
1689
res = self.controller.create(req, body)
1691
reservation_id = res['reservation_id']
1692
self.assertEqual(reservation_id, "myresid")
1694
def test_create_instance_no_key_pair(self):
1695
fakes.stub_out_key_pair_funcs(self.stubs, have_key_pair=False)
1696
self._test_create_instance()
1698
def test_create_instance_with_access_ip(self):
1699
# proper local hrefs must start with 'http://localhost/v2/'
1700
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
1701
image_href = 'http://localhost/v2/fake/images/%s' % image_uuid
1702
flavor_ref = 'http://localhost/fake/flavors/3'
1703
access_ipv4 = '1.2.3.4'
1704
access_ipv6 = 'fead::1234'
1707
'name': 'server_test',
1708
'imageRef': image_href,
1709
'flavorRef': flavor_ref,
1710
'accessIPv4': access_ipv4,
1711
'accessIPv6': access_ipv6,
1718
"path": "/etc/banner.txt",
1725
req = fakes.HTTPRequest.blank('/v2/fake/servers')
1727
req.body = json.dumps(body)
1728
req.headers["content-type"] = "application/json"
1729
res = self.controller.create(req, body).obj
1731
server = res['server']
1732
self.assertEqual(FLAGS.password_length, len(server['adminPass']))
1733
self.assertEqual(FAKE_UUID, server['id'])
1735
def test_create_instance_bad_format_access_ip_v4(self):
1736
# proper local hrefs must start with 'http://localhost/v2/'
1737
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
1738
image_href = 'http://localhost/v2/fake/images/%s' % image_uuid
1739
flavor_ref = 'http://localhost/fake/flavors/3'
1740
access_ipv4 = 'bad_format'
1741
access_ipv6 = 'fead::1234'
1744
'name': 'server_test',
1745
'imageRef': image_href,
1746
'flavorRef': flavor_ref,
1747
'accessIPv4': access_ipv4,
1748
'accessIPv6': access_ipv6,
1755
"path": "/etc/banner.txt",
1762
req = fakes.HTTPRequest.blank('/v2/fake/servers')
1764
req.body = json.dumps(body)
1765
req.headers["content-type"] = "application/json"
1766
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
1769
def test_create_instance_bad_format_access_ip_v6(self):
1770
# proper local hrefs must start with 'http://localhost/v2/'
1771
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
1772
image_href = 'http://localhost/v2/fake/images/%s' % image_uuid
1773
flavor_ref = 'http://localhost/fake/flavors/3'
1774
access_ipv4 = '1.2.3.4'
1775
access_ipv6 = 'bad_format'
1778
'name': 'server_test',
1779
'imageRef': image_href,
1780
'flavorRef': flavor_ref,
1781
'accessIPv4': access_ipv4,
1782
'accessIPv6': access_ipv6,
1789
"path": "/etc/banner.txt",
1796
req = fakes.HTTPRequest.blank('/v2/fake/servers')
1798
req.body = json.dumps(body)
1799
req.headers["content-type"] = "application/json"
1800
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
1803
def test_create_instance(self):
1804
# proper local hrefs must start with 'http://localhost/v2/'
1805
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
1806
image_href = 'http://localhost/v2/images/%s' % image_uuid
1807
flavor_ref = 'http://localhost/123/flavors/3'
1810
'name': 'server_test',
1811
'imageRef': image_href,
1812
'flavorRef': flavor_ref,
1819
"path": "/etc/banner.txt",
1826
req = fakes.HTTPRequest.blank('/v2/fake/servers')
1828
req.body = json.dumps(body)
1829
req.headers["content-type"] = "application/json"
1830
res = self.controller.create(req, body).obj
1832
server = res['server']
1833
self.assertEqual(FLAGS.password_length, len(server['adminPass']))
1834
self.assertEqual(FAKE_UUID, server['id'])
1836
def test_create_instance_too_much_metadata(self):
1837
self.flags(quota_metadata_items=1)
1838
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
1839
image_href = 'http://localhost/v2/images/%s' % image_uuid
1840
flavor_ref = 'http://localhost/123/flavors/3'
1843
'name': 'server_test',
1844
'imageRef': image_href,
1845
'flavorRef': flavor_ref,
1849
'vote': 'fiddletown',
1854
req = fakes.HTTPRequest.blank('/v2/fake/servers')
1856
req.body = json.dumps(body)
1857
req.headers["content-type"] = "application/json"
1859
self.assertRaises(webob.exc.HTTPRequestEntityTooLarge,
1860
self.controller.create, req, body)
1862
def test_create_instance_invalid_key_name(self):
1863
image_href = 'http://localhost/v2/images/2'
1864
flavor_ref = 'http://localhost/flavors/3'
1865
body = dict(server=dict(
1866
name='server_test', imageRef=image_href, flavorRef=flavor_ref,
1867
key_name='nonexistentkey'))
1868
req = fakes.HTTPRequest.blank('/v2/fake/servers')
1870
req.body = json.dumps(body)
1871
req.headers["content-type"] = "application/json"
1873
self.assertRaises(webob.exc.HTTPBadRequest,
1874
self.controller.create, req, body)
1876
def test_create_instance_valid_key_name(self):
1877
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
1878
flavor_ref = 'http://localhost/flavors/3'
1879
body = dict(server=dict(
1880
name='server_test', imageRef=image_href, flavorRef=flavor_ref,
1882
req = fakes.HTTPRequest.blank('/v2/fake/servers')
1884
req.body = json.dumps(body)
1885
req.headers["content-type"] = "application/json"
1886
res = self.controller.create(req, body).obj
1888
self.assertEqual(FAKE_UUID, res["server"]["id"])
1889
self.assertEqual(12, len(res["server"]["adminPass"]))
1891
def test_create_instance_invalid_flavor_href(self):
1892
image_href = 'http://localhost/v2/images/2'
1893
flavor_ref = 'http://localhost/v2/flavors/asdf'
1894
body = dict(server=dict(
1895
name='server_test', imageRef=image_href, flavorRef=flavor_ref,
1896
metadata={'hello': 'world', 'open': 'stack'},
1898
req = fakes.HTTPRequest.blank('/v2/fake/servers')
1900
req.body = json.dumps(body)
1901
req.headers["content-type"] = "application/json"
1903
self.assertRaises(webob.exc.HTTPBadRequest,
1904
self.controller.create, req, body)
1906
def test_create_instance_invalid_flavor_id_int(self):
1907
image_href = 'http://localhost/v2/fake/images/2'
1909
body = dict(server=dict(
1910
name='server_test', imageRef=image_href, flavorRef=flavor_ref,
1911
metadata={'hello': 'world', 'open': 'stack'},
1913
req = fakes.HTTPRequest.blank('/v2/fake/servers')
1915
req.body = json.dumps(body)
1916
req.headers["content-type"] = "application/json"
1918
self.assertRaises(webob.exc.HTTPBadRequest,
1919
self.controller.create, req, body)
1921
def test_create_instance_bad_flavor_href(self):
1922
image_href = 'http://localhost/v2/images/2'
1923
flavor_ref = 'http://localhost/v2/flavors/17'
1924
body = dict(server=dict(
1925
name='server_test', imageRef=image_href, flavorRef=flavor_ref,
1926
metadata={'hello': 'world', 'open': 'stack'},
1928
req = fakes.HTTPRequest.blank('/v2/fake/servers')
1930
req.body = json.dumps(body)
1931
req.headers["content-type"] = "application/json"
1933
self.assertRaises(webob.exc.HTTPBadRequest,
1934
self.controller.create, req, body)
1936
def test_create_instance_with_config_drive(self):
1937
self.config_drive = True
1938
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
1939
flavor_ref = 'http://localhost/v2/fake/flavors/3'
1942
'name': 'config_drive_test',
1943
'imageRef': image_href,
1944
'flavorRef': flavor_ref,
1950
'config_drive': True,
1954
req = fakes.HTTPRequest.blank('/v2/fake/servers')
1956
req.body = json.dumps(body)
1957
req.headers["content-type"] = "application/json"
1958
res = self.controller.create(req, body).obj
1960
server = res['server']
1961
self.assertEqual(FAKE_UUID, server['id'])
1963
def test_create_instance_with_config_drive_as_id(self):
1964
self.config_drive = 2
1965
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
1966
flavor_ref = 'http://localhost/v2/fake/flavors/3'
1969
'name': 'config_drive_test',
1970
'imageRef': image_href,
1971
'flavorRef': flavor_ref,
1977
'config_drive': image_href,
1981
req = fakes.HTTPRequest.blank('/v2/fake/servers')
1983
req.body = json.dumps(body)
1984
req.headers["content-type"] = "application/json"
1985
res = self.controller.create(req, body).obj
1987
server = res['server']
1988
self.assertEqual(FAKE_UUID, server['id'])
1990
def test_create_instance_with_bad_config_drive(self):
1991
self.config_drive = "asdf"
1992
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
1993
flavor_ref = 'http://localhost/v2/fake/flavors/3'
1996
'name': 'config_drive_test',
1997
'imageRef': image_href,
1998
'flavorRef': flavor_ref,
2004
'config_drive': 'asdf',
2008
req = fakes.HTTPRequest.blank('/v2/fake/servers')
2010
req.body = json.dumps(body)
2011
req.headers["content-type"] = "application/json"
2013
self.assertRaises(webob.exc.HTTPBadRequest,
2014
self.controller.create, req, body)
2016
def test_create_instance_without_config_drive(self):
2017
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
2018
flavor_ref = 'http://localhost/v2/fake/flavors/3'
2021
'name': 'config_drive_test',
2022
'imageRef': image_href,
2023
'flavorRef': flavor_ref,
2029
'config_drive': True,
2033
req = fakes.HTTPRequest.blank('/v2/fake/servers')
2035
req.body = json.dumps(body)
2036
req.headers["content-type"] = "application/json"
2037
res = self.controller.create(req, body).obj
2039
server = res['server']
2040
self.assertEqual(FAKE_UUID, server['id'])
2042
def test_create_instance_bad_href(self):
2044
flavor_ref = 'http://localhost/v2/flavors/3'
2045
body = dict(server=dict(
2046
name='server_test', imageRef=image_href, flavorRef=flavor_ref,
2047
metadata={'hello': 'world', 'open': 'stack'},
2049
req = fakes.HTTPRequest.blank('/v2/fake/servers')
2051
req.body = json.dumps(body)
2052
req.headers["content-type"] = "application/json"
2054
self.assertRaises(webob.exc.HTTPBadRequest,
2055
self.controller.create, req, body)
2057
def test_create_instance_local_href(self):
2058
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
2059
flavor_ref = 'http://localhost/v2/flavors/3'
2062
'name': 'server_test',
2063
'imageRef': image_uuid,
2064
'flavorRef': flavor_ref,
2068
req = fakes.HTTPRequest.blank('/v2/fake/servers')
2070
req.body = json.dumps(body)
2071
req.headers["content-type"] = "application/json"
2072
res = self.controller.create(req, body).obj
2074
server = res['server']
2075
self.assertEqual(FAKE_UUID, server['id'])
2077
def test_create_instance_admin_pass(self):
2078
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
2081
'name': 'server_test',
2082
'imageRef': image_uuid,
2084
'adminPass': 'testpass',
2088
req = fakes.HTTPRequest.blank('/v2/fake/servers')
2090
req.body = json.dumps(body)
2091
req.headers['content-type'] = "application/json"
2092
res = self.controller.create(req, body).obj
2094
server = res['server']
2095
self.assertEqual(server['adminPass'], body['server']['adminPass'])
2097
def test_create_instance_admin_pass_empty(self):
2100
'name': 'server_test',
2107
req = fakes.HTTPRequest.blank('/v2/fake/servers')
2109
req.body = json.dumps(body)
2110
req.headers['content-type'] = "application/json"
2112
self.assertRaises(webob.exc.HTTPBadRequest,
2113
self.controller.create, req, body)
2115
def test_create_instance_malformed_entity(self):
2116
req = fakes.HTTPRequest.blank('/v2/fake/servers')
2118
body = {'server': 'string'}
2119
req.body = json.dumps(body)
2120
req.headers['content-type'] = "application/json"
2122
self.assertRaises(webob.exc.HTTPBadRequest,
2123
self.controller.create, req, body)
2125
def test_create_location(self):
2126
selfhref = 'http://localhost/v2/fake/servers/%s' % FAKE_UUID
2127
bookhref = 'http://localhost/fake/servers/%s' % FAKE_UUID
2128
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
2129
image_href = 'http://localhost/v2/images/%s' % image_uuid
2130
flavor_ref = 'http://localhost/123/flavors/3'
2133
'name': 'server_test',
2134
'imageRef': image_href,
2135
'flavorRef': flavor_ref,
2142
"path": "/etc/banner.txt",
2149
req = fakes.HTTPRequest.blank('/v2/fake/servers')
2151
req.body = json.dumps(body)
2152
req.headers['content-type'] = 'application/json'
2153
robj = self.controller.create(req, body)
2155
self.assertEqual(robj['Location'], selfhref)
2158
class TestServerCreateRequestXMLDeserializer(test.TestCase):
2161
super(TestServerCreateRequestXMLDeserializer, self).setUp()
2162
self.deserializer = servers.CreateDeserializer()
2164
def test_minimal_request(self):
2165
serial_request = """
2166
<server xmlns="http://docs.openstack.org/compute/api/v2"
2167
name="new-server-test"
2170
request = self.deserializer.deserialize(serial_request)
2173
"name": "new-server-test",
2178
self.assertEquals(request['body'], expected)
2180
def test_access_ipv4(self):
2181
serial_request = """
2182
<server xmlns="http://docs.openstack.org/compute/api/v2"
2183
name="new-server-test"
2186
accessIPv4="1.2.3.4"/>"""
2187
request = self.deserializer.deserialize(serial_request)
2190
"name": "new-server-test",
2193
"accessIPv4": "1.2.3.4",
2196
self.assertEquals(request['body'], expected)
2198
def test_access_ipv6(self):
2199
serial_request = """
2200
<server xmlns="http://docs.openstack.org/compute/api/v2"
2201
name="new-server-test"
2204
accessIPv6="fead::1234"/>"""
2205
request = self.deserializer.deserialize(serial_request)
2208
"name": "new-server-test",
2211
"accessIPv6": "fead::1234",
2214
self.assertEquals(request['body'], expected)
2216
def test_access_ip(self):
2217
serial_request = """
2218
<server xmlns="http://docs.openstack.org/compute/api/v2"
2219
name="new-server-test"
2222
accessIPv4="1.2.3.4"
2223
accessIPv6="fead::1234"/>"""
2224
request = self.deserializer.deserialize(serial_request)
2227
"name": "new-server-test",
2230
"accessIPv4": "1.2.3.4",
2231
"accessIPv6": "fead::1234",
2234
self.assertEquals(request['body'], expected)
2236
def test_admin_pass(self):
2237
serial_request = """
2238
<server xmlns="http://docs.openstack.org/compute/api/v2"
2239
name="new-server-test"
2242
adminPass="1234"/>"""
2243
request = self.deserializer.deserialize(serial_request)
2246
"name": "new-server-test",
2249
"adminPass": "1234",
2252
self.assertEquals(request['body'], expected)
2254
def test_image_link(self):
2255
serial_request = """
2256
<server xmlns="http://docs.openstack.org/compute/api/v2"
2257
name="new-server-test"
2258
imageRef="http://localhost:8774/v2/images/2"
2260
request = self.deserializer.deserialize(serial_request)
2263
"name": "new-server-test",
2264
"imageRef": "http://localhost:8774/v2/images/2",
2268
self.assertEquals(request['body'], expected)
2270
def test_flavor_link(self):
2271
serial_request = """
2272
<server xmlns="http://docs.openstack.org/compute/api/v2"
2273
name="new-server-test"
2275
flavorRef="http://localhost:8774/v2/flavors/3"/>"""
2276
request = self.deserializer.deserialize(serial_request)
2279
"name": "new-server-test",
2281
"flavorRef": "http://localhost:8774/v2/flavors/3",
2284
self.assertEquals(request['body'], expected)
2286
def test_empty_metadata_personality(self):
2287
serial_request = """
2288
<server xmlns="http://docs.openstack.org/compute/api/v2"
2289
name="new-server-test"
2295
request = self.deserializer.deserialize(serial_request)
2298
"name": "new-server-test",
2305
self.assertEquals(request['body'], expected)
2307
def test_multiple_metadata_items(self):
2308
serial_request = """
2309
<server xmlns="http://docs.openstack.org/compute/api/v2"
2310
name="new-server-test"
2314
<meta key="one">two</meta>
2315
<meta key="open">snack</meta>
2318
request = self.deserializer.deserialize(serial_request)
2321
"name": "new-server-test",
2324
"metadata": {"one": "two", "open": "snack"},
2327
self.assertEquals(request['body'], expected)
2329
def test_multiple_personality_files(self):
2330
serial_request = """
2331
<server xmlns="http://docs.openstack.org/compute/api/v2"
2332
name="new-server-test"
2336
<file path="/etc/banner.txt">MQ==</file>
2337
<file path="/etc/hosts">Mg==</file>
2340
request = self.deserializer.deserialize(serial_request)
2343
"name": "new-server-test",
2347
{"path": "/etc/banner.txt", "contents": "MQ=="},
2348
{"path": "/etc/hosts", "contents": "Mg=="},
2352
self.assertDictMatch(request['body'], expected)
2354
def test_spec_request(self):
2355
image_bookmark_link = "http://servers.api.openstack.org/1234/" + \
2356
"images/52415800-8b69-11e0-9b19-734f6f006e54"
2357
serial_request = """
2358
<server xmlns="http://docs.openstack.org/compute/api/v2"
2360
flavorRef="52415800-8b69-11e0-9b19-734f1195ff37"
2361
name="new-server-test">
2363
<meta key="My Server Name">Apache1</meta>
2366
<file path="/etc/banner.txt">Mg==</file>
2368
</server>""" % (image_bookmark_link)
2369
request = self.deserializer.deserialize(serial_request)
2372
"name": "new-server-test",
2373
"imageRef": "http://servers.api.openstack.org/1234/" + \
2374
"images/52415800-8b69-11e0-9b19-734f6f006e54",
2375
"flavorRef": "52415800-8b69-11e0-9b19-734f1195ff37",
2376
"metadata": {"My Server Name": "Apache1"},
2379
"path": "/etc/banner.txt",
2385
self.assertEquals(request['body'], expected)
2387
def test_request_with_empty_networks(self):
2388
serial_request = """
2389
<server xmlns="http://docs.openstack.org/compute/api/v2"
2390
name="new-server-test" imageRef="1" flavorRef="1">
2393
request = self.deserializer.deserialize(serial_request)
2394
expected = {"server": {
2395
"name": "new-server-test",
2400
self.assertEquals(request['body'], expected)
2402
def test_request_with_one_network(self):
2403
serial_request = """
2404
<server xmlns="http://docs.openstack.org/compute/api/v2"
2405
name="new-server-test" imageRef="1" flavorRef="1">
2407
<network uuid="1" fixed_ip="10.0.1.12"/>
2410
request = self.deserializer.deserialize(serial_request)
2411
expected = {"server": {
2412
"name": "new-server-test",
2415
"networks": [{"uuid": "1", "fixed_ip": "10.0.1.12"}],
2417
self.assertEquals(request['body'], expected)
2419
def test_request_with_two_networks(self):
2420
serial_request = """
2421
<server xmlns="http://docs.openstack.org/compute/api/v2"
2422
name="new-server-test" imageRef="1" flavorRef="1">
2424
<network uuid="1" fixed_ip="10.0.1.12"/>
2425
<network uuid="2" fixed_ip="10.0.2.12"/>
2428
request = self.deserializer.deserialize(serial_request)
2429
expected = {"server": {
2430
"name": "new-server-test",
2433
"networks": [{"uuid": "1", "fixed_ip": "10.0.1.12"},
2434
{"uuid": "2", "fixed_ip": "10.0.2.12"}],
2436
self.assertEquals(request['body'], expected)
2438
def test_request_with_second_network_node_ignored(self):
2439
serial_request = """
2440
<server xmlns="http://docs.openstack.org/compute/api/v2"
2441
name="new-server-test" imageRef="1" flavorRef="1">
2443
<network uuid="1" fixed_ip="10.0.1.12"/>
2446
<network uuid="2" fixed_ip="10.0.2.12"/>
2449
request = self.deserializer.deserialize(serial_request)
2450
expected = {"server": {
2451
"name": "new-server-test",
2454
"networks": [{"uuid": "1", "fixed_ip": "10.0.1.12"}],
2456
self.assertEquals(request['body'], expected)
2458
def test_request_with_one_network_missing_id(self):
2459
serial_request = """
2460
<server xmlns="http://docs.openstack.org/compute/api/v2"
2461
name="new-server-test" imageRef="1" flavorRef="1">
2463
<network fixed_ip="10.0.1.12"/>
2466
request = self.deserializer.deserialize(serial_request)
2467
expected = {"server": {
2468
"name": "new-server-test",
2471
"networks": [{"fixed_ip": "10.0.1.12"}],
2473
self.assertEquals(request['body'], expected)
2475
def test_request_with_one_network_missing_fixed_ip(self):
2476
serial_request = """
2477
<server xmlns="http://docs.openstack.org/compute/api/v2"
2478
name="new-server-test" imageRef="1" flavorRef="1">
2483
request = self.deserializer.deserialize(serial_request)
2484
expected = {"server": {
2485
"name": "new-server-test",
2488
"networks": [{"uuid": "1"}],
2490
self.assertEquals(request['body'], expected)
2492
def test_request_with_one_network_empty_id(self):
2493
serial_request = """
2494
<server xmlns="http://docs.openstack.org/compute/api/v2"
2495
name="new-server-test" imageRef="1" flavorRef="1">
2497
<network uuid="" fixed_ip="10.0.1.12"/>
2500
request = self.deserializer.deserialize(serial_request)
2501
expected = {"server": {
2502
"name": "new-server-test",
2505
"networks": [{"uuid": "", "fixed_ip": "10.0.1.12"}],
2507
self.assertEquals(request['body'], expected)
2509
def test_request_with_one_network_empty_fixed_ip(self):
2510
serial_request = """
2511
<server xmlns="http://docs.openstack.org/compute/api/v2"
2512
name="new-server-test" imageRef="1" flavorRef="1">
2514
<network uuid="1" fixed_ip=""/>
2517
request = self.deserializer.deserialize(serial_request)
2518
expected = {"server": {
2519
"name": "new-server-test",
2522
"networks": [{"uuid": "1", "fixed_ip": ""}],
2524
self.assertEquals(request['body'], expected)
2526
def test_request_with_networks_duplicate_ids(self):
2527
serial_request = """
2528
<server xmlns="http://docs.openstack.org/compute/api/v2"
2529
name="new-server-test" imageRef="1" flavorRef="1">
2531
<network uuid="1" fixed_ip="10.0.1.12"/>
2532
<network uuid="1" fixed_ip="10.0.2.12"/>
2535
request = self.deserializer.deserialize(serial_request)
2536
expected = {"server": {
2537
"name": "new-server-test",
2540
"networks": [{"uuid": "1", "fixed_ip": "10.0.1.12"},
2541
{"uuid": "1", "fixed_ip": "10.0.2.12"}],
2543
self.assertEquals(request['body'], expected)
2546
class TestAddressesXMLSerialization(test.TestCase):
2548
index_serializer = nova.api.openstack.compute.ips.AddressesTemplate()
2549
show_serializer = nova.api.openstack.compute.ips.NetworkTemplate()
2551
def test_xml_declaration(self):
2554
{'addr': '192.168.0.1', 'version': 4},
2555
{'addr': 'fe80::beef', 'version': 6},
2558
output = self.show_serializer.serialize(fixture)
2559
has_dec = output.startswith("<?xml version='1.0' encoding='UTF-8'?>")
2560
self.assertTrue(has_dec)
2562
def test_show(self):
2565
{'addr': '192.168.0.1', 'version': 4},
2566
{'addr': 'fe80::beef', 'version': 6},
2569
output = self.show_serializer.serialize(fixture)
2570
root = etree.XML(output)
2571
network = fixture['network_2']
2572
self.assertEqual(str(root.get('id')), 'network_2')
2573
ip_elems = root.findall('{0}ip'.format(NS))
2574
for z, ip_elem in enumerate(ip_elems):
2576
self.assertEqual(str(ip_elem.get('version')),
2578
self.assertEqual(str(ip_elem.get('addr')),
2581
def test_index(self):
2585
{'addr': '192.168.0.3', 'version': 4},
2586
{'addr': '192.168.0.5', 'version': 4},
2589
{'addr': '192.168.0.1', 'version': 4},
2590
{'addr': 'fe80::beef', 'version': 6},
2594
output = self.index_serializer.serialize(fixture)
2595
root = etree.XML(output)
2596
xmlutil.validate_schema(root, 'addresses')
2597
addresses_dict = fixture['addresses']
2598
network_elems = root.findall('{0}network'.format(NS))
2599
self.assertEqual(len(network_elems), 2)
2600
for i, network_elem in enumerate(network_elems):
2601
network = addresses_dict.items()[i]
2602
self.assertEqual(str(network_elem.get('id')), str(network[0]))
2603
ip_elems = network_elem.findall('{0}ip'.format(NS))
2604
for z, ip_elem in enumerate(ip_elems):
2606
self.assertEqual(str(ip_elem.get('version')),
2608
self.assertEqual(str(ip_elem.get('addr')),
2612
class ServersViewBuilderTest(test.TestCase):
2615
super(ServersViewBuilderTest, self).setUp()
2616
self.flags(use_ipv6=True)
2617
self.instance = fakes.stub_instance(
2620
uuid="deadbeef-feed-edee-beef-d0ea7beefedd",
2621
display_name="test_server",
2622
include_fake_metadata=False)
2624
privates = ['172.19.0.1']
2625
publics = ['192.168.0.3']
2626
public6s = ['b33f::fdee:ddff:fecc:bbaa']
2628
def nw_info(*args, **kwargs):
2629
return [(None, {'label': 'public',
2630
'ips': [dict(ip=ip) for ip in publics],
2631
'ip6s': [dict(ip=ip) for ip in public6s]}),
2632
(None, {'label': 'private',
2633
'ips': [dict(ip=ip) for ip in privates]})]
2635
def floaters(*args, **kwargs):
2638
fakes.stub_out_nw_api_get_instance_nw_info(self.stubs, nw_info)
2639
fakes.stub_out_nw_api_get_floating_ips_by_fixed_address(self.stubs,
2642
self.uuid = self.instance['uuid']
2643
self.view_builder = views.servers.ViewBuilder()
2644
self.request = fakes.HTTPRequest.blank("/v2")
2646
def test_build_server(self):
2647
self_link = "http://localhost/v2/fake/servers/%s" % self.uuid
2648
bookmark_link = "http://localhost/fake/servers/%s" % self.uuid
2652
"name": "test_server",
2660
"href": bookmark_link,
2666
output = self.view_builder.basic(self.request, self.instance)
2667
self.assertDictMatch(output, expected_server)
2669
def test_build_server_with_project_id(self):
2673
"name": "test_server",
2677
"href": "http://localhost/v2/fake/servers/%s" %
2682
"href": "http://localhost/fake/servers/%s" % self.uuid,
2688
output = self.view_builder.basic(self.request, self.instance)
2689
self.assertDictMatch(output, expected_server)
2691
def test_build_server_detail(self):
2692
image_bookmark = "http://localhost/fake/images/5"
2693
flavor_bookmark = "http://localhost/fake/flavors/1"
2694
self_link = "http://localhost/v2/fake/servers/%s" % self.uuid
2695
bookmark_link = "http://localhost/fake/servers/%s" % self.uuid
2700
"tenant_id": "fake",
2701
"updated": "2010-11-11T11:00:00Z",
2702
"created": "2010-10-10T12:00:00Z",
2704
"name": "test_server",
2715
"href": image_bookmark,
2724
"href": flavor_bookmark,
2730
{'version': 4, 'addr': '172.19.0.1'}
2733
{'version': 4, 'addr': '192.168.0.3'},
2734
{'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
2738
"config_drive": None,
2746
"href": bookmark_link,
2752
output = self.view_builder.show(self.request, self.instance)
2753
self.assertDictMatch(output, expected_server)
2755
def test_build_server_detail_with_fault(self):
2756
self.instance['vm_state'] = vm_states.ERROR
2757
self.instance['fault'] = {
2759
'instance_uuid': self.uuid,
2760
'message': "HTTPNotFound",
2761
'details': "Stock details for test",
2762
'created_at': datetime.datetime(2010, 10, 10, 12, 0, 0),
2765
image_bookmark = "http://localhost/fake/images/5"
2766
flavor_bookmark = "http://localhost/fake/flavors/1"
2767
self_link = "http://localhost/v2/fake/servers/%s" % self.uuid
2768
bookmark_link = "http://localhost/fake/servers/%s" % self.uuid
2773
"tenant_id": "fake",
2774
"updated": "2010-11-11T11:00:00Z",
2775
"created": "2010-10-10T12:00:00Z",
2776
"name": "test_server",
2787
"href": image_bookmark,
2796
"href": flavor_bookmark,
2802
{'version': 4, 'addr': '172.19.0.1'}
2805
{'version': 4, 'addr': '192.168.0.3'},
2806
{'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
2810
"config_drive": None,
2818
"href": bookmark_link,
2823
"created": "2010-10-10T12:00:00Z",
2824
"message": "HTTPNotFound",
2825
"details": "Stock details for test",
2830
output = self.view_builder.show(self.request, self.instance)
2831
self.assertDictMatch(output, expected_server)
2833
def test_build_server_detail_with_fault_but_active(self):
2834
self.instance['vm_state'] = vm_states.ACTIVE
2835
self.instance['progress'] = 100
2836
self.instance['fault'] = {
2838
'instance_uuid': self.uuid,
2839
'message': "HTTPNotFound",
2840
'details': "Stock details for test",
2841
'created_at': datetime.datetime(2010, 10, 10, 12, 0, 0),
2844
image_bookmark = "http://localhost/fake/images/5"
2845
flavor_bookmark = "http://localhost/fake/flavors/1"
2846
self_link = "http://localhost/v2/fake/servers/%s" % self.uuid
2847
bookmark_link = "http://localhost/fake/servers/%s" % self.uuid
2852
"tenant_id": "fake",
2853
"updated": "2010-11-11T11:00:00Z",
2854
"created": "2010-10-10T12:00:00Z",
2856
"name": "test_server",
2867
"href": image_bookmark,
2876
"href": flavor_bookmark,
2882
{'version': 4, 'addr': '172.19.0.1'}
2885
{'version': 4, 'addr': '192.168.0.3'},
2886
{'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
2890
"config_drive": None,
2898
"href": bookmark_link,
2904
output = self.view_builder.show(self.request, self.instance)
2905
self.assertDictMatch(output, expected_server)
2907
def test_build_server_detail_active_status(self):
2908
#set the power state of the instance to running
2909
self.instance['vm_state'] = vm_states.ACTIVE
2910
self.instance['progress'] = 100
2911
image_bookmark = "http://localhost/fake/images/5"
2912
flavor_bookmark = "http://localhost/fake/flavors/1"
2913
self_link = "http://localhost/v2/fake/servers/%s" % self.uuid
2914
bookmark_link = "http://localhost/fake/servers/%s" % self.uuid
2919
"tenant_id": "fake",
2920
"updated": "2010-11-11T11:00:00Z",
2921
"created": "2010-10-10T12:00:00Z",
2923
"name": "test_server",
2934
"href": image_bookmark,
2943
"href": flavor_bookmark,
2949
{'version': 4, 'addr': '172.19.0.1'}
2952
{'version': 4, 'addr': '192.168.0.3'},
2953
{'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
2957
"config_drive": None,
2965
"href": bookmark_link,
2971
output = self.view_builder.show(self.request, self.instance)
2972
self.assertDictMatch(output, expected_server)
2974
def test_build_server_detail_with_accessipv4(self):
2976
self.instance['access_ip_v4'] = '1.2.3.4'
2978
image_bookmark = "http://localhost/fake/images/5"
2979
flavor_bookmark = "http://localhost/fake/flavors/1"
2980
self_link = "http://localhost/v2/fake/servers/%s" % self.uuid
2981
bookmark_link = "http://localhost/fake/servers/%s" % self.uuid
2986
"tenant_id": "fake",
2987
"updated": "2010-11-11T11:00:00Z",
2988
"created": "2010-10-10T12:00:00Z",
2990
"name": "test_server",
2999
"href": image_bookmark,
3008
"href": flavor_bookmark,
3014
{'version': 4, 'addr': '172.19.0.1'}
3017
{'version': 4, 'addr': '192.168.0.3'},
3018
{'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
3022
"config_drive": None,
3023
"accessIPv4": "1.2.3.4",
3032
"href": bookmark_link,
3038
output = self.view_builder.show(self.request, self.instance)
3039
self.assertDictMatch(output, expected_server)
3041
def test_build_server_detail_with_accessipv6(self):
3043
self.instance['access_ip_v6'] = 'fead::1234'
3045
image_bookmark = "http://localhost/fake/images/5"
3046
flavor_bookmark = "http://localhost/fake/flavors/1"
3047
self_link = "http://localhost/v2/fake/servers/%s" % self.uuid
3048
bookmark_link = "http://localhost/fake/servers/%s" % self.uuid
3053
"tenant_id": "fake",
3054
"updated": "2010-11-11T11:00:00Z",
3055
"created": "2010-10-10T12:00:00Z",
3057
"name": "test_server",
3066
"href": image_bookmark,
3075
"href": flavor_bookmark,
3081
{'version': 4, 'addr': '172.19.0.1'}
3084
{'version': 4, 'addr': '192.168.0.3'},
3085
{'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
3089
"config_drive": None,
3091
"accessIPv6": "fead::1234",
3099
"href": bookmark_link,
3105
output = self.view_builder.show(self.request, self.instance)
3106
self.assertDictMatch(output, expected_server)
3108
def test_build_server_detail_with_metadata(self):
3111
metadata.append(InstanceMetadata(key="Open", value="Stack"))
3112
metadata.append(InstanceMetadata(key="Number", value=1))
3113
self.instance['metadata'] = metadata
3115
image_bookmark = "http://localhost/fake/images/5"
3116
flavor_bookmark = "http://localhost/fake/flavors/1"
3117
self_link = "http://localhost/v2/fake/servers/%s" % self.uuid
3118
bookmark_link = "http://localhost/fake/servers/%s" % self.uuid
3123
"tenant_id": "fake",
3124
"updated": "2010-11-11T11:00:00Z",
3125
"created": "2010-10-10T12:00:00Z",
3127
"name": "test_server",
3138
"href": image_bookmark,
3147
"href": flavor_bookmark,
3153
{'version': 4, 'addr': '172.19.0.1'}
3156
{'version': 4, 'addr': '192.168.0.3'},
3157
{'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
3164
"config_drive": None,
3172
"href": bookmark_link,
3178
output = self.view_builder.show(self.request, self.instance)
3179
self.assertDictMatch(output, expected_server)
3182
class ServerXMLSerializationTest(test.TestCase):
3184
TIMESTAMP = "2010-10-11T10:30:22Z"
3185
SERVER_HREF = 'http://localhost/v2/servers/%s' % FAKE_UUID
3186
SERVER_NEXT = 'http://localhost/v2/servers?limit=%s&marker=%s'
3187
SERVER_BOOKMARK = 'http://localhost/servers/%s' % FAKE_UUID
3188
IMAGE_BOOKMARK = 'http://localhost/images/5'
3189
FLAVOR_BOOKMARK = 'http://localhost/flavors/1'
3193
test.TestCase.setUp(self)
3195
def test_xml_declaration(self):
3196
serializer = servers.ServerTemplate()
3201
'user_id': 'fake_user_id',
3202
'tenant_id': 'fake_tenant_id',
3203
'created': self.TIMESTAMP,
3204
'updated': self.TIMESTAMP,
3206
"name": "test_server",
3208
"hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
3209
"accessIPv4": "1.2.3.4",
3210
"accessIPv6": "fead::1234",
3216
"href": self.IMAGE_BOOKMARK,
3225
"href": self.FLAVOR_BOOKMARK,
3233
"addr": "67.23.10.138",
3237
"addr": "::babe:67.23.10.138",
3243
"addr": "67.23.10.139",
3247
"addr": "::babe:67.23.10.139",
3257
'href': self.SERVER_HREF,
3261
'href': self.SERVER_BOOKMARK,
3268
output = serializer.serialize(fixture)
3270
has_dec = output.startswith("<?xml version='1.0' encoding='UTF-8'?>")
3271
self.assertTrue(has_dec)
3273
def test_show(self):
3274
serializer = servers.ServerTemplate()
3280
"tenant_id": "fake",
3281
'created': self.TIMESTAMP,
3282
'updated': self.TIMESTAMP,
3284
"name": "test_server",
3286
"hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
3288
"accessIPv4": "1.2.3.4",
3289
"accessIPv6": "fead::1234",
3295
"href": self.IMAGE_BOOKMARK,
3304
"href": self.FLAVOR_BOOKMARK,
3312
"addr": "67.23.10.138",
3316
"addr": "::babe:67.23.10.138",
3322
"addr": "67.23.10.139",
3326
"addr": "::babe:67.23.10.139",
3336
'href': self.SERVER_HREF,
3340
'href': self.SERVER_BOOKMARK,
3347
output = serializer.serialize(fixture)
3349
root = etree.XML(output)
3350
xmlutil.validate_schema(root, 'server')
3352
server_dict = fixture['server']
3354
for key in ['name', 'id', 'created', 'accessIPv4',
3355
'updated', 'progress', 'status', 'hostId',
3357
self.assertEqual(root.get(key), str(server_dict[key]))
3359
link_nodes = root.findall('{0}link'.format(ATOMNS))
3360
self.assertEqual(len(link_nodes), 2)
3361
for i, link in enumerate(server_dict['links']):
3362
for key, value in link.items():
3363
self.assertEqual(link_nodes[i].get(key), value)
3365
metadata_root = root.find('{0}metadata'.format(NS))
3366
metadata_elems = metadata_root.findall('{0}meta'.format(NS))
3367
self.assertEqual(len(metadata_elems), 2)
3368
for i, metadata_elem in enumerate(metadata_elems):
3369
(meta_key, meta_value) = server_dict['metadata'].items()[i]
3370
self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
3371
self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
3373
image_root = root.find('{0}image'.format(NS))
3374
self.assertEqual(image_root.get('id'), server_dict['image']['id'])
3375
link_nodes = image_root.findall('{0}link'.format(ATOMNS))
3376
self.assertEqual(len(link_nodes), 1)
3377
for i, link in enumerate(server_dict['image']['links']):
3378
for key, value in link.items():
3379
self.assertEqual(link_nodes[i].get(key), value)
3381
flavor_root = root.find('{0}flavor'.format(NS))
3382
self.assertEqual(flavor_root.get('id'), server_dict['flavor']['id'])
3383
link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
3384
self.assertEqual(len(link_nodes), 1)
3385
for i, link in enumerate(server_dict['flavor']['links']):
3386
for key, value in link.items():
3387
self.assertEqual(link_nodes[i].get(key), value)
3389
addresses_root = root.find('{0}addresses'.format(NS))
3390
addresses_dict = server_dict['addresses']
3391
network_elems = addresses_root.findall('{0}network'.format(NS))
3392
self.assertEqual(len(network_elems), 2)
3393
for i, network_elem in enumerate(network_elems):
3394
network = addresses_dict.items()[i]
3395
self.assertEqual(str(network_elem.get('id')), str(network[0]))
3396
ip_elems = network_elem.findall('{0}ip'.format(NS))
3397
for z, ip_elem in enumerate(ip_elems):
3399
self.assertEqual(str(ip_elem.get('version')),
3401
self.assertEqual(str(ip_elem.get('addr')),
3404
def test_create(self):
3405
serializer = servers.FullServerTemplate()
3411
"tenant_id": "fake",
3412
'created': self.TIMESTAMP,
3413
'updated': self.TIMESTAMP,
3415
"name": "test_server",
3417
"accessIPv4": "1.2.3.4",
3418
"accessIPv6": "fead::1234",
3419
"hostId": "e4d909c290d0fb1ca068ffaddf22cbd0",
3420
"adminPass": "test_password",
3426
"href": self.IMAGE_BOOKMARK,
3435
"href": self.FLAVOR_BOOKMARK,
3443
"addr": "67.23.10.138",
3447
"addr": "::babe:67.23.10.138",
3453
"addr": "67.23.10.139",
3457
"addr": "::babe:67.23.10.139",
3467
'href': self.SERVER_HREF,
3471
'href': self.SERVER_BOOKMARK,
3478
output = serializer.serialize(fixture)
3480
root = etree.XML(output)
3481
xmlutil.validate_schema(root, 'server')
3483
server_dict = fixture['server']
3485
for key in ['name', 'id', 'created', 'accessIPv4',
3486
'updated', 'progress', 'status', 'hostId',
3487
'accessIPv6', 'adminPass']:
3488
self.assertEqual(root.get(key), str(server_dict[key]))
3490
link_nodes = root.findall('{0}link'.format(ATOMNS))
3491
self.assertEqual(len(link_nodes), 2)
3492
for i, link in enumerate(server_dict['links']):
3493
for key, value in link.items():
3494
self.assertEqual(link_nodes[i].get(key), value)
3496
metadata_root = root.find('{0}metadata'.format(NS))
3497
metadata_elems = metadata_root.findall('{0}meta'.format(NS))
3498
self.assertEqual(len(metadata_elems), 2)
3499
for i, metadata_elem in enumerate(metadata_elems):
3500
(meta_key, meta_value) = server_dict['metadata'].items()[i]
3501
self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
3502
self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
3504
image_root = root.find('{0}image'.format(NS))
3505
self.assertEqual(image_root.get('id'), server_dict['image']['id'])
3506
link_nodes = image_root.findall('{0}link'.format(ATOMNS))
3507
self.assertEqual(len(link_nodes), 1)
3508
for i, link in enumerate(server_dict['image']['links']):
3509
for key, value in link.items():
3510
self.assertEqual(link_nodes[i].get(key), value)
3512
flavor_root = root.find('{0}flavor'.format(NS))
3513
self.assertEqual(flavor_root.get('id'), server_dict['flavor']['id'])
3514
link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
3515
self.assertEqual(len(link_nodes), 1)
3516
for i, link in enumerate(server_dict['flavor']['links']):
3517
for key, value in link.items():
3518
self.assertEqual(link_nodes[i].get(key), value)
3520
addresses_root = root.find('{0}addresses'.format(NS))
3521
addresses_dict = server_dict['addresses']
3522
network_elems = addresses_root.findall('{0}network'.format(NS))
3523
self.assertEqual(len(network_elems), 2)
3524
for i, network_elem in enumerate(network_elems):
3525
network = addresses_dict.items()[i]
3526
self.assertEqual(str(network_elem.get('id')), str(network[0]))
3527
ip_elems = network_elem.findall('{0}ip'.format(NS))
3528
for z, ip_elem in enumerate(ip_elems):
3530
self.assertEqual(str(ip_elem.get('version')),
3532
self.assertEqual(str(ip_elem.get('addr')),
3535
def test_index(self):
3536
serializer = servers.MinimalServersTemplate()
3538
uuid1 = get_fake_uuid(1)
3539
uuid2 = get_fake_uuid(2)
3540
expected_server_href = 'http://localhost/v2/servers/%s' % uuid1
3541
expected_server_bookmark = 'http://localhost/servers/%s' % uuid1
3542
expected_server_href_2 = 'http://localhost/v2/servers/%s' % uuid2
3543
expected_server_bookmark_2 = 'http://localhost/servers/%s' % uuid2
3544
fixture = {"servers": [
3546
"id": get_fake_uuid(1),
3547
"name": "test_server",
3550
'href': expected_server_href,
3554
'href': expected_server_bookmark,
3560
"id": get_fake_uuid(2),
3561
"name": "test_server_2",
3564
'href': expected_server_href_2,
3568
'href': expected_server_bookmark_2,
3575
output = serializer.serialize(fixture)
3577
root = etree.XML(output)
3578
xmlutil.validate_schema(root, 'servers_index')
3579
server_elems = root.findall('{0}server'.format(NS))
3580
self.assertEqual(len(server_elems), 2)
3581
for i, server_elem in enumerate(server_elems):
3582
server_dict = fixture['servers'][i]
3583
for key in ['name', 'id']:
3584
self.assertEqual(server_elem.get(key), str(server_dict[key]))
3586
link_nodes = server_elem.findall('{0}link'.format(ATOMNS))
3587
self.assertEqual(len(link_nodes), 2)
3588
for i, link in enumerate(server_dict['links']):
3589
for key, value in link.items():
3590
self.assertEqual(link_nodes[i].get(key), value)
3592
def test_index_with_servers_links(self):
3593
serializer = servers.MinimalServersTemplate()
3595
uuid1 = get_fake_uuid(1)
3596
uuid2 = get_fake_uuid(2)
3597
expected_server_href = 'http://localhost/v2/servers/%s' % uuid1
3598
expected_server_next = self.SERVER_NEXT % (2, 2)
3599
expected_server_bookmark = 'http://localhost/servers/%s' % uuid1
3600
expected_server_href_2 = 'http://localhost/v2/servers/%s' % uuid2
3601
expected_server_bookmark_2 = 'http://localhost/servers/%s' % uuid2
3602
fixture = {"servers": [
3604
"id": get_fake_uuid(1),
3605
"name": "test_server",
3608
'href': expected_server_href,
3612
'href': expected_server_bookmark,
3618
"id": get_fake_uuid(2),
3619
"name": "test_server_2",
3622
'href': expected_server_href_2,
3626
'href': expected_server_bookmark_2,
3635
'href': expected_server_next,
3639
output = serializer.serialize(fixture)
3641
root = etree.XML(output)
3642
xmlutil.validate_schema(root, 'servers_index')
3643
server_elems = root.findall('{0}server'.format(NS))
3644
self.assertEqual(len(server_elems), 2)
3645
for i, server_elem in enumerate(server_elems):
3646
server_dict = fixture['servers'][i]
3647
for key in ['name', 'id']:
3648
self.assertEqual(server_elem.get(key), str(server_dict[key]))
3650
link_nodes = server_elem.findall('{0}link'.format(ATOMNS))
3651
self.assertEqual(len(link_nodes), 2)
3652
for i, link in enumerate(server_dict['links']):
3653
for key, value in link.items():
3654
self.assertEqual(link_nodes[i].get(key), value)
3656
# Check servers_links
3657
servers_links = root.findall('{0}link'.format(ATOMNS))
3658
for i, link in enumerate(fixture['servers_links']):
3659
for key, value in link.items():
3660
self.assertEqual(servers_links[i].get(key), value)
3662
def test_detail(self):
3663
serializer = servers.ServersTemplate()
3665
uuid1 = get_fake_uuid(1)
3666
expected_server_href = 'http://localhost/v2/servers/%s' % uuid1
3667
expected_server_bookmark = 'http://localhost/servers/%s' % uuid1
3668
expected_image_bookmark = self.IMAGE_BOOKMARK
3669
expected_flavor_bookmark = self.FLAVOR_BOOKMARK
3671
uuid2 = get_fake_uuid(2)
3672
expected_server_href_2 = 'http://localhost/v2/servers/%s' % uuid2
3673
expected_server_bookmark_2 = 'http://localhost/servers/%s' % uuid2
3674
fixture = {"servers": [
3676
"id": get_fake_uuid(1),
3678
"tenant_id": "fake",
3679
'created': self.TIMESTAMP,
3680
'updated': self.TIMESTAMP,
3682
"name": "test_server",
3684
"accessIPv4": "1.2.3.4",
3685
"accessIPv6": "fead::1234",
3686
"hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
3692
"href": expected_image_bookmark,
3701
"href": expected_flavor_bookmark,
3709
"addr": "67.23.10.138",
3713
"addr": "::babe:67.23.10.138",
3722
"href": expected_server_href,
3726
"href": expected_server_bookmark,
3732
"id": get_fake_uuid(2),
3734
"tenant_id": 'fake',
3735
'created': self.TIMESTAMP,
3736
'updated': self.TIMESTAMP,
3738
"name": "test_server_2",
3740
"accessIPv4": "1.2.3.4",
3741
"accessIPv6": "fead::1234",
3742
"hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
3748
"href": expected_image_bookmark,
3757
"href": expected_flavor_bookmark,
3765
"addr": "67.23.10.138",
3769
"addr": "::babe:67.23.10.138",
3778
"href": expected_server_href_2,
3782
"href": expected_server_bookmark_2,
3789
output = serializer.serialize(fixture)
3790
root = etree.XML(output)
3791
xmlutil.validate_schema(root, 'servers')
3792
server_elems = root.findall('{0}server'.format(NS))
3793
self.assertEqual(len(server_elems), 2)
3794
for i, server_elem in enumerate(server_elems):
3795
server_dict = fixture['servers'][i]
3797
for key in ['name', 'id', 'created', 'accessIPv4',
3798
'updated', 'progress', 'status', 'hostId',
3800
self.assertEqual(server_elem.get(key), str(server_dict[key]))
3802
link_nodes = server_elem.findall('{0}link'.format(ATOMNS))
3803
self.assertEqual(len(link_nodes), 2)
3804
for i, link in enumerate(server_dict['links']):
3805
for key, value in link.items():
3806
self.assertEqual(link_nodes[i].get(key), value)
3808
metadata_root = server_elem.find('{0}metadata'.format(NS))
3809
metadata_elems = metadata_root.findall('{0}meta'.format(NS))
3810
for i, metadata_elem in enumerate(metadata_elems):
3811
(meta_key, meta_value) = server_dict['metadata'].items()[i]
3812
self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
3813
self.assertEqual(str(metadata_elem.text).strip(),
3816
image_root = server_elem.find('{0}image'.format(NS))
3817
self.assertEqual(image_root.get('id'), server_dict['image']['id'])
3818
link_nodes = image_root.findall('{0}link'.format(ATOMNS))
3819
self.assertEqual(len(link_nodes), 1)
3820
for i, link in enumerate(server_dict['image']['links']):
3821
for key, value in link.items():
3822
self.assertEqual(link_nodes[i].get(key), value)
3824
flavor_root = server_elem.find('{0}flavor'.format(NS))
3825
self.assertEqual(flavor_root.get('id'),
3826
server_dict['flavor']['id'])
3827
link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
3828
self.assertEqual(len(link_nodes), 1)
3829
for i, link in enumerate(server_dict['flavor']['links']):
3830
for key, value in link.items():
3831
self.assertEqual(link_nodes[i].get(key), value)
3833
addresses_root = server_elem.find('{0}addresses'.format(NS))
3834
addresses_dict = server_dict['addresses']
3835
network_elems = addresses_root.findall('{0}network'.format(NS))
3836
for i, network_elem in enumerate(network_elems):
3837
network = addresses_dict.items()[i]
3838
self.assertEqual(str(network_elem.get('id')), str(network[0]))
3839
ip_elems = network_elem.findall('{0}ip'.format(NS))
3840
for z, ip_elem in enumerate(ip_elems):
3842
self.assertEqual(str(ip_elem.get('version')),
3844
self.assertEqual(str(ip_elem.get('addr')),
3847
def test_update(self):
3848
serializer = servers.ServerTemplate()
3854
"tenant_id": "fake",
3855
'created': self.TIMESTAMP,
3856
'updated': self.TIMESTAMP,
3858
"name": "test_server",
3860
"hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
3861
"accessIPv4": "1.2.3.4",
3862
"accessIPv6": "fead::1234",
3868
"href": self.IMAGE_BOOKMARK,
3877
"href": self.FLAVOR_BOOKMARK,
3885
"addr": "67.23.10.138",
3889
"addr": "::babe:67.23.10.138",
3895
"addr": "67.23.10.139",
3899
"addr": "::babe:67.23.10.139",
3909
'href': self.SERVER_HREF,
3913
'href': self.SERVER_BOOKMARK,
3919
"created": self.TIMESTAMP,
3920
"message": "Error Message",
3921
"details": "Fault details",
3926
output = serializer.serialize(fixture)
3928
root = etree.XML(output)
3929
xmlutil.validate_schema(root, 'server')
3931
server_dict = fixture['server']
3933
for key in ['name', 'id', 'created', 'accessIPv4',
3934
'updated', 'progress', 'status', 'hostId',
3936
self.assertEqual(root.get(key), str(server_dict[key]))
3938
link_nodes = root.findall('{0}link'.format(ATOMNS))
3939
self.assertEqual(len(link_nodes), 2)
3940
for i, link in enumerate(server_dict['links']):
3941
for key, value in link.items():
3942
self.assertEqual(link_nodes[i].get(key), value)
3944
metadata_root = root.find('{0}metadata'.format(NS))
3945
metadata_elems = metadata_root.findall('{0}meta'.format(NS))
3946
self.assertEqual(len(metadata_elems), 2)
3947
for i, metadata_elem in enumerate(metadata_elems):
3948
(meta_key, meta_value) = server_dict['metadata'].items()[i]
3949
self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
3950
self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
3952
image_root = root.find('{0}image'.format(NS))
3953
self.assertEqual(image_root.get('id'), server_dict['image']['id'])
3954
link_nodes = image_root.findall('{0}link'.format(ATOMNS))
3955
self.assertEqual(len(link_nodes), 1)
3956
for i, link in enumerate(server_dict['image']['links']):
3957
for key, value in link.items():
3958
self.assertEqual(link_nodes[i].get(key), value)
3960
flavor_root = root.find('{0}flavor'.format(NS))
3961
self.assertEqual(flavor_root.get('id'), server_dict['flavor']['id'])
3962
link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
3963
self.assertEqual(len(link_nodes), 1)
3964
for i, link in enumerate(server_dict['flavor']['links']):
3965
for key, value in link.items():
3966
self.assertEqual(link_nodes[i].get(key), value)
3968
addresses_root = root.find('{0}addresses'.format(NS))
3969
addresses_dict = server_dict['addresses']
3970
network_elems = addresses_root.findall('{0}network'.format(NS))
3971
self.assertEqual(len(network_elems), 2)
3972
for i, network_elem in enumerate(network_elems):
3973
network = addresses_dict.items()[i]
3974
self.assertEqual(str(network_elem.get('id')), str(network[0]))
3975
ip_elems = network_elem.findall('{0}ip'.format(NS))
3976
for z, ip_elem in enumerate(ip_elems):
3978
self.assertEqual(str(ip_elem.get('version')),
3980
self.assertEqual(str(ip_elem.get('addr')),
3983
fault_root = root.find('{0}fault'.format(NS))
3984
fault_dict = server_dict['fault']
3985
self.assertEqual(fault_root.get("code"), str(fault_dict["code"]))
3986
self.assertEqual(fault_root.get("created"), fault_dict["created"])
3987
msg_elem = fault_root.find('{0}message'.format(NS))
3988
self.assertEqual(msg_elem.text, fault_dict["message"])
3989
det_elem = fault_root.find('{0}details'.format(NS))
3990
self.assertEqual(det_elem.text, fault_dict["details"])
3992
def test_action(self):
3993
serializer = servers.FullServerTemplate()
3999
"tenant_id": "fake",
4000
'created': self.TIMESTAMP,
4001
'updated': self.TIMESTAMP,
4003
"name": "test_server",
4005
"accessIPv4": "1.2.3.4",
4006
"accessIPv6": "fead::1234",
4007
"hostId": "e4d909c290d0fb1ca068ffaddf22cbd0",
4008
"adminPass": "test_password",
4014
"href": self.IMAGE_BOOKMARK,
4023
"href": self.FLAVOR_BOOKMARK,
4031
"addr": "67.23.10.138",
4035
"addr": "::babe:67.23.10.138",
4041
"addr": "67.23.10.139",
4045
"addr": "::babe:67.23.10.139",
4055
'href': self.SERVER_HREF,
4059
'href': self.SERVER_BOOKMARK,
4066
output = serializer.serialize(fixture)
4067
root = etree.XML(output)
4068
xmlutil.validate_schema(root, 'server')
4070
server_dict = fixture['server']
4072
for key in ['name', 'id', 'created', 'accessIPv4',
4073
'updated', 'progress', 'status', 'hostId',
4074
'accessIPv6', 'adminPass']:
4075
self.assertEqual(root.get(key), str(server_dict[key]))
4077
link_nodes = root.findall('{0}link'.format(ATOMNS))
4078
self.assertEqual(len(link_nodes), 2)
4079
for i, link in enumerate(server_dict['links']):
4080
for key, value in link.items():
4081
self.assertEqual(link_nodes[i].get(key), value)
4083
metadata_root = root.find('{0}metadata'.format(NS))
4084
metadata_elems = metadata_root.findall('{0}meta'.format(NS))
4085
self.assertEqual(len(metadata_elems), 2)
4086
for i, metadata_elem in enumerate(metadata_elems):
4087
(meta_key, meta_value) = server_dict['metadata'].items()[i]
4088
self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
4089
self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
4091
image_root = root.find('{0}image'.format(NS))
4092
self.assertEqual(image_root.get('id'), server_dict['image']['id'])
4093
link_nodes = image_root.findall('{0}link'.format(ATOMNS))
4094
self.assertEqual(len(link_nodes), 1)
4095
for i, link in enumerate(server_dict['image']['links']):
4096
for key, value in link.items():
4097
self.assertEqual(link_nodes[i].get(key), value)
4099
flavor_root = root.find('{0}flavor'.format(NS))
4100
self.assertEqual(flavor_root.get('id'), server_dict['flavor']['id'])
4101
link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
4102
self.assertEqual(len(link_nodes), 1)
4103
for i, link in enumerate(server_dict['flavor']['links']):
4104
for key, value in link.items():
4105
self.assertEqual(link_nodes[i].get(key), value)
4107
addresses_root = root.find('{0}addresses'.format(NS))
4108
addresses_dict = server_dict['addresses']
4109
network_elems = addresses_root.findall('{0}network'.format(NS))
4110
self.assertEqual(len(network_elems), 2)
4111
for i, network_elem in enumerate(network_elems):
4112
network = addresses_dict.items()[i]
4113
self.assertEqual(str(network_elem.get('id')), str(network[0]))
4114
ip_elems = network_elem.findall('{0}ip'.format(NS))
4115
for z, ip_elem in enumerate(ip_elems):
4117
self.assertEqual(str(ip_elem.get('version')),
4119
self.assertEqual(str(ip_elem.get('addr')),