A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 1 | import os |
| 2 | import shutil |
| 3 | import re |
| 4 | from novaclient import client as nova_client |
| 5 | from SSHTestAgent import SSHTestAgent |
| 6 | from CordTestUtils import * |
A R Karthick | 933f5b5 | 2017-03-27 15:27:16 -0700 | [diff] [blame] | 7 | from CordTestUtils import log_test as log |
| 8 | |
| 9 | log.setLevel('INFO') |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 10 | |
| 11 | class VSGAccess(object): |
| 12 | |
| 13 | vcpe_map = {} |
| 14 | interface_map = {} |
| 15 | ip_addr_pattern = re.compile('[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/[0-9]{1,2}$') |
| 16 | |
| 17 | @classmethod |
| 18 | def setUp(cls): |
| 19 | try: |
| 20 | shutil.copy('/etc/resolv.conf', '/etc/resolv.conf.orig') |
| 21 | except: |
| 22 | pass |
| 23 | |
| 24 | @classmethod |
| 25 | def tearDown(cls): |
| 26 | try: |
| 27 | shutil.copy('/etc/resolv.conf.orig', '/etc/resolv.conf') |
| 28 | except: |
| 29 | pass |
| 30 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 31 | ''' |
| 32 | @method: get_nova_credentials_v2 |
| 33 | @Description: Get nova credentials |
| 34 | @params: |
| 35 | returns credential from env |
| 36 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 37 | @classmethod |
| 38 | def get_nova_credentials_v2(cls): |
| 39 | credential = {} |
| 40 | credential['username'] = os.environ['OS_USERNAME'] |
| 41 | credential['api_key'] = os.environ['OS_PASSWORD'] |
| 42 | credential['auth_url'] = os.environ['OS_AUTH_URL'] |
| 43 | credential['project_id'] = os.environ['OS_TENANT_NAME'] |
| 44 | return credential |
| 45 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 46 | ''' |
| 47 | @method: get_compute_nodes |
| 48 | @Description: Get the list of compute nodes |
| 49 | @params: |
| 50 | returns node list |
| 51 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 52 | @classmethod |
| 53 | def get_compute_nodes(cls): |
| 54 | credentials = cls.get_nova_credentials_v2() |
| 55 | nvclient = nova_client.Client('2', **credentials) |
| 56 | return nvclient.hypervisors.list() |
| 57 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 58 | ''' |
| 59 | @method: get_vsgs |
| 60 | @Description: Get list of vsg's running in compute node |
| 61 | @params: status of vsg |
| 62 | returns vsg wrappers |
| 63 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 64 | @classmethod |
| 65 | def get_vsgs(cls, active = True): |
| 66 | credentials = cls.get_nova_credentials_v2() |
| 67 | nvclient = nova_client.Client('2', **credentials) |
| 68 | vsgs = nvclient.servers.list(search_opts = {'all_tenants': 1}) |
| 69 | if active is True: |
| 70 | vsgs = filter(lambda vsg: vsg.status == 'ACTIVE', vsgs) |
| 71 | vsg_wrappers = [] |
| 72 | for vsg in vsgs: |
| 73 | vsg_wrappers.append(VSGWrapper(vsg)) |
| 74 | return vsg_wrappers |
| 75 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 76 | ''' |
| 77 | @method: open_mgmt |
| 78 | @Description: Bringing up Interface for access to management |
| 79 | @params: intf = "Interface to open" |
| 80 | returns Gateway |
| 81 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 82 | @classmethod |
| 83 | def open_mgmt(cls, intf = 'eth0'): |
| 84 | if intf in cls.interface_map: |
| 85 | gw = cls.interface_map[intf]['gw'] |
| 86 | ip = cls.interface_map[intf]['ip'] |
| 87 | if gw != '0.0.0.0': |
| 88 | current_gw, _ = get_default_gw() |
| 89 | cmds = [ 'route del default gw {}'.format(current_gw), |
| 90 | 'ifconfig {} {} up'.format(intf, ip), |
| 91 | 'route add default gw {}'.format(gw) ] |
| 92 | for cmd in cmds: |
| 93 | os.system(cmd) |
| 94 | shutil.copy('/etc/resolv.conf', '/etc/resolv.conf.lastdhcp') |
| 95 | shutil.copy('/etc/resolv.conf.orig', '/etc/resolv.conf') |
| 96 | return current_gw |
| 97 | return None |
| 98 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 99 | ''' |
| 100 | @method: close_mgmt |
| 101 | @Description: Bringing up gateway deleting default |
| 102 | @params: intf = "Interface to open" |
| 103 | dict2 = retrieved data from GET method |
| 104 | returns: NA |
| 105 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 106 | @classmethod |
| 107 | def close_mgmt(cls, restore_gw, intf = 'eth0'): |
| 108 | if restore_gw: |
| 109 | cmds = [ 'route del default gw 0.0.0.0', |
| 110 | 'route add default gw {}'.format(restore_gw), |
| 111 | 'cp /etc/resolv.conf.lastdhcp /etc/resolv.conf', |
| 112 | 'rm -f /etc/resolv.conf.lastdhcp' |
| 113 | ] |
| 114 | for cmd in cmds: |
| 115 | os.system(cmd) |
| 116 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 117 | ''' |
| 118 | @method: health_check |
| 119 | @Description: Check if vsgs are reachable |
| 120 | @params: |
| 121 | returns True |
| 122 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 123 | @classmethod |
| 124 | def health_check(cls): |
| 125 | '''Returns 0 if all active vsgs are reachable through the compute node''' |
| 126 | vsgs = cls.get_vsgs() |
| 127 | vsg_status = [] |
| 128 | for vsg in vsgs: |
| 129 | vsg_status.append(vsg.get_health()) |
| 130 | unreachable = filter(lambda st: st == False, vsg_status) |
| 131 | return len(unreachable) == 0 |
| 132 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 133 | ''' |
| 134 | @method: get_vcpe_vsg |
| 135 | @Description: Getting vsg vm instance info from given vcpe |
| 136 | @params: vcpe = "vcpe name" |
| 137 | returns vsg |
| 138 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 139 | @classmethod |
| 140 | def get_vcpe_vsg(cls, vcpe): |
| 141 | '''Find the vsg hosting the vcpe service''' |
| 142 | if vcpe in cls.vcpe_map: |
| 143 | return cls.vcpe_map[vcpe]['vsg'] |
| 144 | vsgs = cls.get_vsgs() |
| 145 | for vsg in vsgs: |
| 146 | cmd = 'sudo docker exec {} ls 2>/dev/null'.format(vcpe) |
| 147 | st, _ = vsg.run_cmd(cmd, timeout = 30) |
| 148 | if st == True: |
| 149 | return vsg |
| 150 | return None |
| 151 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 152 | ''' |
| 153 | @method: save_vcpe_config |
| 154 | @Description: Saving vcpe config with lan & wan side info |
| 155 | @params: vsg |
| 156 | vcpe |
| 157 | returns True |
| 158 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 159 | @classmethod |
| 160 | def save_vcpe_config(cls, vsg, vcpe): |
| 161 | if vcpe not in cls.vcpe_map: |
| 162 | cmd_gw = "sudo docker exec %s ip route show | grep default | head -1 | awk '{print $3}'" %(vcpe) |
| 163 | vsg_ip = vsg.ip |
| 164 | if vsg_ip is None: |
| 165 | return False |
| 166 | st, output = vsg.run_cmd(cmd_gw, timeout = 30) |
| 167 | if st == False or not output: |
| 168 | return False |
| 169 | gw = output |
| 170 | cmd_wan = "sudo docker exec %s ip addr show eth0 |grep inet |head -1 | tr -s ' ' | awk '{print $2}' | awk '{print $1}'" %(vcpe) |
| 171 | cmd_lan = "sudo docker exec %s ip addr show eth1 |grep inet |head -1 | tr -s ' ' | awk '{print $2}' | awk '{print $1}'" %(vcpe) |
| 172 | st, output = vsg.run_cmd(cmd_wan, timeout = 30) |
| 173 | ip_wan = '0.0.0.0/24' |
| 174 | ip_lan = '0.0.0.0/24' |
| 175 | if st and output: |
| 176 | if cls.ip_addr_pattern.match(output): |
| 177 | ip_wan = output |
| 178 | |
| 179 | st, output = vsg.run_cmd(cmd_lan, timeout = 30) |
| 180 | if st and output: |
| 181 | if cls.ip_addr_pattern.match(output): |
| 182 | ip_lan = output |
| 183 | |
| 184 | cls.vcpe_map[vcpe] = { 'vsg': vsg, 'gw': gw, 'wan': ip_wan, 'lan': ip_lan } |
| 185 | |
| 186 | return True |
| 187 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 188 | ''' |
| 189 | @method: restore_vcpe_config |
| 190 | @Description: Restoring saved config for lan & wan |
| 191 | @params: vcpe |
| 192 | gw |
| 193 | wan |
| 194 | lan |
| 195 | returns True/False |
| 196 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 197 | @classmethod |
| 198 | def restore_vcpe_config(cls, vcpe, gw = True, wan = False, lan = False): |
| 199 | if vcpe in cls.vcpe_map: |
| 200 | vsg = cls.vcpe_map[vcpe]['vsg'] |
| 201 | cmds = [] |
| 202 | if gw is True: |
| 203 | #restore default gw |
| 204 | gw = cls.vcpe_map[vcpe]['gw'] |
| 205 | cmds.append('sudo docker exec {} ip link set eth0 up'.format(vcpe)) |
| 206 | cmds.append('sudo docker exec {} route add default gw {} dev eth0'.format(vcpe, gw)) |
| 207 | if wan is True: |
| 208 | ip_wan = cls.vcpe_map[vcpe]['wan'] |
| 209 | cmds.append('sudo docker exec {} ip addr set {} dev eth0'.format(vcpe, ip_wan)) |
| 210 | if lan is True: |
| 211 | ip_lan = cls.vcpe_map[vcpe]['lan'] |
| 212 | cmds.append('sudo docker exec {} ip addr set {} dev eth1'.format(vcpe, ip_lan)) |
| 213 | ret_status = True |
| 214 | for cmd in cmds: |
| 215 | st, _ = vsg.run_cmd(cmd, timeout = 30) |
| 216 | if st == False: |
| 217 | ret_status = False |
| 218 | return ret_status |
| 219 | return False |
| 220 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 221 | ''' |
| 222 | @method: get_vcpe_gw |
| 223 | @Description: Get gw of vcpe from created map |
| 224 | @params: vcpe |
| 225 | returns gw |
| 226 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 227 | @classmethod |
| 228 | def get_vcpe_gw(cls, vcpe): |
| 229 | if vcpe in cls.vcpe_map: |
| 230 | return cls.vcpe_map[vcpe]['gw'] |
| 231 | return None |
| 232 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 233 | ''' |
| 234 | @method: get_vcpe_wan |
| 235 | @Description: |
| 236 | @params: |
| 237 | return wan side of vcpe |
| 238 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 239 | @classmethod |
| 240 | def get_vcpe_wan(cls, vcpe): |
| 241 | if vcpe in cls.vcpe_map: |
| 242 | return cls.vcpe_map[vcpe]['wan'] |
| 243 | return None |
| 244 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 245 | ''' |
| 246 | @method: get_vcpe_lan |
| 247 | @Description: |
| 248 | @params: |
| 249 | returns True if contents of dict1 exists in dict2 |
| 250 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 251 | @classmethod |
| 252 | def get_vcpe_lan(cls, vcpe): |
| 253 | if vcpe in cls.vcpe_map: |
| 254 | return cls.vcpe_map[vcpe]['lan'] |
| 255 | return None |
| 256 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 257 | ''' |
| 258 | @method: vcpe_wan_up |
| 259 | @Description: |
| 260 | @params: |
| 261 | returns status |
| 262 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 263 | @classmethod |
| 264 | def vcpe_wan_up(cls, vcpe): |
| 265 | return cls.restore_vcpe_config(vcpe) |
| 266 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 267 | ''' |
| 268 | @method: vcpe_lan_up |
| 269 | @Description: |
| 270 | @params: |
| 271 | returns status |
| 272 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 273 | @classmethod |
| 274 | def vcpe_lan_up(cls, vcpe, vsg = None): |
| 275 | if vsg is None: |
| 276 | vsg = cls.get_vcpe_vsg(vcpe) |
| 277 | if vsg is None: |
| 278 | return False |
| 279 | cmd = 'sudo docker exec {} ip link set eth1 up'.format(vcpe) |
| 280 | st, _ = vsg.run_cmd(cmd, timeout = 30) |
| 281 | return st |
| 282 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 283 | ''' |
| 284 | @method: vcpe_port_down |
| 285 | @Description: |
| 286 | @params: |
| 287 | returns status |
| 288 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 289 | #we cannot access compute node if the vcpe port gets dhcp as default would be through fabric |
| 290 | @classmethod |
| 291 | def vcpe_port_down(cls, vcpe, port, vsg = None): |
| 292 | if vsg is None: |
| 293 | vsg = cls.get_vcpe_vsg(vcpe) |
| 294 | if vsg is None: |
| 295 | return False |
| 296 | if not cls.save_vcpe_config(vsg, vcpe): |
| 297 | return False |
| 298 | cmd = 'sudo docker exec {} ip link set {} down'.format(vcpe, port) |
| 299 | st, _ = vsg.run_cmd(cmd, timeout = 30) |
| 300 | if st is False: |
| 301 | cls.restore_vcpe_config(vcpe) |
| 302 | return False |
| 303 | return st |
| 304 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 305 | ''' |
| 306 | @method: vcpe_wan_down |
| 307 | @Description: |
| 308 | @params: |
| 309 | returns status |
| 310 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 311 | @classmethod |
| 312 | def vcpe_wan_down(cls, vcpe, vsg = None): |
| 313 | return cls.vcpe_port_down(vcpe, 'eth0', vsg = vsg) |
| 314 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 315 | ''' |
| 316 | @method: vcpe_lan_down |
| 317 | @Description: |
| 318 | @params: |
| 319 | returns status |
| 320 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 321 | @classmethod |
| 322 | def vcpe_lan_down(cls, vcpe, vsg = None): |
| 323 | return cls.vcpe_port_down(vcpe, 'eth1', vsg = vsg) |
| 324 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 325 | ''' |
| 326 | @method: save_interface_config |
| 327 | @Description: |
| 328 | @params: |
| 329 | returns NA |
| 330 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 331 | @classmethod |
| 332 | def save_interface_config(cls, intf): |
| 333 | if intf not in cls.interface_map: |
| 334 | ip = get_ip(intf) |
| 335 | if ip is None: |
| 336 | ip = '0.0.0.0' |
| 337 | default_gw, default_gw_device = get_default_gw() |
| 338 | if default_gw_device != intf: |
| 339 | default_gw = '0.0.0.0' |
| 340 | cls.interface_map[intf] = { 'ip' : ip, 'gw': default_gw } |
| 341 | #bounce the interface to remove default gw |
| 342 | cmds = ['ifconfig {} 0 down'.format(intf), |
| 343 | 'ifconfig {} 0 up'.format(intf) |
| 344 | ] |
| 345 | for cmd in cmds: |
| 346 | os.system(cmd) |
| 347 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 348 | ''' |
| 349 | @method: restore_interface_config |
| 350 | @Description: |
| 351 | @params: |
| 352 | returns NA |
| 353 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 354 | #open up access to compute node |
| 355 | @classmethod |
| 356 | def restore_interface_config(cls, intf, vcpe = None): |
| 357 | if intf in cls.interface_map: |
| 358 | ip = cls.interface_map[intf]['ip'] |
| 359 | gw = cls.interface_map[intf]['gw'] |
| 360 | del cls.interface_map[intf] |
| 361 | cmds = [] |
| 362 | if vcpe is not None: |
| 363 | shutil.copy('/etc/resolv.conf.orig', '/etc/resolv.conf') |
| 364 | #bounce the vcpes to clear default gw |
| 365 | cmds.append('ifconfig {} 0 down'.format(vcpe)) |
| 366 | cmds.append('ifconfig {} 0 up'.format(vcpe)) |
| 367 | cmds.append('ifconfig {} {} up'.format(intf, ip)) |
| 368 | if gw and gw != '0.0.0.0': |
| 369 | cmds.append('route add default gw {} dev {}'.format(gw, intf)) |
| 370 | for cmd in cmds: |
| 371 | os.system(cmd) |
| 372 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 373 | ''' |
| 374 | @method: vcpe_get_dhcp |
| 375 | @Description: Get DHCP from vcpe dhcp interface. |
| 376 | @params: |
| 377 | returns vcpe ip |
| 378 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 379 | @classmethod |
| 380 | def vcpe_get_dhcp(cls, vcpe, mgmt = 'eth0'): |
| 381 | '''Get DHCP from vcpe dhcp interface.''' |
| 382 | '''We have to also save the management interface config for restoration''' |
| 383 | cls.save_interface_config(mgmt) |
| 384 | getstatusoutput('pkill -9 dhclient') |
| 385 | st, output = getstatusoutput('dhclient -q {}'.format(vcpe)) |
| 386 | getstatusoutput('pkill -9 dhclient') |
| 387 | vcpe_ip = get_ip(vcpe) |
| 388 | if vcpe_ip is None: |
| 389 | cls.restore_interface_config(mgmt) |
| 390 | return None |
| 391 | if output: |
| 392 | #workaround for docker container apparmor that prevents moving dhclient resolv.conf |
| 393 | start = output.find('/etc/resolv.conf') |
| 394 | if start >= 0: |
| 395 | end = output.find("'", start) |
| 396 | dns_file = output[start:end] |
| 397 | if os.access(dns_file, os.F_OK): |
| 398 | shutil.copy(dns_file, '/etc/resolv.conf') |
| 399 | |
| 400 | default_gw, default_gw_device = get_default_gw() |
| 401 | if default_gw and default_gw_device == vcpe: |
| 402 | return vcpe_ip |
| 403 | cls.restore_interface_config(mgmt, vcpe = vcpe) |
| 404 | return None |
| 405 | |
| 406 | class VSGWrapper(object): |
| 407 | |
| 408 | def __init__(self, vsg): |
| 409 | self.vsg = vsg |
| 410 | self.name = self.vsg.name |
| 411 | self.compute_node = self.get_compute_node() |
| 412 | self.ip = self.get_ip() |
| 413 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 414 | ''' |
| 415 | @method: get_compute_node |
| 416 | @Description: |
| 417 | @params: |
| 418 | returns compute node name |
| 419 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 420 | def get_compute_node(self): |
| 421 | return self.vsg._info['OS-EXT-SRV-ATTR:hypervisor_hostname'] |
| 422 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 423 | ''' |
| 424 | @method: get_ip |
| 425 | @Description: |
| 426 | @params: |
| 427 | returns ip of network |
| 428 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 429 | def get_ip(self): |
| 430 | if 'management' in self.vsg.networks: |
| 431 | ips = self.vsg.networks['management'] |
| 432 | if len(ips) > 0: |
| 433 | return ips[0] |
| 434 | return None |
| 435 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 436 | ''' |
| 437 | @method: run_cmd_compute |
| 438 | @Description: |
| 439 | @params: |
| 440 | returns Status & output |
| 441 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 442 | def run_cmd_compute(self, cmd, timeout = 5): |
| 443 | ssh_agent = SSHTestAgent(self.compute_node) |
| 444 | st, output = ssh_agent.run_cmd(cmd, timeout = timeout) |
| 445 | if st == True and output: |
| 446 | output = output.strip() |
| 447 | else: |
| 448 | output = None |
| 449 | |
| 450 | return st, output |
| 451 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 452 | ''' |
| 453 | @method: run_cmd |
| 454 | @Description: |
| 455 | @params: |
| 456 | returns status & output |
| 457 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 458 | def run_cmd(self, cmd, timeout = 5, mgmt = 'eth0'): |
| 459 | last_gw = VSGAccess.open_mgmt(mgmt) |
| 460 | ssh_agent = SSHTestAgent(self.compute_node) |
| 461 | ssh_cmd = 'ssh {} {}'.format(self.ip, cmd) |
| 462 | st, output = ssh_agent.run_cmd(ssh_cmd, timeout = timeout) |
| 463 | if st == True and output: |
| 464 | output = output.strip() |
| 465 | else: |
| 466 | output = None |
| 467 | VSGAccess.close_mgmt(last_gw, mgmt) |
| 468 | return st, output |
| 469 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 470 | ''' |
| 471 | @method: get_health |
| 472 | @Description: |
| 473 | @params: |
| 474 | returns Status |
| 475 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 476 | def get_health(self): |
| 477 | if self.ip is None: |
A R Karthick | 850795b | 2017-03-27 14:07:03 -0700 | [diff] [blame] | 478 | return True |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 479 | cmd = 'ping -c 1 {}'.format(self.ip) |
A R Karthick | 933f5b5 | 2017-03-27 15:27:16 -0700 | [diff] [blame] | 480 | log.info('Pinging VSG %s at IP %s' %(self.name, self.ip)) |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 481 | st, _ = self.run_cmd_compute(cmd) |
A R Karthick | 933f5b5 | 2017-03-27 15:27:16 -0700 | [diff] [blame] | 482 | log.info('VSG %s at IP %s is %s' %(self.name, self.ip, 'reachable' if st == True else 'unreachable')) |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 483 | return st |
| 484 | |
Chetan Gaonker | 79b3553 | 2017-03-31 18:58:36 +0000 | [diff] [blame] | 485 | ''' |
| 486 | @method: check_access |
| 487 | @Description: validates access |
| 488 | @params: |
| 489 | returns Status |
| 490 | ''' |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 491 | def check_access(self): |
| 492 | if self.ip is None: |
A R Karthick | 933f5b5 | 2017-03-27 15:27:16 -0700 | [diff] [blame] | 493 | return True |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 494 | ssh_agent = SSHTestAgent(self.compute_node) |
| 495 | st, _ = ssh_agent.run_cmd('ls', timeout=10) |
| 496 | if st == False: |
A R Karthick | 933f5b5 | 2017-03-27 15:27:16 -0700 | [diff] [blame] | 497 | log.error('Compute node at %s is not accessible' %(self.compute_node)) |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 498 | return st |
A R Karthick | 933f5b5 | 2017-03-27 15:27:16 -0700 | [diff] [blame] | 499 | log.info('Checking if VSG at %s is accessible from compute node %s' %(self.ip, self.compute_node)) |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 500 | st, _ = ssh_agent.run_cmd('ssh {} ls'.format(self.ip), timeout=30) |
A R Karthick | 933f5b5 | 2017-03-27 15:27:16 -0700 | [diff] [blame] | 501 | if st == True: |
| 502 | log.info('OK') |
A R Karthick | d0fdf3b | 2017-03-21 16:54:22 -0700 | [diff] [blame] | 503 | return st |