summaryrefslogtreecommitdiffstats
path: root/odl-pipeline/lib/tripleo_introspector/tripleo_introspector.py
blob: 9258e838b75535ac52e4b7d8137a707a23e8959a (plain)
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
#
# Copyright (c) 2017 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
#
#
import os
import re

from utils import processutils
from utils.node import Node
from utils.utils_log import log_enter_exit, for_all_methods, LOG
from utils.service import Service
from utils.shutil import shutil
from common import constants
from utils import utils_yaml
from utils.tripleo_helper import TripleoHelper


@for_all_methods(log_enter_exit)
class TripleOIntrospector(Service):

    def __init__(self):
        self.overcloud_user = 'heat-admin'
        self.node_info = {'servers': {}}

    def create_cli_parser(self, parser):
        parser.add_argument('--out-file',
                            help="File where pod config will be written to. "
                                 "Defaults to ./node.yaml",
                            default=constants.NODE_YAML_PATH,
                            dest="out_file",
                            required=False)
        return parser

    def run(self, sys_args, config):
        self.gen_node_info()
        shutil.mkdir_if_not_exist(os.path.dirname(sys_args.out_file))
        utils_yaml.write_dict_to_yaml(self.node_info, sys_args.out_file)

    def gen_node_info(self):
        overcloud_ip_list = TripleoHelper.find_overcloud_ips()

        for node_ip in overcloud_ip_list:
            LOG.info('Introspecting node %s' % node_ip)
            node = Node('intro-%s' % node_ip, address=node_ip,
                        user=self.overcloud_user)
            node_mac = None
            virsh_domain = None
            server_name, _ = node.execute('hostname')
            server_name = server_name.rstrip()
            if 'overcloud-controller' in server_name:
                node_type = 'controller'
            elif 'overcloud-novacompute' in server_name:
                node_type = 'compute'
            else:
                raise TripleOInspectorException('Unknown type '
                                                '(controller/compute) %s '
                                                % server_name)
            try:
                processutils.execute('ping -c 1 %s' % node_ip)
                res, _ = processutils.execute('/usr/sbin/arp -a '
                                              '%s' % node_ip)
                node_mac = \
                    re.search('([0-9a-z]+:){5}[0-9a-z]+', res).group(0)
                virsh_domain = \
                    TripleoHelper.get_virtual_node_name_from_mac(node_mac)
            except AttributeError:
                LOG.warning("Unable to find MAC address for node {"
                            "}".format(node_ip))

            # find ovs controller and manager
            ovs_controller = self.get_ovs_controller(node)
            out, _ = node.execute('ovs-vsctl get-manager', as_root=True)
            ovs_managers = out.rstrip().split("\n")
            if all(ovs_manager == '' for ovs_manager in ovs_managers):
                LOG.warning("OVS managers for node {} is empty!".format(
                    node_ip))
            self.node_info['servers'][server_name] = {
                'address': node_ip,
                'user': self.overcloud_user,
                'type': node_type,
                'orig-ctl-mac': node_mac,
                'vNode-name': virsh_domain,
                'ovs-controller': ovs_controller,
                'ovs-managers': ovs_managers}

    @staticmethod
    def copy_ssh_id_and_overcloudrc(dest):
        undercloud = TripleoHelper.get_undercloud()
        # copy overcloudrc
        undercloud.copy('from', dest, './overcloudrc')

        # copy ssh id
        undercloud.copy('from', dest, '.ssh/id_rsa')

    @staticmethod
    def get_ovs_controller(node):
        # find ovs controller and manager
        ovs_controller, _ = node.execute('ovs-vsctl get-controller '
                                         'br-int', as_root=True)
        ovs_controller = ovs_controller.rstrip()
        if ovs_controller == '':
            LOG.warning("OVS controller for node {} is empty!".format(
                node.address))
        else:
            return ovs_controller


class TripleOInspectorException(Exception):

    def __init__(self, value):
        self.value = value

    def __str__(self):
        return self.value


def main():
    TripleOIntrospector().start()


if __name__ == '__main__':
    main()