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
|
#!/usr/bin/env python
# Copyright (c) 2017 HUAWEI TECHNOLOGIES CO.,LTD and others.
#
# 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 json
import netaddr
import re
from opnfv.deployment import manager
from opnfv.utils import opnfv_logger as logger
from opnfv.utils import ssh_utils
logger = logger.Logger(__name__).getLogger()
class CompassAdapter(manager.DeploymentHandler):
def __init__(self, installer_ip, installer_user, installer_pwd):
super(CompassAdapter, self).__init__(installer='compass',
installer_ip=installer_ip,
installer_user=installer_user,
installer_pwd=installer_pwd,
pkey_file=None)
def get_nodes(self, options=None):
nodes = []
self.deployment_status = None
self.nodes_dict = self._get_deployment_nodes()
self.deployment_status = self.get_deployment_status()
for k, v in self.nodes_dict.iteritems():
node = manager.Node(v['id'], v['ip'],
k, v['status'],
v['roles'], v['ssh_client'], v['mac'])
nodes.append(node)
self.get_nodes_called = True
return nodes
def get_openstack_version(self):
version = None
cmd = 'source /opt/admin-openrc.sh;nova-manage version 2>/dev/null'
version = next(node.run_cmd(cmd) for node in self.nodes
if node.is_controller())
return version
def get_sdn_version(self):
for node in self.nodes:
if node.is_odl():
sdn_info = self._get_sdn_info(node, manager.Role.ODL)
break
elif node.is_onos():
sdn_info = self._get_sdn_info(node, manager.Role.ONOS)
break
else:
sdn_info = None
return sdn_info
def _get_sdn_info(self, node, sdn_type):
if sdn_type == manager.Role.ODL:
sdn_key = 'distribution-karaf'
elif sdn_type == manager.Role.ONOS:
sdn_key = 'onos-'
else:
raise KeyError('SDN %s is not supported', sdn_type)
cmd = "find /opt -name '{0}*'".format(sdn_key)
sdn_info = node.run_cmd(cmd)
sdn_version = 'None'
if sdn_info:
# /opt/distribution-karaf-0.5.2-Boron-SR2.tar.gz
match_sdn = re.findall(r".*(0\.\d\.\d).*", sdn_info)
if (match_sdn and len(match_sdn) >= 1):
sdn_version = match_sdn[0]
sdn_version = '{0} {1}'.format(sdn_type, sdn_version)
return sdn_version
def get_deployment_status(self):
if self.deployment_status is not None:
logger.debug('Skip - Node status has been retrieved once')
return self.deployment_status
for k, v in self.nodes_dict.iteritems():
if manager.Role.CONTROLLER in v['roles']:
cmd = 'source /opt/admin-openrc.sh; nova hypervisor-list;'
'''
+----+---------------------+-------+---------+
| ID | Hypervisor hostname | State | Status |
+----+---------------------+-------+---------+
| 3 | host4 | up | enabled |
| 6 | host5 | up | enabled |
+----+---------------------+-------+---------+
'''
_, stdout, stderr = (v['ssh_client'].exec_command(cmd))
error = stderr.readlines()
if len(error) > 0:
logger.error("error %s" % ''.join(error))
status = manager.NodeStatus.STATUS_ERROR
v['status'] = status
continue
lines = stdout.readlines()
for i in range(3, len(lines) - 1):
fields = lines[i].strip().encode().rsplit(' | ')
hostname = fields[1].strip().encode().lower()
state = fields[2].strip().encode().lower()
if 'up' == state:
status = manager.NodeStatus.STATUS_OK
else:
status = manager.NodeStatus.STATUS_ERROR
self.nodes_dict[hostname]['status'] = status
v['status'] = manager.NodeStatus.STATUS_OK
failed_nodes = [k for k, v in self.nodes_dict.iteritems()
if v['status'] != manager.NodeStatus.STATUS_OK]
if failed_nodes and len(failed_nodes) > 0:
return 'Hosts {0} failed'.format(','.join(failed_nodes))
return 'active'
def _get_deployment_nodes(self):
sql_query = ('select host.host_id, host.roles, '
'network.ip_int, machine.mac from clusterhost as host, '
'host_network as network, machine as machine '
'where host.host_id=network.host_id '
'and host.id=machine.id;')
cmd = 'mysql -uroot -Dcompass -e "{0}"'.format(sql_query)
logger.debug('mysql command: %s', cmd)
output = self.installer_node.run_cmd(cmd)
'''
host_id roles ip_int mac
1 ["controller", "ha", "odl", "ceph-adm", "ceph-mon"]
167837746 00:00:e3:ee:a8:63
2 ["controller", "ha", "odl", "ceph-mon"]
167837747 00:00:31:1d:16:7a
3 ["controller", "ha", "odl", "ceph-mon"]
167837748 00:00:0c:bf:eb:01
4 ["compute", "ceph-osd"] 167837749 00:00:d8:22:6f:59
5 ["compute", "ceph-osd"] 167837750 00:00:75:d5:6b:9e
'''
lines = output.encode().rsplit('\n')
nodes_dict = {}
if (not lines or len(lines) < 2):
logger.error('No nodes are found in the deployment.')
return nodes_dict
proxy = {'ip': self.installer_ip,
'username': self.installer_user,
'password': self.installer_pwd}
for i in range(1, len(lines)):
fields = lines[i].strip().encode().rsplit('\t')
host_id = fields[0].strip().encode()
name = 'host{0}'.format(host_id)
node_roles_str = fields[1].strip().encode().lower()
node_roles_list = json.loads(node_roles_str)
node_roles = [manager.Role.ODL if x == 'odl'
else x for x in node_roles_list]
roles = [x for x in [manager.Role.CONTROLLER,
manager.Role.COMPUTE,
manager.Role.ODL,
manager.Role.ONOS] if x in node_roles]
ip = fields[2].strip().encode()
ip = str(netaddr.IPAddress(ip))
mac = fields[3].strip().encode()
nodes_dict[name] = {}
nodes_dict[name]['id'] = host_id
nodes_dict[name]['roles'] = roles
nodes_dict[name]['ip'] = ip
nodes_dict[name]['mac'] = mac
ssh_client = ssh_utils.get_ssh_client(hostname=ip,
username='root',
proxy=proxy)
nodes_dict[name]['ssh_client'] = ssh_client
nodes_dict[name]['status'] = manager.NodeStatus.STATUS_UNKNOWN
return nodes_dict
|