/
vm_test.py
3185 lines (2906 loc) · 141 KB
/
vm_test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
import re
import time
import shlex
import shutil
import traceback
import threading
import tempfile
import fixtures
import socket
import paramiko
from collections import defaultdict
from fabric.api import env
from fabric.api import run
from fabric.state import output
from fabric.state import connections as fab_connections
from fabric.operations import get, put
from fabric.context_managers import settings, hide
from subprocess import Popen, PIPE
from ipam_test import *
from vn_test import *
from tcutils.util import *
from tcutils.util import safe_run, safe_sudo
from contrail_fixtures import *
from tcutils.pkgs.install import PkgHost, build_and_install
from security_group import get_secgrp_id_from_name, list_sg_rules
from tcutils.tcpdump_utils import start_tcpdump_for_intf,\
stop_tcpdump_for_intf
from tcutils.agent.vrouter_lib import *
from tcutils.fabutils import *
from tcutils.test_lib.contrail_utils import get_interested_computes
from interface_route_table_fixture import InterfaceRouteTableFixture
env.disable_known_hosts = True
try:
from webui_test import *
except ImportError:
pass
try:
from vcenter_gateway import VcenterGatewayOrch
except ImportError:
pass
#output.debug= True
#@contrail_fix_ext ()
class VMFixture(fixtures.Fixture):
'''
Fixture to handle creation, verification and deletion of VM.
image_name : One of cirros, redmine-fe, redmine-be, ubuntu
Deletion of the VM upon exit can be disabled by setting fixtureCleanup= 'no' in params file.
If a VM with the vm_name is already present, it is not deleted upon exit. To forcefully clean them up, set fixtureCleanup= 'force'
Vn object can be a single VN object(vn_obj) or a list of VN objects(vn_objs) but not both
'''
def __init__(self, connections, vm_name=None, vn_obj=None,
vn_objs=[],
image_name='ubuntu', subnets=[],
flavor=None,
node_name=None, sg_ids=[], count=1, userdata=None,
port_ids=[], fixed_ips=[], zone=None, vn_ids=[], uuid=None,*args,**kwargs):
self.connections = connections
self.admin_connections = kwargs.get('admin_connections')
self.inputs = self.connections.inputs
self.logger = self.connections.logger
self.api_s_inspects = self.connections.api_server_inspects
self.api_s_inspect = self.connections.api_server_inspect
self.agent_inspect = self.connections.agent_inspect
self.cn_inspect = self.connections.cn_inspect
self.ops_inspect = self.connections.ops_inspects
self.orch = kwargs.get('orch', self.connections.orch)
self.quantum_h = self.connections.quantum_h
self.vnc_lib_fixture = self.connections.vnc_lib_fixture
self.vnc_lib_h = self.connections.get_vnc_lib_h()
self.nova_h = self.connections.nova_h
self.node_name = node_name
self.zone = zone
self.sg_ids = sg_ids
self.count = count
self.port_ids = port_ids
self.fixed_ips = fixed_ips
self.subnets = subnets
self.image_name = self.inputs.get_ci_image(image_name) or image_name
self.flavor = self.orch.get_default_image_flavor(self.image_name) or flavor
self.project_name = connections.project_name
self.project_id = connections.project_id
self.domain_name = connections.domain_name
self.vm_name = vm_name or get_random_name(self.project_name)
self.vm_id = uuid
self.vm_obj = None
self.vm_ips = list()
self.vn_objs = list((vn_obj and [vn_obj]) or vn_objs or
[self.orch.get_vn_obj_from_id(x) for x in vn_ids])
if self.inputs.is_ci_setup():
cidrs = []
for vn_obj in self.vn_objs:
if vn_obj['network'].has_key('subnet_ipam'):
cidrs.extend(list(map(lambda obj: obj['subnet_cidr'],
vn_obj['network']['subnet_ipam'])))
if cidrs and get_af_from_cidrs(cidrs) != 'v4':
raise v4OnlyTestException('Disabling v6 tests for CI')
self.vn_names = [self.orch.get_vn_name(x) for x in self.vn_objs]
self.vn_fq_names = [':'.join(self.vnc_lib_h.id_to_fq_name(self.orch.get_vn_id(x)))
for x in self.vn_objs]
self.vn_ids = vn_ids
if len(self.vn_objs) == 1:
self.vn_name = self.vn_names[0]
self.vn_fq_name = self.vn_fq_names[0]
self.verify_is_run = False
self.analytics_obj = self.connections.analytics_obj
self.agent_vrf_name = {}
self.agent_vrf_id = {}
self.agent_path = {}
self.agent_l2_path = {}
self.tap_intf = {}
self.mac_addr = {}
self.agent_label = {}
self.agent_l2_label = {}
self.agent_vxlan_id = {}
self.local_ips = {}
self.cs_vmi_obj = {}
self.vm_launch_flag = True
self.vm_in_api_flag = True
self.vm_in_agent_flag = True
self.vm_in_cn_flag = True
self.vm_in_op_flag = True
self.verify_vm_not_in_setup = True
self.verify_vm_not_in_api_server_flag = True
self.verify_vm_not_in_agent_flag = True
self.verify_vm_not_in_control_nodes_flag = True
self.verify_vm_not_in_nova_flag = True
self.vm_flows_removed_flag = True
self.printlock = threading.Lock()
self.verify_vm_flag = True
self.userdata = userdata
self.vm_username = None
self.vm_password = None
if self.inputs.verify_thru_gui():
self.browser = self.connections.browser
self.browser_openstack = self.connections.browser_openstack
self.webui = WebuiTest(self.connections, self.inputs)
self._vm_interface = {}
self._vrf_ids = {}
self._interested_computes = []
self.created = False
self.refresh = False
self._vmi_ids = {}
self.cfgm_ip = self.inputs.cfgm_ip
self.collector_ip = self.inputs.collector_ip
# end __init__
def read(self,refresh=False):
self.refresh = refresh
if refresh:
self.vm_ips = list()
if not self.vm_id:
self.fq_name = [self.domain_name, self.project_name, self.vm_name]
self.vm_id = self.vnc_lib_h.fq_name_to_id('virtual-machine', self.fq_name)
if self.vm_id:
self.vm_obj = self.orch.get_vm_by_id(vm_id=self.vm_id)
if not self.vm_obj:
raise Exception('VM with id %s not found' % self.vm_id)
self.orch.wait_till_vm_is_active(self.vm_obj)
if not self.orch.get_vm_detail(self.vm_obj):
raise Exception('VM %s is not yet launched' % self.vm_id)
self.vm_objs = [self.vm_obj]
self.vm_name = self.vm_obj.name
self.vn_names = self.orch.get_networks_of_vm(self.vm_obj)
self.vn_objs = [self.orch.get_vn_obj_if_present(x, project_id=self.connections.project_id)
for x in self.vn_names]
self.vn_ids = [self.orch.get_vn_id(x) for x in self.vn_objs]
self.vn_fq_names = [':'.join(self.vnc_lib_h.id_to_fq_name(x))
for x in self.vn_ids]
self.vn_name = self.vn_names[0]
self.vn_fq_name = self.vn_fq_names[0]
self.vm_ip_dict = self.get_vm_ip_dict()
self.vm_ips = self.get_vm_ips()
try:
#Avoid crashing in vcenter scenario where nova not present
self.image_id = self.vm_obj.image['id']
self.image_name = self.nova_h.get_image_by_id(self.image_id)
self.set_image_details(self.vm_obj)
except Exception as e:
pass
def setUp(self):
super(VMFixture, self).setUp()
self.create()
def create(self):
(self.vm_username, self.vm_password) = self.orch.get_image_account(
self.image_name)
if self.vm_id:
return self.read()
self.vn_ids = [self.orch.get_vn_id(x) for x in self.vn_objs]
self.vm_obj = self.orch.get_vm_if_present(self.vm_name,
project_id=self.project_id)
self.vm_objs = self.orch.get_vm_list(name_pattern=self.vm_name,
project_id=self.project_id)
if self.vm_obj:
self.vm_id = self.vm_obj.id
with self.printlock:
self.logger.debug('VM %s already present, not creating it'
% (self.vm_name))
self.set_image_details(self.vm_obj)
else:
if self.inputs.is_gui_based_config():
self.webui.create_vm(self)
else:
objs = self.orch.create_vm(
project_uuid=self.project_id,
image_name=self.image_name,
flavor=self.flavor,
vm_name=self.vm_name,
vn_objs=self.vn_objs,
node_name=self.node_name,
zone=self.zone,
sg_ids=self.sg_ids,
count=self.count,
userdata=self.userdata,
port_ids=self.port_ids,
fixed_ips=self.fixed_ips)
self.created = True
self.vm_obj = objs[0]
self.vm_objs = objs
self.vm_id = self.vm_objs[0].id
# end setUp
def set_image_details(self, vm_obj):
'''
Need to update image details for the setup where we manipulate image name in orchestrator
like in docker setup, image name will be changed while nova vm creation:
First get the latest zone from orch and then get image info for the zone'''
self.zone = getattr(vm_obj, 'OS-EXT-AZ:availability_zone', None)
self.image_name = self.orch.get_image_name_for_zone(
image_name=self.image_name,
zone=self.zone)
(self.vm_username, self.vm_password) = self.orch.get_image_account(
self.image_name)
@property
def uuid(self):
return self.get_uuid()
def get_uuid(self):
return self.vm_id
def get_fq_name(self):
return self.vm_name
def get_name(self):
return self.vm_name
def get_vm_ips(self, vn_fq_name=None, af=None):
if not af:
af = self.inputs.get_af()
af = ['v4', 'v6'] if 'dual' in af else af
if vn_fq_name:
vm_ips = self.get_vm_ip_dict()[vn_fq_name]
else:
if not getattr(self, 'vm_ips', None) or self.refresh:
for vm_obj in self.vm_objs:
for vn_name in self.vn_names:
for ip in self.orch.get_vm_ip(vm_obj, vn_name,refresh=self.refresh):
if self.hack_for_v6(ip):
continue
self.vm_ips.append(ip)
vm_ips = self.vm_ips
return [ip for ip in vm_ips if get_af_type(ip) in af]
def hack_for_v6(self, ip):
if 'v6' in self.inputs.get_af() and not is_v6(ip):
return True
return False
@property
def vm_ip(self):
return self.vm_ips[0] if self.vm_ips else None
def verify_vm_launched(self):
self.vm_launch_flag = True
for vm_obj in self.vm_objs:
if not self.orch.get_vm_detail(vm_obj):
self.logger.error('VM %s is not launched yet' % vm_obj.id)
self.vm_launch_flag = False
return False
self.logger.debug("VM %s ID is %s" % (vm_obj.name, vm_obj.id))
self.logger.debug('VM %s launched on Node %s'
% (vm_obj.name, self.get_host_of_vm(vm_obj)))
self.set_image_details(vm_obj)
self.vm_ips = self.get_vm_ips()
if not self.vm_ips:
self.logger.error('VM didnt seem to have got any IP')
self.vm_launch_flag = False
return False
self.vm_launch_flag = True
return True
# end verify_vm_launched
@property
def vm_node_ip(self):
if not getattr(self, '_vm_node_ip', None):
self._vm_node_ip = self.inputs.get_host_ip(self.get_host_of_vm())
return self._vm_node_ip
def get_host_of_vm(self, vm_obj=None):
vm_obj = vm_obj or self.vm_obj
attr = '_host_' + vm_obj.name
if not getattr(self, attr, None):
setattr(self, attr, self.orch.get_host_of_vm(vm_obj))
return getattr(self, attr, None)
@property
def vm_node_data_ip(self):
if not getattr(self, '_vm_data_node_ip', None):
self._vm_node_data_ip = self.inputs.get_host_data_ip(
self.get_host_of_vm())
return self._vm_node_data_ip
def get_compute_host(self):
return self.vm_node_data_ip
def set_vm_creds(self, username, password):
self.vm_username = username
self.vm_password = password
def get_vm_username(self):
return self.vm_username
def get_vm_password(self):
return self.vm_password
@retry(delay=1, tries=5)
def get_vm_obj_from_api_server(self, cfgm_ip=None, refresh=False):
cfgm_ip = cfgm_ip or self.inputs.cfgm_ip
if not getattr(self, 'cs_vm_obj', None):
self.cs_vm_obj = dict()
if not self.cs_vm_obj.get(cfgm_ip) or refresh:
vm_obj = self.api_s_inspects[
cfgm_ip].get_cs_vm(self.vm_id, refresh)
self.cs_vm_obj[cfgm_ip] = vm_obj
ret = True if self.cs_vm_obj[cfgm_ip] else False
return (ret, self.cs_vm_obj[cfgm_ip])
def get_vm_objs(self):
vm_obj = self.get_vm_obj_from_api_server(self.cfgm_ip)[1]
if not vm_obj:
return None
return self.cs_vm_obj
@retry(delay=1, tries=5)
def get_vmi_obj_from_api_server(self, cfgm_ip=None, refresh=False):
cfgm_ip = cfgm_ip or self.inputs.cfgm_ip
if not getattr(self, 'cs_vmi_objs', None):
self.cs_vmi_objs = dict()
if not self.cs_vmi_objs.get(cfgm_ip) or refresh:
vmi_obj = self.api_s_inspects[cfgm_ip].get_cs_vmi_of_vm(
self.vm_id, refresh=True)
self.cs_vmi_objs[cfgm_ip] = vmi_obj
ret = True if self.cs_vmi_objs[cfgm_ip] else False
return (ret, self.cs_vmi_objs[cfgm_ip])
def get_vmi_objs(self, refresh=False):
vmi_obj = self.get_vmi_obj_from_api_server(self.cfgm_ip, refresh)[1]
if not vmi_obj:
return None
return self.cs_vmi_objs
@retry(delay=1, tries=5)
def get_iip_obj_from_api_server(self, cfgm_ip=None, refresh=False):
cfgm_ip = cfgm_ip or self.inputs.cfgm_ip
if not getattr(self, 'cs_instance_ip_objs', None):
self.cs_instance_ip_objs = dict()
if not self.cs_instance_ip_objs.get(cfgm_ip) or refresh:
iip_objs = self.api_s_inspects[cfgm_ip].get_cs_instance_ips_of_vm(
self.vm_id, refresh)
self.cs_instance_ip_objs[cfgm_ip] = iip_objs
ret = True if self.cs_instance_ip_objs[cfgm_ip] else False
return (ret, self.cs_instance_ip_objs[cfgm_ip])
def get_iip_objs(self, refresh=False):
iip_obj = self.get_iip_obj_from_api_server(self.cfgm_ip, refresh)[1]
if not iip_obj:
return None
return self.cs_instance_ip_objs
def get_vm_ip_dict(self, include_secondary_ip=False):
if not getattr(self, 'vm_ip_dict', None) or self.refresh:
self.vm_ip_dict = defaultdict(list)
iip_objs = self.get_iip_obj_from_api_server(refresh=True)[1]
for iip_obj in iip_objs:
# If include_secondary_ip is False, then skip secondary IPs
if (not include_secondary_ip) and (
iip_obj['instance-ip'].get('instance_ip_secondary')):
continue
ip = iip_obj.ip
if self.hack_for_v6(ip):
continue
self.vm_ip_dict[iip_obj.vn_fq_name].append(ip)
return self.vm_ip_dict
def add_security_group(self, secgrp):
self.orch.add_security_group(vm_id=self.vm_obj.id, sg_id=secgrp)
def remove_security_group(self, secgrp):
self.orch.remove_security_group(vm_id=self.vm_obj.id, sg_id=secgrp)
def verify_security_group(self, secgrp):
result = False
errmsg = "Security group %s is not attached to the VM %s" % (secgrp,
self.vm_name)
cs_vmi_objs = self.get_vmi_obj_from_api_server(refresh=True)[1]
for cs_vmi_obj in cs_vmi_objs:
vmi = cs_vmi_obj['virtual-machine-interface']
if vmi.has_key('security_group_refs'):
sec_grps = vmi['security_group_refs']
for sec_grp in sec_grps:
if secgrp == sec_grp['to'][-1]:
self.logger.debug(
"Security group %s is attached \
to the VM %s", secgrp, self.vm_name)
result = True
if not result:
self.logger.warn(errmsg)
return result, errmsg
result, msg = self.verify_sec_grp_in_agent(secgrp)
if not result:
self.logger.warn(msg)
return result, msg
result, msg = self.verify_sg_acls_in_agent(secgrp)
if not result:
self.logger.warn(msg)
return result, msg
else:
self.logger.info('Validated that SG %s is bound to VM %s' % (
secgrp, self.vm_name))
return result, None
@retry(delay=2, tries=4)
def verify_sec_grp_in_agent(self, secgrp, domain=None):
# this method verifies sg secgrp attached to vm info in agent
domain = domain or self.domain_name
secgrp_fq_name = ':'.join([domain,
self.project_name,
secgrp])
sg_id = get_secgrp_id_from_name(
self.connections,
secgrp_fq_name)
inspect_h = self.agent_inspect[self.vm_node_ip]
sg_info = inspect_h.get_sg(sg_id)
if sg_info:
self.logger.debug("Agent: Security group %s is attached to the VM %s",
secgrp, self.vm_name)
return True, None
errmsg = "Agent: Security group %s is NOT attached to the VM %s" % (secgrp,
self.vm_name)
return False, errmsg
@retry(delay=2, tries=4)
def verify_sg_acls_in_agent(self, secgrp, domain=None):
domain = domain or self.domain_name
secgrp_fq_name = ':'.join([domain,
self.project_name,
secgrp])
sg_id = get_secgrp_id_from_name(
self.connections,
secgrp_fq_name)
rules = self.orch.get_security_group_rules(sg_id)
inspect_h = self.agent_inspect[self.vm_node_ip]
acls_list = inspect_h.get_sg_acls_list(sg_id)
errmsg = "sg acl rule not found in agent"
result = False
for rule in rules:
result = False
uuid = rule.get('id', None)
if not uuid:
uuid = rule['rule_uuid']
for acl in acls_list:
for r in acl['entries']:
if r.has_key('uuid'):
if r['uuid'] == uuid:
result = True
break
if result:
break
if not result:
return result, errmsg
return True, None
@retry(delay=2, tries=4)
def verify_vm_in_vrouter(self):
'''
Verify that VM's /32 route is in vrouter of all computes
'''
for vn_fq_name in self.vn_fq_names:
if self.vnc_lib_fixture.get_active_forwarding_mode(vn_fq_name) =='l2':
# TODO
# After bug 1614824 is fixed
# L2 route verification
continue
tap_intf = self.tap_intf[vn_fq_name]
for compute_ip in self.inputs.compute_ips:
inspect_h = self.agent_inspect[compute_ip]
prefixes = self.vm_ip_dict[vn_fq_name]
vrf_id = self.vrf_ids.get(compute_ip, {}).get(vn_fq_name)
# No need to check route if vrf is not in that compute
if not vrf_id:
continue
for prefix in prefixes:
# Skip validattion of v6 route on kernel till 1632511 is fixed
if get_af_type(prefix) == 'v6':
continue
route_table = inspect_h.get_vrouter_route_table(
vrf_id,
prefix=prefix,
prefix_len='32',
get_nh_details=True)
# Do WA for bug 1614847
if len(route_table) == 2 and \
route_table[0] == route_table[1]:
pass
elif len(route_table) != 1:
self.logger.warn('Did not find vrouter route for IP %s'
' in %s' %(prefix, compute_ip))
return False
self.logger.debug('Validated VM route %s in vrouter of %s' %(
prefix, compute_ip))
# Check the label and nh details
route = route_table[0]
if compute_ip == self.vm_node_ip:
result = validate_local_route_in_vrouter(route,
inspect_h, tap_intf['name'], self.logger)
else:
tunnel_dest_ip = self.inputs.host_data[self.vm_node_ip]['control-ip']
label = tap_intf['label']
result = validate_remote_route_in_vrouter(route,
tunnel_dest_ip,
label,
self.logger)
if not result:
self.logger.warn('Failed to validate VM route %s in'
' vrouter of %s' %(prefix, compute_ip))
return False
else:
self.logger.debug('Validated VM route %s in '
'vrouter of %s' %(prefix, compute_ip))
# endif
# endif
# for prefix
#end for compute_ip
# end for vn_fq_name
self.logger.info('Validated routes of VM %s in all vrouters' % (
self.vm_name))
return True
# end verify_vm_in_vrouter
def verify_on_setup(self, force=False,refresh=False):
#TO DO: sandipd - Need adjustments in multiple places to make verification success
# in vcenter gateway setup.Will do gradually.For now made changes just needed to make few functionality
#test cases pass
if isinstance(self.orch,VcenterGatewayOrch):
self.logger.debug('Skipping VM %s verification for vcenter gateway setup' % (self.vm_name))
return True
if not (self.inputs.verify_on_setup or force):
self.logger.debug('Skipping VM %s verification' % (self.vm_name))
return True
result = True
self.refresh = refresh
vm_status = self.orch.wait_till_vm_is_active(self.vm_obj)
if type(vm_status) is tuple:
if vm_status[1] in 'ERROR':
self.logger.warn("VM in error state. Asserting...")
return False
if vm_status[1] != 'ACTIVE':
return False
elif not vm_status:
return False
self.verify_vm_launched()
if len(self.vm_ips) < 1:
return False
self.verify_vm_flag = True
if self.inputs.verify_thru_gui():
self.webui.verify_vm(self)
result = self.verify_vm_in_api_server()
if not result:
self.logger.error('VM %s verification in API Server failed'
% (self.vm_name))
return result
result = self.verify_vm_in_agent()
if not result:
self.logger.error('VM %s verification in Agent failed'
% (self.vm_name))
return result
result = self.verify_vm_in_vrouter()
if not result:
self.logger.error('VM %s verification in Vrouter failed'
% (self.vm_name))
return result
result = self.verify_vm_in_control_nodes()
if not result:
self.logger.error('Route verification for VM %s in Controlnodes'
' failed ' % (self.vm_name))
return result
result = self.verify_vm_in_opserver()
if not result:
self.logger.error('VM %s verification in Opserver failed'
% (self.vm_name))
return result
self.verify_is_run = True
return result
# end verify_on_setup
def mini_verify_on_setup(self):
result = True
if not self.verify_vm_launched():
return False
if not self.verify_vm_in_api_server():
self.logger.error('VM %s verification in API Server failed'
% (self.vm_name))
result = result and False
if not self.verify_vm_in_agent():
self.logger.error('VM %s verification in Agent failed'
% (self.vm_name))
result = result and False
self.verify_is_run = True
return result
# end mini_verify_on_setup
def get_vrf_id(self, vn_fq_name, vn_vrf_name):
inspect_h = self.agent_inspect[self.vm_node_ip]
(domain, project, vn) = vn_fq_name.split(':')
agent_vrf_objs_vn = inspect_h.get_vna_vrf_objs(domain, project, vn)
agent_vrf_obj_vn = self.get_matching_vrf(
agent_vrf_objs_vn['vrf_list'],
vn_vrf_name)
vn_vrf_id = agent_vrf_obj_vn['ucindex']
return vn_vrf_id
# end get_vrf_id
def chk_vmi_for_vrf_entry(self, vn_fq_name):
try:
cs_vmi_objs_vm = self.get_vmi_obj_from_api_server()[1]
inspect_h = self.agent_inspect[self.vm_node_ip]
for vmi_obj in cs_vmi_objs_vm:
tap_intf = {}
tmp_vmi_id = vmi_obj.uuid
tap_intf[vn_fq_name] = inspect_h.get_vna_tap_interface_by_vmi(
vmi_id=tmp_vmi_id)[0]
vrf_entry = tap_intf[vn_fq_name]['fip_list'][0]['vrf_name']
return vrf_entry
except IndexError, e:
self.logger.warn('Unable to get VRFEntry in agent %s for VM %s,',
'VN %s' % (self.vm_node_ip, self.vm_name, vn_fq_name))
return None
# end chk_vmi_for_vrf_entry
def chk_vmi_for_fip(self, vn_fq_name):
try:
cs_vmi_objs_vm = self.get_vmi_obj_from_api_server()[1]
inspect_h = self.agent_inspect[self.vm_node_ip]
for vmi_obj in cs_vmi_objs_vm:
tap_intf = {}
tmp_vmi_id = vmi_obj.uuid
tap_intf = inspect_h.get_vna_tap_interface_by_vmi(
vmi_id=tmp_vmi_id)[0]
fip_list = tap_intf['fip_list']
for fip in fip_list:
if vn_fq_name in fip['vrf_name']:
fip_addr_vm = fip['ip_addr']
return fip_addr_vm
except IndexError, e:
self.logger.warn('Unable to get Floating IP from agent %s ',
'for VM %s,VN %s' % (self.vm_node_ip, self.vm_name, vn_fq_name))
return None
# end chk_vmi_for_fip
@retry(delay=2, tries=15)
def verify_vm_in_api_server(self):
'''Validate API-Server objects for a VM.
Checks if Instance IP in API Server is same as what
Orchestration system gave it.
Checks if the virtual-machine-interface's VN in API Server is correct.
'''
self.vm_in_api_flag = True
self.get_vm_objs()
self.get_vmi_objs(refresh=True)
self.get_iip_objs(refresh=True)
self.logger.debug("Verifying in api server %s" % (self.cfgm_ip))
if not self.cs_instance_ip_objs[self.cfgm_ip]:
with self.printlock:
self.logger.error('Instance IP of VM ID %s not seen in '
'API Server ' % (self.vm_id))
self.vm_in_api_flag = self.vm_in_api_flag and False
return False
for ips in self.get_vm_ip_dict().values():
if len((set(ips).intersection(set(self.vm_ips)))) < 1:
with self.printlock:
self.logger.warn('Instance IP %s from API Server is '
' not found in VM IP list %s' % (ips, str(self.vm_ips)))
self.vm_in_api_flag = self.vm_in_api_flag and False
return False
for vmi_obj in self.cs_vmi_objs[self.inputs.cfgm_ip]:
vmi_vn_id = vmi_obj.vn_uuid
vmi_vn_fq_name = vmi_obj.vn_fq_name
# ToDo: msenthil the checks have to be other way around
if vmi_vn_id not in self.vn_ids:
with self.printlock:
self.logger.warn('VMI %s of VM %s is not mapped to the '
'right VN ID in API Server' % (vmi_vn_id, self.vm_name))
self.vm_in_api_flag = self.vm_in_api_flag and False
return False
self.cs_vmi_obj[vmi_vn_fq_name] = vmi_obj
self.logger.info('VM %s verfication in all API Servers passed' % (
self.vm_name))
self.vm_in_api_flag = self.vm_in_api_flag and True
return True
# end verify_vm_in_api_server
@retry(delay=2, tries=25)
def verify_vm_not_in_api_server(self):
self.verify_vm_not_in_api_server_flag = True
self.logger.debug("Verifying in api server %s" % (self.cfgm_ip))
api_inspect = self.api_s_inspects[self.cfgm_ip]
if api_inspect.get_cs_vm(self.vm_id, refresh=True) is not None:
with self.printlock:
self.logger.debug("VM ID %s of VM %s is still found in API Server"
% (self.vm_id, self.vm_name))
self.verify_vm_not_in_api_server_flag = self.verify_vm_not_in_api_server_flag and False
return False
if api_inspect.get_cs_vr_of_vm(self.vm_id, refresh=True) is not None:
with self.printlock:
self.logger.debug('API-Server still seems to have VM reference '
'for VM %s' % (self.vm_name))
self.verify_vm_not_in_api_server_flag = self.verify_vm_not_in_api_server_flag and False
return False
if api_inspect.get_cs_vmi_of_vm(self.vm_id,
refresh=True):
with self.printlock:
self.logger.debug("API-Server still has VMI info of VM %s"
% (self.vm_name))
self.verify_vm_not_in_api_server_flag = self.verify_vm_not_in_api_server_flag and False
return False
self.verify_vm_not_in_api_server_flag = self.verify_vm_not_in_api_server_flag and True
with self.printlock:
self.logger.info(
"VM %s is fully removed in API-Server " % (self.vm_name))
return True
# end verify_vm_not_in_api_server
def get_tap_intf_of_vmi(self, vmi_uuid):
inspect_h = self.agent_inspect[self.vm_node_ip]
vna_tap_id = inspect_h.get_vna_tap_interface_by_vmi(vmi_id=vmi_uuid)
try:
return vna_tap_id[0]
except Exception as e:
self.logger.exception("Caught exception as %s"%(e))
def get_tap_intf_of_vm(self):
inspect_h = self.agent_inspect[self.vm_node_ip]
tap_intfs = inspect_h.get_vna_tap_interface_by_vm(vm_id=self.vm_id)
return tap_intfs
def get_vmi_id(self, vn_fq_name):
vmi_ids = self.get_vmi_ids()
if vmi_ids and vn_fq_name in vmi_ids:
return vmi_ids[vn_fq_name]
def get_vmi_ids(self, refresh=False):
if not getattr(self, '_vmi_ids', None) or refresh or self.refresh:
self._vmi_ids = dict()
vmi_objs = self.get_vmi_obj_from_api_server(refresh=refresh)[1]
for vmi_obj in vmi_objs:
self._vmi_ids[vmi_obj.vn_fq_name] = vmi_obj.uuid
return self._vmi_ids
def get_mac_addr_from_config(self):
if not getattr(self, 'mac_addr', None) or self.refresh:
vmi_objs = self.get_vmi_obj_from_api_server()[1]
for vmi_obj in vmi_objs:
self.mac_addr[vmi_obj.vn_fq_name] = vmi_obj.mac_addr
return self.mac_addr
def get_agent_label(self):
if not getattr(self, 'agent_label', None):
for (vn_fq_name, vmi) in self.get_vmi_ids().iteritems():
self.agent_label[
vn_fq_name] = self.get_tap_intf_of_vmi(vmi)['label']
return self.agent_label
def get_local_ips(self, refresh=False):
if refresh or not getattr(self, 'local_ips', None):
for (vn_fq_name, vmi) in self.get_vmi_ids().iteritems():
try:
self.local_ips[vn_fq_name] = self.get_tap_intf_of_vmi(
vmi)['mdata_ip_addr']
except Exception as e:
self.logger.exception(e)
return self.local_ips
def get_local_ip(self, refresh=False):
if refresh or not getattr(self, '_local_ip', None) or self.refresh:
local_ips = self.get_local_ips(refresh=refresh)
for vn_fq_name in self.vn_fq_names:
if self.vnc_lib_fixture.get_active_forwarding_mode(vn_fq_name) == 'l2':
self.logger.debug(
"skipping ping to one of the 169.254.x.x IPs")
if vn_fq_name in local_ips and local_ips[vn_fq_name] != '0.0.0.0':
if self.ping_vm_from_host(vn_fq_name):
self._local_ip = self.local_ips[vn_fq_name]
break
return getattr(self, '_local_ip', '')
def clear_local_ips(self):
self._local_ip = None
self.local_ips = {}
@property
def local_ip(self):
return self.get_local_ip()
@property
def vrf_ids(self):
return self.get_vrf_ids()
@property
def vmi_ids(self):
return self.get_vmi_ids()
#Need to retry many times due to bug 1683478, once bug is fixed we can reduce the no. of retry
@retry(delay=3, tries=30)
def verify_vm_in_agent(self):
''' Verifies whether VM has got created properly in agent.
'''
self.vm_in_agent_flag = True
# Verification in vcenter plugin introspect
# vcenter introspect not working.disabling vcenter verification till.
# if getattr(self.orch,'verify_vm_in_vcenter',None):
# assert self.orch.verify_vm_in_vcenter(self.vm_obj)
inspect_h = self.agent_inspect[self.vm_node_ip]
for vn_fq_name in self.vn_fq_names:
(domain, project, vn) = vn_fq_name.split(':')
agent_vn_obj = inspect_h.get_vna_vn(domain, project, vn)
if not agent_vn_obj:
self.logger.warn('VN %s is not seen in agent %s'
% (vn_fq_name, self.vm_node_ip))
self.vm_in_agent_flag = self.vm_in_agent_flag and False
return False
# Check if the VN ID matches between the Orchestration S and Agent
# ToDo: msenthil should be == check of vn_id[vn_fq_name] rather
# than list match
if agent_vn_obj['uuid'] not in self.vn_ids:
self.logger.warn('Unexpected VN UUID %s found in agent %s '
'Expected: One of %s' % (agent_vn_obj['uuid'],
self.vm_node_ip, self.vn_ids))
self.vm_in_agent_flag = self.vm_in_agent_flag and False
return False
try:
vna_tap_id = self.get_tap_intf_of_vmi(
self.get_vmi_ids()[vn_fq_name])
except Exception as e:
self.logger.warn("Exception: %s" % (e))
vna_tap_id = None
self.tap_intf[vn_fq_name] = vna_tap_id
if not self.tap_intf[vn_fq_name]:
self.logger.error('Tap interface in VN %s for VM %s not'
'seen in agent %s '
% (vn_fq_name, self.vm_name, self.vm_node_ip))
self.vm_in_agent_flag = self.vm_in_agent_flag and False
return False
mac_addr = self.tap_intf[vn_fq_name]['mac_addr']
#For vcenter gateway case, mac in tap interface was in lower case,but mac
# in api server was in upper case, though the value was same
if mac_addr.lower() != self.get_mac_addr_from_config()[vn_fq_name].lower():
with self.printlock:
self.logger.error('VM Mac address for VM %s not seen in'
'agent %s or VMI mac is not matching with API'
'Server information' % (self.vm_name, self.vm_node_ip))
self.vm_in_agent_flag = self.vm_in_agent_flag and False
return False
try:
self.tap_intf[vn_fq_name] = inspect_h.get_vna_intf_details(
self.tap_intf[vn_fq_name]['name'])[0]
except Exception as e:
self.logger.warn("Exception: %s" % (e))
return False
self.logger.debug("VM %s Tap interface: %s" % (self.vm_name,
str(self.tap_intf[vn_fq_name])))
self.agent_vrf_name[vn_fq_name] = self.tap_intf[
vn_fq_name]['vrf_name']
self.logger.debug("Agent %s vrf name: %s" %
(self.vm_node_ip, str(self.agent_vrf_name[vn_fq_name])))
try:
agent_vrf_objs = inspect_h.get_vna_vrf_objs(
domain, project, vn)
except Exception as e:
self.logger.warn("Exception: %s" % (e))
agent_vrf_objs = None
self.logger.debug("Agent VRF Object : %s" % (str(agent_vrf_objs)))
if not agent_vrf_objs:
return False
# Bug 1372858
try:
agent_vrf_obj = self.get_matching_vrf(
agent_vrf_objs['vrf_list'],
self.agent_vrf_name[vn_fq_name])
except Exception as e:
self.logger.warn("Exception: %s" % (e))
vrf_id = inspect_h.get_vna_vrf_id(vn_fq_name)
self.logger.debug("VRF id in agent for VN %s is %s" % (
vn_fq_name, vrf_id))
return False
self.agent_vrf_id[vn_fq_name] = agent_vrf_obj['ucindex']
self.agent_path[vn_fq_name] = list()
self.agent_label[vn_fq_name] = list()
agent_label = None
if self.vnc_lib_fixture.get_active_forwarding_mode(vn_fq_name) != 'l2':
try:
for vm_ip in self.vm_ip_dict[vn_fq_name]:
agent_path = inspect_h.get_vna_active_route(
vrf_id=self.agent_vrf_id[vn_fq_name],
ip=vm_ip)
if agent_path is None:
self.logger.warn("No route seen for VM IP %s in agent %s"
% (vm_ip, self.vm_node_ip))
return False
self.agent_path[vn_fq_name].append(agent_path)
except Exception as e:
self.logger.exception('Error while getting agent route')
return False
if not self.agent_path[vn_fq_name]:
with self.printlock:
self.logger.warn('No path seen for VM IP %s in agent %s'
% (self.vm_ip_dict[vn_fq_name], self.vm_node_ip))
self.vm_in_agent_flag = self.vm_in_agent_flag and False
return False
for agent_path in self.agent_path[vn_fq_name]:
for intf in agent_path['path_list']:
if 'itf' in intf['nh']:
intf_name = intf['nh']['itf']
if not intf['nh'].get('mc_list', None):
agent_label = intf['label']
break
self.agent_label[vn_fq_name].append(agent_label)
if intf_name != \
self.tap_intf[vn_fq_name]['name']:
self.logger.warning("Active route in agent for %s is "
"not pointing to right tap interface. It is %s "
% (self.vm_ip_dict[vn_fq_name],
agent_path['path_list'][0]['nh']['itf']))
self.vm_in_agent_flag = self.vm_in_agent_flag and False
return False
else:
self.logger.debug('Active route in agent is present for'
' VMI %s ' % (self.tap_intf[vn_fq_name]['name']))
if self.tap_intf[vn_fq_name]['label'] != agent_label:
self.logger.warning('VM %s label mismatch! ,'
' Expected : %s , Got : %s' % (self.vm_name,
self.tap_intf[vn_fq_name]['label'], agent_label))
self.vm_in_agent_flag = self.vm_in_agent_flag and False