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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
|
import django
import os
import threading
from django.conf import settings
from django.core.exceptions import AppRegistryNotReady
from django.utils import timezone
from .utils import *
try:
django.setup()
from .models import ImageSync
from caas.models import Cluster
from caas.models import Location
from caas.models import Namespace
except django.core.exceptions.AppRegistryNotReady as exp:
pass
class RemoteRegionWorker:
def __init__(self):
pass
def _get_crd_details(self):
crd_cluster_role = "nad"
crd_api_group = "k8s.cni.cncf.io"
crd_api_resources = "network-attachment-definitions"
crd_api_verbs = "*"
return crd_cluster_role, crd_api_group, crd_api_resources, crd_api_verbs
def _read_remote_openrc(self, remote_region_oam_ip, logger):
#cmd = "scp @[fd00:4888:2000:120c::290]:/etc/platform/openrc .
logger.info("Inside _read_remote_openrc")
host_username = settings.HOST_CREDS['username']
host_password = settings.HOST_CREDS['password']
ssh_prefix = 'ssh -o StrictHostKeyChecking=no -t ' + host_username + '@' + remote_region_oam_ip
env_string = ""
cmds_scp = []
folder = get_temp_file_location()
logger.info("Tmp file location:" + folder)
#tmpFilePath = os.path.join(os.path.dirname(__file__), "./" + folder)
tmpFileName = 'openrc_' + str(remote_region_oam_ip)
cmds_scp.append('scp -o StrictHostKeyChecking=no ' + host_username + '@[' + remote_region_oam_ip + ']:/etc/platform/openrc ' + folder + '/' + tmpFileName)
logger.info(cmds_scp)
run_commands_scp(cmds_scp, host_password, logger, block=True)
logger.info("About to create env string")
fp = open(folder + '/' + tmpFileName)
lines = fp.readlines()
logger.info(lines)
password_line = ''
for line in lines:
line = line.lstrip().rstrip()
logger.info(line)
parts = line.split(' ')
if len(parts) == 2:
if parts[0] == 'export':
if parts[1]:
env_var = parts[1].lstrip().rstrip()
logger.info(env_var)
if 'OS_PASSWORD' not in env_var:
env_string = env_string + " " + env_var
if len(parts) >= 2 and 'OS_PASSWORD=' in parts[1]:
logger.info("Parsing password")
password_parts = line.split('PASSWORD=')
password_command_parts = password_parts[1].split(' ')
password_line = password_command_parts[1].rstrip().lstrip()
logger.info("Password line:" + password_line)
logger.info("Deleting openrc file ")
# Delete file
if os.path.exists(folder + '/' + tmpFileName):
os.remove(folder + '/' + tmpFileName)
logger.info("Looking for password")
# Get password
password_cmd = []
#cmd = 'TERM=linux /opt/platform/.keyring/20.06/.CREDENTIAL 2>/dev/null'
cmd_to_run = ssh_prefix + " " + password_line
logger.info(cmd_to_run)
successful, value = self._run_command_get_output([cmd_to_run], host_password, logger)
password_val = host_password
#if successful:
# if value != '':
# password_val = value
os_password = "OS_PASSWORD=" + password_val
env_string = env_string + " " + os_password
logger.info("Env string:" + env_string)
return env_string
def _run_command_get_all_lines(self, commands, host_password, logger, block=False, timeout=None):
logger.info("Inside _run_command_get_all_lines")
all_lines = []
for command in commands:
logger.info(" Executing.." + str(command))
child = pexpect.spawn(command)
child.timeout=timeout
try:
i = child.expect(['password: ','Connection refused\r\r\n'], timeout=timeout)
if i == 0:
child.sendline(host_password)
all_lines = child.read()
all_lines = all_lines.rstrip().lstrip()
all_lines = all_lines.decode('utf-8').replace('\r\n', '\n')
logger.info(all_lines)
if i == 1:
logger.info("Connection refused")
except:
logger.info(str(child))
return all_lines
def _run_command_get_output(self, commands, host_password, logger, block=False, timeout=None):
successful = False
value_to_return = ''
logger.info("Inside _run_command_get_output")
for command in commands:
logger.info(" Executing.." + str(command))
child = pexpect.spawn(command)
child.timeout=timeout
try:
child.expect(['password: '], timeout=timeout)
child.sendline(host_password)
all_lines = child.read()
all_lines = all_lines.rstrip().lstrip()
all_lines = all_lines.decode('utf-8').replace('\r\n', '\n')
successful = True # Tentative
for line in all_lines.split("\n"):
logger.info(line)
if value_to_return == '':
value_to_return = line.strip()
if re.search('error', line, re.IGNORECASE):
successful = False
if re.search('unable', line, re.IGNORECASE):
successful = False
except:
logger.info(str(child))
logger.info("Status:" + str(successful) + " value_to_return:" + value_to_return)
return successful, value_to_return
def _get_remote_region_oam_ip(self, cluster_name, logger):
remoteclusterObj = Cluster.objects.filter(cluster_name=cluster_name)
oam_ip = remoteclusterObj[0].oam_vip_address
logger.info(" Remote region:" + cluster_name + " OAM IP:" + str(oam_ip))
return oam_ip
def _get_central_region_name(self, oam_vip_address, logger):
logger.info("1")
remoteclusterObj = Cluster.objects.filter(oam_vip_address=oam_vip_address)
logger.info("2")
logger.info(remoteclusterObj)
cluster_name = remoteclusterObj[0].cluster_name
logger.info(" Remote region:" + str(oam_vip_address) + " Cluster Name:" + str(cluster_name))
return cluster_name
def _get_namespace(self, region, logger):
# Lookup database and findout namespace given region
logger.info(" Inside _get_namespace")
remoteclusterObj = Cluster.objects.filter(cluster_name=region)
if len(remoteclusterObj) > 0:
logger.info(" RemoteClusterObj:" + str(remoteclusterObj))
namespace_id = remoteclusterObj[0].namespace_id
logger.info(" Namespace id:" + str(namespace_id))
namespaceObj = Namespace.objects.filter(id=namespace_id)
logger.info(" NamespaceObj:" + str(namespaceObj))
namespace_name = namespaceObj[0].namespace_name
logger.info(" Remote region:" + region + " Namespace:" + namespace_name)
return namespace_name
else:
return ""
def _get_central_region_oam_ip(self, remoteregion, transaction_id):
remoteclusterObj = Cluster.objects.filter(cluster_name=remoteregion)
parent_cluster_id = remoteclusterObj[0].parent_cluster_id
self.logger.info(str(transaction_id) + " Parent cluster id.." + str(parent_cluster_id))
centralclusterObj = Cluster.objects.filter(id=parent_cluster_id)
self.logger.info(str(transaction_id) + " " + str(centralclusterObj))
central_region_list = []
for central_region in centralclusterObj:
central_region_list.append(central_region.oam_vip_address)
self.logger.info(str(transaction_id) + " Central Region List:" + ','.join(central_region_list))
return central_region_list
def get_fuze_spm_site_details(self, cluster_name, logger):
fuze_spm_site_name = ''
fuze_spm_site_id = ''
logger.info(" Inside _get_fuze_spm_site_name " + str(cluster_name))
remoteclusterObj = Cluster.objects.filter(cluster_name=cluster_name)
if len(remoteclusterObj) > 0:
fuze_id = remoteclusterObj[0].location_id
locationObj = Location.objects.filter(id=fuze_id)
if len(locationObj) > 0:
fuze_spm_site_name = locationObj[0].fuze_spm_site_name
fuze_spm_site_id = locationObj[0].fuze_spm_site_id
logger.info(" Fuze site name:" + fuze_spm_site_name)
logger.info(" Fuze site id:" + fuze_spm_site_id)
return fuze_spm_site_name, fuze_spm_site_id
def check_namespaces(self, remote_region_oam_ip, logger):
host_username, host_password, ssh_prefix = get_host_connection_details(remote_region_oam_ip)
cmds = []
cmds.append(ssh_prefix + " kubectl get namespaces --kubeconfig=/etc/kubernetes/admin.conf ")
output_lines = self._run_command_get_all_lines(cmds, host_password, logger, block=True)
#logger.info("Returned output lines:")
#logger.info(output_lines)
new_op_lines = []
for line in output_lines.split("\n"):
if not 'Connection to' in line:
new_op_lines.append(line)
return new_op_lines
def check_namespace_secrets(self, region, remote_region_oam_ip, logger):
namespace = self._get_namespace(region, logger)
host_username, host_password, ssh_prefix = get_host_connection_details(remote_region_oam_ip)
cmds = []
cmds.append(ssh_prefix + " kubectl get secrets --kubeconfig=/etc/kubernetes/admin.conf -n " + namespace)
output_lines = self._run_command_get_all_lines(cmds, host_password, logger, block=True)
#logger.info("Returned output lines:")
#logger.info(output_lines)
new_op_lines = []
for line in output_lines.split("\n"):
if not 'Connection to' in line:
new_op_lines.append(line)
return new_op_lines
def check_namespace_serviceaccounts(self, region, remote_region_oam_ip, logger):
namespace = self._get_namespace(region, logger)
host_username, host_password, ssh_prefix = get_host_connection_details(remote_region_oam_ip)
cmds = []
cmds.append(ssh_prefix + " kubectl get serviceaccounts --kubeconfig=/etc/kubernetes/admin.conf -n " + namespace)
output_lines = self._run_command_get_all_lines(cmds, host_password, logger, block=True)
#logger.info("Returned output lines:")
#logger.info(output_lines)
new_op_lines = []
for line in output_lines.split("\n"):
if not 'Connection to' in line:
new_op_lines.append(line)
return new_op_lines
def check_online_status(self, region, remote_region_oam_ip, logger):
host_username, host_password, ssh_prefix = get_host_connection_details(remote_region_oam_ip)
central_region_list = self._get_central_region_oam_ip(region, "-1")
region_online_status = []
new_op_lines = []
for central_region_ip in central_region_list:
cmds = []
cmd = 'ssh -o StrictHostKeyChecking=no -t ' + host_username + '@' + central_region_ip + ' ' + '"source /etc/platform/openrc; dcmanager subcloud list | grep ' + region + '"'
cmds.append(cmd)
output_lines = self._run_command_get_all_lines(cmds, host_password, logger, block=True)
logger.info(output_lines)
for line in output_lines.split("\n"):
if not 'Connection to' in line:
new_op_lines.append(line)
return new_op_lines
def create_host_network(self, remote_region_oam_ip, logger):
logger.info("Inside _create_host_network")
#host_username = settings.HOST_CREDS['username']
#host_password = settings.HOST_CREDS['password']
#ssh_prefix = 'ssh -o StrictHostKeyChecking=no -t ' + host_username + '@' + remote_region_oam_ip
host_username, host_password, ssh_prefix = get_host_connection_details(remote_region_oam_ip)
env_string = self._read_remote_openrc(remote_region_oam_ip, logger)
#basecmd = " OS_ENDPOINT_TYPE=internalURL CINDER_ENDPOINT_TYPE=internalURL OS_USERNAME=admin"
#basecmd = basecmd + " OS_PASSWORD=`TERM=linux /opt/platform/.keyring/20.06/.CREDENTIAL 2>/dev/null`"
#basecmd = basecmd + " OS_AUTH_TYPE=password OS_AUTH_URL=http://[fd00:4888:2000:120b::220]:5000/v3"
#basecmd = basecmd + " OS_PROJECT_NAME=admin OS_USER_DOMAIN_NAME=Default OS_PROJECT_DOMAIN_NAME=Default"
#basecmd = basecmd + " OS_IDENTITY_API_VERSION=3 OS_REGION_NAME=subcloud2 OS_INTERFACE=internal"
basecmd = env_string
cmds = ["system host-lock controller-0",
"system host-if-modify -n f1u -c pci-sriov --num-vfs 8 controller-0 ens3f1 --vf-driver=vfio",
"system host-if-add -c pci-sriov controller-0 f1c vf f1u --num-vfs 4 --vf-driver=netdevice",
"system host-if-modify controller-0 f1u --imtu=1956",
"system host-if-modify controller-0 f1c --imtu=1956",
"system datanetwork-add f1u vlan --mtu=1956",
"system datanetwork-add f1c vlan --mtu=1956",
"system interface-datanetwork-assign controller-0 f1u f1u",
"system interface-datanetwork-assign controller-0 f1c f1c",
"system host-if-add -c pci-sriov controller-0 fh0m vf fh0 --num-vfs 4 --vf-driver=netdevice",
"system host-if-modify controller-0 fh0m --imtu=9000",
"system datanetwork-add fh0m flat",
"system interface-datanetwork-assign controller-0 fh0m fh0m",
"system host-if-modify -n fh1 -c pci-sriov --num-vfs 8 controller-0 enp181s0f0 --vf-driver=vfio",
"system host-if-modify controller-0 fh1 --imtu=9000",
"system datanetwork-add fh1 vlan --mtu=9000",
"system interface-datanetwork-assign controller-0 fh1 fh1"]
# New steps proposed by Eddy - These do not seem to create fh0m so commenting out.
#cmds = ["system host-lock controller-0",
# "system host-if-modify -n f1c -c pci-sriov --num-vfs 8 controller-0 ens3f1 --vf-driver=netdevice",
# "system host-if-add -c pci-sriov controller-0 f1u vf f1c --num-vfs 4 --vf-driver=vfio",
# "system host-if-modify controller-0 f1u --imtu=1956",
# "system host-if-modify controller-0 f1c --imtu=1956",
# "system datanetwork-add f1u vlan --mtu=1956",
# "system datanetwork-add f1c vlan --mtu=1956",
# "system interface-datanetwork-assign controller-0 f1u f1u",
# "system interface-datanetwork-assign controller-0 f1c f1c",
# # this one is wrong as well but for some reason I think the fh0 is setup in Carlos deployment config. So we have to delete the fh0 and recreate both.
# "system host-if-modify controller0 fh0 -nc none"
# "system host-if-modify -n fh0m -c pci-sriov --num-vfs 8 controller-0 ens179s0f0 --vf-driver=netdevice",
# "system host-if-add -c pci-sriov controller-0 fh0 vf fh0m --num-vfs 4 --vf-driver=vfio",
# "system host-if-modify controller-0 fh0m --imtu=9000",
# "system datanetwork-add fh0m flat",
# "system interface-datanetwork-assign controller-0 fh0m fh0m",
# "system host-if-modify -n fh1 -c pci-sriov --num-vfs 8 controller-0 enp181s0f0 --vf-driver=vfio",
# "system host-if-modify controller-0 fh1 --imtu=9000",
# "system datanetwork-add fh1 vlan --mtu=9000",
# "system interface-datanetwork-assign controller-0 fh1 fh1"]
for cmd in cmds:
cmd_to_run = ssh_prefix + " " + basecmd + " " + cmd
logger.info(cmd_to_run)
run_commands([cmd_to_run], host_password, logger, block=True)
# host_network_configured = False
# while not host_network_configured:
# host_network_configured = self._verify_host_network(ssh_prefix, basecmd, host_password, logger)
# if not host_network_configured:
# cmds = ["system host-lock controller-0"]
# for cmd in cmds:
# cmd_to_run = ssh_prefix + " " + basecmd + " " + cmd
# logger.info(cmd_to_run)
# output_lines = self._run_command_get_all_lines([cmd_to_run], host_password, logger, block=True)
# logger.info("Returned output lines:")
# logger.info(output_lines)
# time.sleep(3)
cmds = ["system host-unlock controller-0"]
while True:
unlock_wait = False
for cmd in cmds:
cmd_to_run = ssh_prefix + " " + basecmd + " " + cmd
logger.info(cmd_to_run)
output_lines = self._run_command_get_all_lines([cmd_to_run], host_password, logger, block=True)
logger.info("Returned output lines:")
logger.info(output_lines)
if len(output_lines) > 0:
for line in output_lines.split("\n"):
logger.info("Line:" + line)
if not unlock_wait:
if 'retry host-unlock' in line or 'Rejected' in line:
logger.info("Need to wait to call host-unlock ##### ")
unlock_wait = True
break
if unlock_wait:
time.sleep(60)
else:
break
# for cmd in cmds:
# cmd_to_run = ssh_prefix + " " + basecmd + " " + cmd
# logger.info(cmd_to_run)
# output_lines = self._run_command_get_all_lines([cmd_to_run], host_password, logger, block=True)
# logger.info("Returned output lines:")
# logger.info(output_lines)
logger.info("Done setting up host network")
|