Guest User

functest_utils.py

a guest
Jan 19th, 2016
34
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.71 KB | None | 0 0
  1. #!/usr/bin/env python
  2. #
  3. # jose.lausuch@ericsson.com
  4. # valentin.boucher@orange.com
  5. # All rights reserved. This program and the accompanying materials
  6. # are made available under the terms of the Apache License, Version 2.0
  7. # which accompanies this distribution, and is available at
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10.  
  11.  
  12. import os
  13. import os.path
  14. import urllib2
  15. import subprocess
  16. import sys
  17. import requests
  18. import json
  19. import shutil
  20. import re
  21. import yaml
  22. from git import Repo
  23.  
  24.  
  25. # ############ CREDENTIALS OPENSTACK #############
  26. def check_credentials():
  27. """
  28. Check if the OpenStack credentials (openrc) are sourced
  29. """
  30. env_vars = ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD', 'OS_TENANT_NAME']
  31. return all(map(lambda v: v in os.environ and os.environ[v], env_vars))
  32.  
  33.  
  34. def get_credentials(service):
  35. """Returns a creds dictionary filled with the following keys:
  36. * username
  37. * password/api_key (depending on the service)
  38. * tenant_name/project_id (depending on the service)
  39. * auth_url
  40. :param service: a string indicating the name of the service
  41. requesting the credentials.
  42. """
  43. creds = {}
  44. # Unfortunately, each of the OpenStack client will request slightly
  45. # different entries in their credentials dict.
  46. if service.lower() in ("nova", "cinder"):
  47. password = "api_key"
  48. tenant = "project_id"
  49. else:
  50. password = "password"
  51. tenant = "tenant_name"
  52.  
  53. # The most common way to pass these info to the script is to do it through
  54. # environment variables.
  55. creds.update({
  56. "username": os.environ.get('OS_USERNAME', "admin"),
  57. password: os.environ.get("OS_PASSWORD", 'admin'),
  58. "auth_url": os.environ.get("OS_AUTH_URL",
  59. "http://192.168.20.71:5000/v2.0"),
  60. tenant: os.environ.get("OS_TENANT_NAME", "admin"),
  61. })
  62.  
  63. return creds
  64.  
  65.  
  66. # ################ NOVA #################
  67. def get_instances(nova_client):
  68. try:
  69. instances = nova_client.servers.list(search_opts={'all_tenants': 1})
  70. return instances
  71. except:
  72. return None
  73.  
  74.  
  75. def get_instance_status(nova_client, instance):
  76. try:
  77. instance = nova_client.servers.get(instance.id)
  78. return instance.status
  79. except:
  80. return None
  81.  
  82.  
  83. def get_instance_by_name(nova_client, instance_name):
  84. try:
  85. instance = nova_client.servers.find(name=instance_name)
  86. return instance
  87. except:
  88. return None
  89.  
  90.  
  91. def get_flavor_id(nova_client, flavor_name):
  92. flavors = nova_client.flavors.list(detailed=True)
  93. id = ''
  94. for f in flavors:
  95. if f.name == flavor_name:
  96. id = f.id
  97. break
  98. return id
  99.  
  100.  
  101. def get_flavor_id_by_ram_range(nova_client, min_ram, max_ram):
  102. flavors = nova_client.flavors.list(detailed=True)
  103. id = ''
  104. for f in flavors:
  105. if min_ram <= f.ram and f.ram <= max_ram:
  106. id = f.id
  107. break
  108. return id
  109.  
  110.  
  111. def delete_instance(nova_client, instance_id):
  112. try:
  113. nova_client.servers.force_delete(instance_id)
  114. return True
  115. except:
  116. print "Error:", sys.exc_info()[0]
  117. return False
  118.  
  119. def create_floating_ip(neutron_client):
  120. extnet_id = get_external_net_id(neutron_client)
  121. props = {'floating_network_id': extnet_id}
  122. try:
  123. ip_json = neutron_client.create_floatingip({'floatingip': props})
  124. floating_ip = ip_json['floatingip']['floating_ip_address']
  125. except:
  126. return None
  127. return floating_ip
  128.  
  129. def get_floating_ips(nova_client):
  130. try:
  131. floating_ips = nova_client.floating_ips.list()
  132. return floating_ips
  133. except:
  134. return None
  135.  
  136. def add_floating_ip(nova_client, server_id, floatingip_id):
  137. try:
  138. nova_client.servers.add_floating_ip(server_id,floatingip_id)
  139. return True
  140. except:
  141. print "Error:", sys.exc_info()[0]
  142. return None
  143.  
  144. def delete_floating_ip(nova_client, floatingip_id):
  145. try:
  146. nova_client.floating_ips.delete(floatingip_id)
  147. return True
  148. except:
  149. print "Error:", sys.exc_info()[0]
  150. return None
  151.  
  152.  
  153. # ################ NEUTRON #################
  154. def create_neutron_net(neutron_client, name):
  155. json_body = {'network': {'name': name,
  156. 'admin_state_up': True}}
  157. try:
  158. network = neutron_client.create_network(body=json_body)
  159. network_dict = network['network']
  160. return network_dict['id']
  161. except:
  162. print "Error:", sys.exc_info()[0]
  163. return False
  164.  
  165.  
  166. def update_neutron_net(neutron_client, network_id, shared=False):
  167. json_body = {'network': {'shared': shared}}
  168. try:
  169. neutron_client.update_network(network_id, body=json_body)
  170. return True
  171. except:
  172. print "Error:", sys.exc_info()[0]
  173. return False
  174.  
  175.  
  176. def delete_neutron_net(neutron_client, network_id):
  177. try:
  178. neutron_client.delete_network(network_id)
  179. return True
  180. except:
  181. print "Error:", sys.exc_info()[0]
  182. return False
  183.  
  184.  
  185. def create_neutron_subnet(neutron_client, name, cidr, net_id):
  186. json_body = {'subnets': [{'name': name, 'cidr': cidr,
  187. 'ip_version': 4, 'network_id': net_id}]}
  188. try:
  189. subnet = neutron_client.create_subnet(body=json_body)
  190. return subnet['subnets'][0]['id']
  191. except:
  192. print "Error:", sys.exc_info()[0]
  193. return False
  194.  
  195.  
  196. def delete_neutron_subnet(neutron_client, subnet_id):
  197. try:
  198. neutron_client.delete_subnet(subnet_id)
  199. return True
  200. except:
  201. print "Error:", sys.exc_info()[0]
  202. return False
  203.  
  204.  
  205. def create_neutron_router(neutron_client, name):
  206. json_body = {'router': {'name': name, 'admin_state_up': True}}
  207. try:
  208. router = neutron_client.create_router(json_body)
  209. return router['router']['id']
  210. except:
  211. print "Error:", sys.exc_info()[0]
  212. return False
  213.  
  214.  
  215. def delete_neutron_router(neutron_client, router_id):
  216. json_body = {'router': {'id': router_id}}
  217. try:
  218. neutron_client.delete_router(router=router_id)
  219. return True
  220. except:
  221. print "Error:", sys.exc_info()[0]
  222. return False
  223.  
  224.  
  225. def add_interface_router(neutron_client, router_id, subnet_id):
  226. json_body = {"subnet_id": subnet_id}
  227. try:
  228. neutron_client.add_interface_router(router=router_id, body=json_body)
  229. return True
  230. except:
  231. print "Error:", sys.exc_info()[0]
  232. return False
  233.  
  234.  
  235. def remove_interface_router(neutron_client, router_id, subnet_id):
  236. json_body = {"subnet_id": subnet_id}
  237. try:
  238. neutron_client.remove_interface_router(router=router_id,
  239. body=json_body)
  240. return True
  241. except:
  242. print "Error:", sys.exc_info()[0]
  243. return False
  244.  
  245. def add_gateway_router(neutron_client, router_id):
  246. ext_net_id = get_external_net_id(neutron_client)
  247. router_dict = {'network_id': ext_net_id}
  248. try:
  249. neutron_client.add_gateway_router(router_id,router_dict)
  250. return True
  251. except:
  252. print "Error:", sys.exc_info()[0]
  253. return False
  254.  
  255. def remove_gateway_router(neutron_client, router_id):
  256. try:
  257. neutron_client.remove_gateway_router(router_id)
  258. return True
  259. except:
  260. print "Error:", sys.exc_info()[0]
  261. return False
  262.  
  263.  
  264. def create_neutron_port(neutron_client, name, network_id, ip):
  265. json_body = {'port': {
  266. 'admin_state_up': True,
  267. 'name': name,
  268. 'network_id': network_id,
  269. 'fixed_ips': [{"ip_address": ip}]
  270. }}
  271. try:
  272. port = neutron_client.create_port(body=json_body)
  273. return port['port']['id']
  274. except:
  275. print "Error:", sys.exc_info()[0]
  276. return False
  277.  
  278.  
  279. def update_neutron_port(neutron_client, port_id, device_owner):
  280. json_body = {'port': {
  281. 'device_owner': device_owner,
  282. }}
  283. try:
  284. port = neutron_client.update_port(port=port_id,
  285. body=json_body)
  286. return port['port']['id']
  287. except:
  288. print "Error:", sys.exc_info()[0]
  289. return False
  290.  
  291.  
  292. def delete_neutron_port(neutron_client, port_id):
  293. try:
  294. neutron_client.delete_port(port_id)
  295. return True
  296. except:
  297. print "Error:", sys.exc_info()[0]
  298. return False
  299.  
  300.  
  301. def get_network_id(neutron_client, network_name):
  302. networks = neutron_client.list_networks()['networks']
  303. id = ''
  304. for n in networks:
  305. if n['name'] == network_name:
  306. id = n['id']
  307. break
  308. return id
  309.  
  310.  
  311. def check_neutron_net(neutron_client, net_name):
  312. for network in neutron_client.list_networks()['networks']:
  313. if network['name'] == net_name:
  314. for subnet in network['subnets']:
  315. return True
  316. return False
  317.  
  318.  
  319. def get_network_list(neutron_client):
  320. network_list = neutron_client.list_networks()['networks']
  321. if len(network_list) == 0:
  322. return None
  323. else:
  324. return network_list
  325.  
  326.  
  327. def get_router_list(neutron_client):
  328. router_list = neutron_client.list_routers()['routers']
  329. if len(router_list) == 0:
  330. return None
  331. else:
  332. return router_list
  333.  
  334.  
  335. def get_port_list(neutron_client):
  336. port_list = neutron_client.list_ports()['ports']
  337. if len(port_list) == 0:
  338. return None
  339. else:
  340. return port_list
  341.  
  342.  
  343. def get_external_net(neutron_client):
  344. for network in neutron_client.list_networks()['networks']:
  345. if network['router:external']:
  346. return network['name']
  347. return False
  348.  
  349.  
  350. def get_external_net_id(neutron_client):
  351. for network in neutron_client.list_networks()['networks']:
  352. if network['router:external']:
  353. return network['id']
  354. return False
  355.  
  356.  
  357. def update_sg_quota(neutron_client, tenant_id, sg_quota, sg_rule_quota):
  358. json_body = {"quota": {
  359. "security_group": sg_quota,
  360. "security_group_rule": sg_rule_quota
  361. }}
  362.  
  363. try:
  364. quota = neutron_client.update_quota(tenant_id=tenant_id,
  365. body=json_body)
  366. return True
  367. except:
  368. print "Error:", sys.exc_info()[0]
  369. return False
  370.  
  371.  
  372. def update_cinder_quota(cinder_client, tenant_id, vols_quota,
  373. snapshots_quota, gigabytes_quota):
  374. quotas_values = {"volumes": vols_quota,
  375. "snapshots": snapshots_quota,
  376. "gigabytes": gigabytes_quota}
  377.  
  378. try:
  379. quotas_default = cinder_client.quotas.update(tenant_id,
  380. **quotas_values)
  381. return True
  382. except:
  383. print "Error:", sys.exc_info()[0]
  384. return False
  385.  
  386.  
  387. def get_private_net(neutron_client):
  388. # Checks if there is an existing shared private network
  389. networks = neutron_client.list_networks()['networks']
  390. if len(networks) == 0:
  391. return None
  392. for net in networks:
  393. if (net['router:external'] is False) and (net['shared'] is True):
  394. return net
  395. return None
  396.  
  397.  
  398. # ################ GLANCE #################
  399. def get_images(nova_client):
  400. try:
  401. images = nova_client.images.list()
  402. return images
  403. except:
  404. return None
  405.  
  406.  
  407. def get_image_id(glance_client, image_name):
  408. images = glance_client.images.list()
  409. id = ''
  410. for i in images:
  411. if i.name == image_name:
  412. id = i.id
  413. break
  414. return id
  415.  
  416.  
  417. def create_glance_image(glance_client, image_name, file_path, public=True):
  418. if not os.path.isfile(file_path):
  419. print "Error: file " + file_path + " does not exist."
  420. return False
  421. try:
  422. with open(file_path) as fimage:
  423. image = glance_client.images.create(name=image_name,
  424. is_public=public,
  425. disk_format="qcow2",
  426. container_format="bare",
  427. data=fimage)
  428. return image.id
  429. except:
  430. print "Error:", sys.exc_info()[0]
  431. return False
  432.  
  433.  
  434. def delete_glance_image(nova_client, image_id):
  435. try:
  436. nova_client.images.delete(image_id)
  437. return True
  438. except:
  439. print "Error:", sys.exc_info()[0]
  440. return False
  441.  
  442.  
  443. # ################ CINDER #################
  444. def get_volumes(cinder_client):
  445. try:
  446. volumes = cinder_client.volumes.list(search_opts={'all_tenants': 1})
  447. return volumes
  448. except:
  449. return None
  450.  
  451.  
  452. def delete_volume(cinder_client, volume_id, forced=False):
  453. try:
  454. if forced:
  455. try:
  456. cinder_client.volumes.detach(volume_id)
  457. except:
  458. print "Error:", sys.exc_info()[0]
  459. cinder_client.volumes.force_delete(volume_id)
  460. else:
  461. cinder_client.volumes.delete(volume_id)
  462. return True
  463. except:
  464. print "Error:", sys.exc_info()[0]
  465. return False
  466.  
  467.  
  468. # ################ CINDER #################
  469. def get_security_groups(neutron_client):
  470. try:
  471. security_groups = neutron_client.list_security_groups()[
  472. 'security_groups']
  473. return security_groups
  474. except:
  475. return None
  476.  
  477.  
  478. def delete_security_group(neutron_client, secgroup_id):
  479. try:
  480. neutron_client.delete_security_group(secgroup_id)
  481. return True
  482. except:
  483. print "Error:", sys.exc_info()[0]
  484. return False
  485.  
  486.  
  487. # ################ KEYSTONE #################
  488. def get_tenants(keystone_client):
  489. try:
  490. tenants = keystone_client.tenants.list()
  491. return tenants
  492. except:
  493. return None
  494.  
  495.  
  496. def get_tenant_id(keystone_client, tenant_name):
  497. tenants = keystone_client.tenants.list()
  498. id = ''
  499. for t in tenants:
  500. if t.name == tenant_name:
  501. id = t.id
  502. break
  503. return id
  504.  
  505.  
  506. def get_users(keystone_client):
  507. try:
  508. users = keystone_client.users.list()
  509. return users
  510. except:
  511. return None
  512.  
  513.  
  514. def get_role_id(keystone_client, role_name):
  515. roles = keystone_client.roles.list()
  516. id = ''
  517. for r in roles:
  518. if r.name == role_name:
  519. id = r.id
  520. break
  521. return id
  522.  
  523.  
  524. def get_user_id(keystone_client, user_name):
  525. users = keystone_client.users.list()
  526. id = ''
  527. for u in users:
  528. if u.name == user_name:
  529. id = u.id
  530. break
  531. return id
  532.  
  533.  
  534. def create_tenant(keystone_client, tenant_name, tenant_description):
  535. try:
  536. tenant = keystone_client.tenants.create(tenant_name,
  537. tenant_description,
  538. enabled=True)
  539. return tenant.id
  540. except:
  541. print "Error:", sys.exc_info()[0]
  542. return False
  543.  
  544.  
  545. def delete_tenant(keystone_client, tenant_id):
  546. try:
  547. tenant = keystone_client.tenants.delete(tenant_id)
  548. return True
  549. except:
  550. print "Error:", sys.exc_info()[0]
  551. return False
  552.  
  553.  
  554. def create_user(keystone_client, user_name, user_password,
  555. user_email, tenant_id):
  556. try:
  557. user = keystone_client.users.create(user_name, user_password,
  558. user_email, tenant_id,
  559. enabled=True)
  560. return user.id
  561. except:
  562. print "Error:", sys.exc_info()[0]
  563. return False
  564.  
  565.  
  566. def delete_user(keystone_client, user_id):
  567. try:
  568. tenant = keystone_client.users.delete(user_id)
  569. return True
  570. except:
  571. print "Error:", sys.exc_info()[0]
  572. return False
  573.  
  574.  
  575. def add_role_user(keystone_client, user_id, role_id, tenant_id):
  576. try:
  577. keystone_client.roles.add_user_role(user_id, role_id, tenant_id)
  578. return True
  579. except:
  580. print "Error:", sys.exc_info()[0]
  581. return False
  582.  
  583.  
  584. # ################ UTILS #################
  585. def check_internet_connectivity(url='http://www.opnfv.org/'):
  586. """
  587. Check if there is access to the internet
  588. """
  589. try:
  590. urllib2.urlopen(url, timeout=5)
  591. return True
  592. except urllib2.URLError:
  593. return False
  594.  
  595.  
  596. def download_url(url, dest_path):
  597. """
  598. Download a file to a destination path given a URL
  599. """
  600. name = url.rsplit('/')[-1]
  601. dest = dest_path + "/" + name
  602. try:
  603. response = urllib2.urlopen(url)
  604. except (urllib2.HTTPError, urllib2.URLError):
  605. return False
  606.  
  607. with open(dest, 'wb') as f:
  608. shutil.copyfileobj(response, f)
  609. return True
  610.  
  611.  
  612. def execute_command(cmd, logger=None, exit_on_error=True):
  613. """
  614. Execute Linux command
  615. """
  616. if logger:
  617. logger.debug('Executing command : {}'.format(cmd))
  618. output_file = "output.txt"
  619. f = open(output_file, 'w+')
  620. p = subprocess.call(cmd, shell=True, stdout=f, stderr=subprocess.STDOUT)
  621. f.close()
  622. f = open(output_file, 'r')
  623. result = f.read()
  624. if result != "" and logger:
  625. logger.debug(result)
  626. if p == 0:
  627. return True
  628. else:
  629. if logger:
  630. logger.error("Error when executing command %s" % cmd)
  631. if exit_on_error:
  632. exit(-1)
  633. return False
  634.  
  635.  
  636. def get_git_branch(repo_path):
  637. """
  638. Get git branch name
  639. """
  640. repo = Repo(repo_path)
  641. branch = repo.active_branch
  642. return branch.name
  643.  
  644.  
  645. def get_installer_type(logger=None):
  646. """
  647. Get installer type (fuel, apex, joid, compass)
  648. """
  649. try:
  650. installer = os.environ['INSTALLER_TYPE']
  651. except KeyError:
  652. if logger:
  653. logger.error("Impossible to retrieve the installer type")
  654. installer = "Unkown"
  655.  
  656. return installer
  657.  
  658.  
  659. def get_pod_name(logger=None):
  660. """
  661. Get PoD Name from env variable NODE_NAME
  662. """
  663. try:
  664. return os.environ['NODE_NAME']
  665. except KeyError:
  666. if logger:
  667. logger.error(
  668. "Unable to retrieve the POD name from environment.Using pod name 'unknown-pod'")
  669. return "unknown-pod"
  670.  
  671.  
  672. def push_results_to_db(db_url, case_name, logger, pod_name,
  673. git_version, payload):
  674. url = db_url + "/results"
  675. installer = get_installer_type(logger)
  676. params = {"project_name": "functest", "case_name": case_name,
  677. "pod_name": pod_name, "installer": installer,
  678. "version": git_version, "details": payload}
  679.  
  680. headers = {'Content-Type': 'application/json'}
  681. try:
  682. r = requests.post(url, data=json.dumps(params), headers=headers)
  683. if logger:
  684. logger.debug(r)
  685. return True
  686. except:
  687. print "Error:", sys.exc_info()[0]
  688. return False
  689.  
  690.  
  691. def get_resolvconf_ns():
  692. nameservers = []
  693. rconf = open("/etc/resolv.conf", "r")
  694. line = rconf.readline()
  695. while line:
  696. ip = re.search(r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b", line)
  697. if ip:
  698. nameservers.append(ip.group())
  699. line = rconf.readline()
  700. return nameservers
  701.  
  702. def getTestEnv(test, functest_yaml):
  703. # get the config of the testcase based on functest_config.yaml
  704. # 2 options
  705. # - test = test project e.g; ovno
  706. # - test = testcase e.g. functest/odl
  707. # look for the / to see if it is a test project or a testcase
  708. try:
  709. TEST_ENV = functest_yaml.get("test-dependencies")
  710.  
  711. if test.find("/") < 0:
  712. config_test = TEST_ENV[test]
  713. else:
  714. test_split = test.split("/")
  715. testproject = test_split[0]
  716. testcase = test_split[1]
  717. config_test = TEST_ENV[testproject][testcase]
  718. except KeyError:
  719. # if not defined in dependencies => no dependencies
  720. config_test = ""
  721. except:
  722. print "Error getTestEnv:", sys.exc_info()[0]
  723.  
  724. return config_test
  725.  
  726.  
  727. def get_ci_envvars():
  728. """
  729. Get the CI env variables
  730. """
  731. ci_env_var = {
  732. "installer": os.environ.get('INSTALLER_TYPE'),
  733. "scenario": os.environ.get('DEPLOY_SCENARIO')}
  734. return ci_env_var
  735.  
  736.  
  737. def isTestRunnable(test, functest_yaml):
  738. # By default we assume that all the tests are always runnable...
  739. is_runnable = True
  740. # Retrieve CI environment
  741. ci_env = get_ci_envvars()
  742. # Retrieve test environement from config file
  743. test_env = getTestEnv(test, functest_yaml)
  744.  
  745. # if test_env not empty => dependencies to be checked
  746. if test_env is not None and len(test_env) > 0:
  747. # possible criteria = ["installer", "scenario"]
  748. # consider test criteria from config file
  749. # compare towards CI env through CI en variable
  750. for criteria in test_env:
  751. if re.search(test_env[criteria], ci_env[criteria]) is None:
  752. # print "Test "+ test + " cannot be run on the environment"
  753. is_runnable = False
  754. return is_runnable
  755.  
  756.  
  757. def generateTestcaseList(functest_yaml):
  758. test_list = ""
  759. # get testcases
  760. testcase_list = functest_yaml.get("test-dependencies")
  761. projects = testcase_list.keys()
  762.  
  763. for project in projects:
  764. testcases = testcase_list[project]
  765. # 1 or 2 levels for testcases project[/case]
  766. # if only project name without controller or scenario
  767. # => shall be runnable on any controller/scenario
  768. if testcases is None:
  769. test_list += project + " "
  770. else:
  771. for testcase in testcases:
  772. if testcase == "installer" or testcase == "scenario":
  773. # project (1 level)
  774. if isTestRunnable(project, functest_yaml):
  775. test_list += project + " "
  776. else:
  777. # project/testcase (2 levels)
  778. thetest = project + "/" + testcase
  779. if isTestRunnable(thetest, functest_yaml):
  780. test_list += testcase + " "
  781.  
  782. # sort the list to execute the test in the right order
  783. test_order_list = functest_yaml.get("test_exec_priority")
  784. test_sorted_list = ""
  785. for test in test_order_list:
  786. if test_order_list[test] in test_list:
  787. test_sorted_list += test_order_list[test] + " "
  788.  
  789. # create a file that could be consumed by run-test.sh
  790. # this method is used only for CI
  791. # so it can be run only in container
  792. # reuse default conf directory to store the list of runnable tests
  793. file = open("/home/opnfv/functest/conf/testcase-list.txt", 'w')
  794. file.write(test_sorted_list)
  795. file.close()
  796.  
  797. return test_sorted_list
Add Comment
Please, Sign In to add comment