diff options
Diffstat (limited to 'qtip')
-rw-r--r-- | qtip/ansible_library/modules/apex.py | 133 | ||||
-rw-r--r-- | qtip/ansible_library/plugins/action/aggregate.py | 36 | ||||
-rw-r--r-- | qtip/ansible_library/plugins/action/calculate.py | 9 | ||||
-rw-r--r-- | qtip/reporter/testapi.py | 22 |
4 files changed, 193 insertions, 7 deletions
diff --git a/qtip/ansible_library/modules/apex.py b/qtip/ansible_library/modules/apex.py new file mode 100644 index 00000000..218440b2 --- /dev/null +++ b/qtip/ansible_library/modules/apex.py @@ -0,0 +1,133 @@ +#!/usr/bin/python + +############################################################### +# Copyright (c) 2017 ZTE Corporation +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +from collections import defaultdict +import json +import re + +from ansible.module_utils.basic import AnsibleModule + + +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + +DOCUMENTATION = ''' +--- +module: apex +short_description: collecting facts from apex environments +description: + - Use this module to create a dynamic inventory from apex undercloud. +version_added: "2.2" +author: "Zhihui Wu" +options: +notes: +requirements: + - Host 'apex-undercloud' is in ~/.ssh/config +''' + +RETURN = ''' +ansible_facts: + description: facts collected for ansible + returned: success + type: dictionary + contains: + hosts: + description: host grouped by hostname, cluster, role and manufacture + type: dict + hosts_meta: + description: hosts meta data indexed by hostname + type: dict +''' + +EXAMPLES = ''' +--- +- hosts: apex-undercloud + tasks: + - name: collect facts of apex hosts + apex: + - debug: var=hostvarsi + - name: add compute node to ansible inventory + add_host: + name: "{{ hosts_meta[item]['ip'] }}" + groups: compute + ansible_user: root + ansible_ssh_common_args: '-o StrictHostKeyChecking=No -o ProxyJump=apex-master' + with_items: "{{ hosts.compute }}" +- hosts: compute + tasks: + - name: check ssh connection + ping: +''' + + +def generate_inventory(baremetal_info, server_info): + """Generate ansible inventory from node list in json format + + Modified from https://github.com/martineg/ansible-apex-inventory/blob/master/apex.py + """ + + hosts = defaultdict(list) + hosts_meta = {} + + for node in baremetal_info: + if node['Provisioning State'].lower() == 'active': + role = re.findall('.+profile:(\w+)$', node['Properties']['capabilities'])[0] + for server in server_info: + if server['ID'] == node['Instance UUID']: + node_ip = re.findall('.+=(\d+.\d+.\d+.\d+)$', server['Networks'])[0] + hosts[role].append(node_ip) + # To match ssh.cfg.j2 template + hosts_meta[node_ip] = {'ansible_ssh_host': node_ip} + + for host in hosts: + hosts[host].sort() + + return {'hosts': hosts, 'hosts_meta': hosts_meta} + + +def main(): + module = AnsibleModule(argument_spec=dict()) + + (rc, out, err) = module.run_command(['source ~/stackrc']) + + if rc is not None and rc != 0: + return module.fail_json(msg=err) + + cmd = [module.get_bin_path('openstack', True), + 'baremetal', + 'list', + '--fields instance_uuid properties provision_state', + '--format json'] + (rc, out, err) = module.run_command(cmd) + + if rc is not None and rc != 0: + return module.fail_json(msg=err) + + baremetal_info = json.loads(out) + + cmd = [module.get_bin_path('openstack', True), + 'server', + 'list', + '--format json'] + (rc, out, err) = module.run_command(cmd) + + if rc is not None and rc != 0: + return module.fail_json(msg=err) + + server_info = json.loads(out) + + module.exit_json(changed=False, + ansible_facts=generate_inventory(baremetal_info, server_info)) + + +if __name__ == '__main__': + main() diff --git a/qtip/ansible_library/plugins/action/aggregate.py b/qtip/ansible_library/plugins/action/aggregate.py new file mode 100644 index 00000000..6e280419 --- /dev/null +++ b/qtip/ansible_library/plugins/action/aggregate.py @@ -0,0 +1,36 @@ +#!/usr/bin/python + +############################################################### +# Copyright (c) 2017 ZTE Corporation +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +from numpy import mean + +from ansible.plugins.action import ActionBase + + +class ActionModule(ActionBase): + def run(self, tmp=None, task_vars=None): + + if task_vars is None: + task_vars = dict() + + result = super(ActionModule, self).run(tmp, task_vars) + + if result.get('skipped', False): + return result + + return aggregate(self._task.args.get('group'), task_vars) + + +# aggregate QPI results +def aggregate(group, task_vars): + qpi_results = [task_vars['hostvars'][host]['qpi_result'] for host in task_vars['groups'][group]] + return { + 'score': int(mean([r['score'] for r in qpi_results])) + } diff --git a/qtip/ansible_library/plugins/action/calculate.py b/qtip/ansible_library/plugins/action/calculate.py index f88729b7..fade367f 100644 --- a/qtip/ansible_library/plugins/action/calculate.py +++ b/qtip/ansible_library/plugins/action/calculate.py @@ -10,6 +10,7 @@ ############################################################################## from numpy import mean +import yaml from ansible.plugins.action import ActionBase from ansible.utils.display import Display @@ -28,7 +29,9 @@ class ActionModule(ActionBase): if result.get('skipped', False): return result - spec = self._task.args.get('spec') + with open(self._task.args.get('spec')) as stream: + spec = yaml.safe_load(stream) + metrics = self._task.args.get('metrics') return calc_qpi(spec, metrics) @@ -42,8 +45,10 @@ def calc_qpi(qpi_spec, metrics): section_results = [{'name': s['name'], 'result': calc_section(s, metrics)} for s in qpi_spec['sections']] + # TODO(yujunz): use formula in spec - qpi_score = mean([r['result']['score'] for r in section_results]) + standard_score = 2048 + qpi_score = int(mean([r['result']['score'] for r in section_results]) * standard_score) return { 'spec': qpi_spec, 'score': qpi_score, diff --git a/qtip/reporter/testapi.py b/qtip/reporter/testapi.py index a0be5379..2e4205ea 100644 --- a/qtip/reporter/testapi.py +++ b/qtip/reporter/testapi.py @@ -7,8 +7,18 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -import requests +# OPNFV Testapi Client +# +# API url: http://testresults.opnfv.org/test/api/v1 +# API spec: +# - http://testresults.opnfv.org/test/swagger/spec.html#!/spec/queryTestResults +# - http://testresults.opnfv.org/test/swagger/spec.html#!/spec/createTestResult +# Login: +# username: opnfv +# password: contact admin +# Self host: https://github.com/opnfv/releng/tree/master/utils/test/testapi/deployment +import requests payload_template = {'project_name', 'case_name', @@ -29,19 +39,21 @@ def validate_payload(): if set(payload.keys()) != payload_template: missing_parameters = list(payload_template - set(payload.keys())) - print "Missing Parameters -- {}".\ - format(",".join(missing_parameters)) + print("Missing Parameters -- {}". + format(",".join(missing_parameters))) raise MissingParamsError("push_results", missing_parameters) invalid_params = [] for key in payload: if (payload[key] == "") or (payload[key] is None): invalid_params.append(key) if len(invalid_params) > 0: - print "Invalid or missing values of parameters -- `{}`".\ - format(",".join(invalid_params)) + print ("Invalid or missing values of parameters -- `{}`". + format(",".join(invalid_params))) raise InvalidParamsError("push_results", invalid_params) return func(testapi_url, payload) + return _execute + return _decorator |