1 # -*- coding: utf-8 -*-
4 # Copyright 2018 Telefonica S.A.
6 # Licensed under the Apache License, Version 2.0 (the "License"); you may
7 # not use this file except in compliance with the License. You may obtain
8 # a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15 # License for the specific language governing permissions and limitations
21 import logging
.handlers
23 from lcm_utils
import LcmException
, LcmBase
24 from osm_common
.dbbase
import DbException
25 from copy
import deepcopy
27 __author__
= "Alfonso Tierno"
30 class VimLcm(LcmBase
):
31 # values that are encrypted at vim config because they are passwords
32 vim_config_encrypted
= ("admin_password", "nsx_password", "vcenter_password")
34 def __init__(self
, db
, msg
, fs
, lcm_tasks
, ro_config
, loop
):
36 Init, Connect to database, filesystem storage, and messaging
37 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
41 self
.logger
= logging
.getLogger('lcm.vim')
43 self
.lcm_tasks
= lcm_tasks
44 self
.ro_config
= ro_config
46 super().__init
__(db
, msg
, fs
, self
.logger
)
48 async def create(self
, vim_content
, order_id
):
49 vim_id
= vim_content
["_id"]
50 logging_text
= "Task vim_create={} ".format(vim_id
)
51 self
.logger
.debug(logging_text
+ "Enter")
57 step
= "Getting vim-id='{}' from db".format(vim_id
)
58 db_vim
= self
.db
.get_one("vim_accounts", {"_id": vim_id
})
59 if vim_content
.get("config") and vim_content
["config"].get("sdn-controller"):
60 step
= "Getting sdn-controller-id='{}' from db".format(vim_content
["config"]["sdn-controller"])
61 db_sdn
= self
.db
.get_one("sdns", {"_id": vim_content
["config"]["sdn-controller"]})
62 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get("RO"):
63 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
65 raise LcmException("sdn-controller={} is not available. Not deployed at RO".format(
66 vim_content
["config"]["sdn-controller"]))
68 step
= "Creating vim at RO"
69 db_vim_update
["_admin.deployed.RO"] = None
70 db_vim_update
["_admin.detailed-status"] = step
71 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
72 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
73 vim_RO
= deepcopy(vim_content
)
74 vim_RO
.pop("_id", None)
75 vim_RO
.pop("_admin", None)
76 schema_version
= vim_RO
.pop("schema_version", None)
77 vim_RO
.pop("schema_type", None)
78 vim_RO
.pop("vim_tenant_name", None)
79 vim_RO
["type"] = vim_RO
.pop("vim_type")
80 vim_RO
.pop("vim_user", None)
81 vim_RO
.pop("vim_password", None)
83 vim_RO
["config"]["sdn-controller"] = RO_sdn_id
84 desc
= await RO
.create("vim", descriptor
=vim_RO
)
85 RO_vim_id
= desc
["uuid"]
86 db_vim_update
["_admin.deployed.RO"] = RO_vim_id
87 self
.logger
.debug(logging_text
+ "VIM created at RO_vim_id={}".format(RO_vim_id
))
89 step
= "Creating vim_account at RO"
90 db_vim_update
["_admin.detailed-status"] = step
91 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
93 if vim_content
.get("vim_password"):
94 vim_content
["vim_password"] = self
.db
.decrypt(vim_content
["vim_password"],
95 schema_version
=schema_version
,
97 vim_account_RO
= {"vim_tenant_name": vim_content
["vim_tenant_name"],
98 "vim_username": vim_content
["vim_user"],
99 "vim_password": vim_content
["vim_password"]
101 if vim_RO
.get("config"):
102 vim_account_RO
["config"] = vim_RO
["config"]
103 if "sdn-controller" in vim_account_RO
["config"]:
104 del vim_account_RO
["config"]["sdn-controller"]
105 if "sdn-port-mapping" in vim_account_RO
["config"]:
106 del vim_account_RO
["config"]["sdn-port-mapping"]
107 for p
in self
.vim_config_encrypted
:
108 if vim_account_RO
["config"].get(p
):
109 vim_account_RO
["config"][p
] = self
.db
.decrypt(vim_account_RO
["config"][p
],
110 schema_version
=schema_version
,
113 desc
= await RO
.attach("vim_account", RO_vim_id
, descriptor
=vim_account_RO
)
114 db_vim_update
["_admin.deployed.RO-account"] = desc
["uuid"]
115 db_vim_update
["_admin.operationalState"] = "ENABLED"
116 db_vim_update
["_admin.detailed-status"] = "Done"
118 # await asyncio.sleep(15) # TODO remove. This is for test
119 self
.logger
.debug(logging_text
+ "Exit Ok VIM account created at RO_vim_account_id={}".format(desc
["uuid"]))
122 except (ROclient
.ROClientException
, DbException
) as e
:
123 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
125 except Exception as e
:
126 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
130 db_vim_update
["_admin.operationalState"] = "ERROR"
131 db_vim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
134 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
135 except DbException
as e
:
136 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
138 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
140 async def edit(self
, vim_content
, order_id
):
141 vim_id
= vim_content
["_id"]
142 logging_text
= "Task vim_edit={} ".format(vim_id
)
143 self
.logger
.debug(logging_text
+ "Enter")
149 step
= "Getting vim-id='{}' from db".format(vim_id
)
151 db_vim
= self
.db
.get_one("vim_accounts", {"_id": vim_id
})
153 # look if previous tasks in process
154 task_name
, task_dependency
= self
.lcm_tasks
.lookfor_related("vim_account", vim_id
, order_id
)
156 step
= "Waiting for related tasks to be completed: {}".format(task_name
)
157 self
.logger
.debug(logging_text
+ step
)
158 # TODO write this to database
159 _
, pending
= await asyncio
.wait(task_dependency
, timeout
=3600)
161 raise LcmException("Timeout waiting related tasks to be completed")
163 if db_vim
.get("_admin") and db_vim
["_admin"].get("deployed") and db_vim
["_admin"]["deployed"].get("RO"):
164 if vim_content
.get("config") and vim_content
["config"].get("sdn-controller"):
165 step
= "Getting sdn-controller-id='{}' from db".format(vim_content
["config"]["sdn-controller"])
166 db_sdn
= self
.db
.get_one("sdns", {"_id": vim_content
["config"]["sdn-controller"]})
168 # look if previous tasks in process
169 task_name
, task_dependency
= self
.lcm_tasks
.lookfor_related("sdn", db_sdn
["_id"])
171 step
= "Waiting for related tasks to be completed: {}".format(task_name
)
172 self
.logger
.debug(logging_text
+ step
)
173 # TODO write this to database
174 _
, pending
= await asyncio
.wait(task_dependency
, timeout
=3600)
176 raise LcmException("Timeout waiting related tasks to be completed")
178 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get(
180 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
182 raise LcmException("sdn-controller={} is not available. Not deployed at RO".format(
183 vim_content
["config"]["sdn-controller"]))
185 RO_vim_id
= db_vim
["_admin"]["deployed"]["RO"]
186 step
= "Editing vim at RO"
187 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
188 vim_RO
= deepcopy(vim_content
)
189 vim_RO
.pop("_id", None)
190 vim_RO
.pop("_admin", None)
191 schema_version
= vim_RO
.pop("schema_version", None)
192 vim_RO
.pop("schema_type", None)
193 vim_RO
.pop("vim_tenant_name", None)
194 if "vim_type" in vim_RO
:
195 vim_RO
["type"] = vim_RO
.pop("vim_type")
196 vim_RO
.pop("vim_user", None)
197 vim_RO
.pop("vim_password", None)
199 vim_RO
["config"]["sdn-controller"] = RO_sdn_id
200 # TODO make a deep update of sdn-port-mapping
202 await RO
.edit("vim", RO_vim_id
, descriptor
=vim_RO
)
204 step
= "Editing vim-account at RO tenant"
206 if "config" in vim_content
:
207 if "sdn-controller" in vim_content
["config"]:
208 del vim_content
["config"]["sdn-controller"]
209 if "sdn-port-mapping" in vim_content
["config"]:
210 del vim_content
["config"]["sdn-port-mapping"]
211 if not vim_content
["config"]:
212 del vim_content
["config"]
213 if "vim_tenant_name" in vim_content
:
214 vim_account_RO
["vim_tenant_name"] = vim_content
["vim_tenant_name"]
215 if "vim_password" in vim_content
:
216 vim_account_RO
["vim_password"] = vim_content
["vim_password"]
217 if vim_content
.get("vim_password"):
218 vim_account_RO
["vim_password"] = self
.db
.decrypt(vim_content
["vim_password"],
219 schema_version
=schema_version
,
221 if "config" in vim_content
:
222 vim_account_RO
["config"] = vim_content
["config"]
223 if vim_content
.get("config"):
224 for p
in self
.vim_config_encrypted
:
225 if vim_content
["config"].get(p
):
226 vim_account_RO
["config"][p
] = self
.db
.decrypt(vim_content
["config"][p
],
227 schema_version
=schema_version
,
230 if "vim_user" in vim_content
:
231 vim_content
["vim_username"] = vim_content
["vim_user"]
232 # vim_account must be edited always even if empty in order to ensure changes are translated to RO
233 # vim_thread. RO will remove and relaunch a new thread for this vim_account
234 await RO
.edit("vim_account", RO_vim_id
, descriptor
=vim_account_RO
)
235 db_vim_update
["_admin.operationalState"] = "ENABLED"
237 self
.logger
.debug(logging_text
+ "Exit Ok RO_vim_id={}".format(RO_vim_id
))
240 except (ROclient
.ROClientException
, DbException
) as e
:
241 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
243 except Exception as e
:
244 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
248 db_vim_update
["_admin.operationalState"] = "ERROR"
249 db_vim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
252 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
253 except DbException
as e
:
254 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
256 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
258 async def delete(self
, vim_id
, order_id
):
259 logging_text
= "Task vim_delete={} ".format(vim_id
)
260 self
.logger
.debug(logging_text
+ "Enter")
264 step
= "Getting vim from db"
266 db_vim
= self
.db
.get_one("vim_accounts", {"_id": vim_id
})
267 if db_vim
.get("_admin") and db_vim
["_admin"].get("deployed") and db_vim
["_admin"]["deployed"].get("RO"):
268 RO_vim_id
= db_vim
["_admin"]["deployed"]["RO"]
269 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
270 step
= "Detaching vim from RO tenant"
272 await RO
.detach("vim_account", RO_vim_id
)
273 except ROclient
.ROClientException
as e
:
274 if e
.http_code
== 404: # not found
275 self
.logger
.debug(logging_text
+ "RO_vim_id={} already detached".format(RO_vim_id
))
279 step
= "Deleting vim from RO"
281 await RO
.delete("vim", RO_vim_id
)
282 except ROclient
.ROClientException
as e
:
283 if e
.http_code
== 404: # not found
284 self
.logger
.debug(logging_text
+ "RO_vim_id={} already deleted".format(RO_vim_id
))
289 self
.logger
.error(logging_text
+ "Nohing to remove at RO")
290 self
.db
.del_one("vim_accounts", {"_id": vim_id
})
292 self
.logger
.debug(logging_text
+ "Exit Ok")
295 except (ROclient
.ROClientException
, DbException
) as e
:
296 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
298 except Exception as e
:
299 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
302 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
304 db_vim_update
["_admin.operationalState"] = "ERROR"
305 db_vim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
307 if db_vim
and db_vim_update
:
308 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
309 except DbException
as e
:
310 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
311 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
314 class WimLcm(LcmBase
):
315 # values that are encrypted at wim config because they are passwords
316 wim_config_encrypted
= ()
318 def __init__(self
, db
, msg
, fs
, lcm_tasks
, ro_config
, loop
):
320 Init, Connect to database, filesystem storage, and messaging
321 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
325 self
.logger
= logging
.getLogger('lcm.vim')
327 self
.lcm_tasks
= lcm_tasks
328 self
.ro_config
= ro_config
330 super().__init
__(db
, msg
, fs
, self
.logger
)
332 async def create(self
, wim_content
, order_id
):
333 wim_id
= wim_content
["_id"]
334 logging_text
= "Task wim_create={} ".format(wim_id
)
335 self
.logger
.debug(logging_text
+ "Enter")
340 step
= "Getting wim-id='{}' from db".format(wim_id
)
341 db_wim
= self
.db
.get_one("wim_accounts", {"_id": wim_id
})
342 db_wim_update
["_admin.deployed.RO"] = None
344 step
= "Creating wim at RO"
345 db_wim_update
["_admin.detailed-status"] = step
346 self
.update_db_2("wim_accounts", wim_id
, db_wim_update
)
347 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
348 wim_RO
= deepcopy(wim_content
)
349 wim_RO
.pop("_id", None)
350 wim_RO
.pop("_admin", None)
351 schema_version
= wim_RO
.pop("schema_version", None)
352 wim_RO
.pop("schema_type", None)
353 wim_RO
.pop("wim_tenant_name", None)
354 wim_RO
["type"] = wim_RO
.pop("wim_type")
355 wim_RO
.pop("wim_user", None)
356 wim_RO
.pop("wim_password", None)
357 desc
= await RO
.create("wim", descriptor
=wim_RO
)
358 RO_wim_id
= desc
["uuid"]
359 db_wim_update
["_admin.deployed.RO"] = RO_wim_id
360 self
.logger
.debug(logging_text
+ "WIM created at RO_wim_id={}".format(RO_wim_id
))
362 step
= "Creating wim_account at RO"
363 db_wim_update
["_admin.detailed-status"] = step
364 self
.update_db_2("wim_accounts", wim_id
, db_wim_update
)
366 if wim_content
.get("wim_password"):
367 wim_content
["wim_password"] = self
.db
.decrypt(wim_content
["wim_password"],
368 schema_version
=schema_version
,
370 wim_account_RO
= {"name": wim_content
["name"],
371 "user": wim_content
["user"],
372 "password": wim_content
["password"]
374 if wim_RO
.get("config"):
375 wim_account_RO
["config"] = wim_RO
["config"]
376 if "wim_port_mapping" in wim_account_RO
["config"]:
377 del wim_account_RO
["config"]["wim_port_mapping"]
378 for p
in self
.wim_config_encrypted
:
379 if wim_account_RO
["config"].get(p
):
380 wim_account_RO
["config"][p
] = self
.db
.decrypt(wim_account_RO
["config"][p
],
381 schema_version
=schema_version
,
384 desc
= await RO
.attach("wim_account", RO_wim_id
, descriptor
=wim_account_RO
)
385 db_wim_update
["_admin.deployed.RO-account"] = desc
["uuid"]
386 db_wim_update
["_admin.operationalState"] = "ENABLED"
387 db_wim_update
["_admin.detailed-status"] = "Done"
389 self
.logger
.debug(logging_text
+ "Exit Ok WIM account created at RO_wim_account_id={}".format(desc
["uuid"]))
392 except (ROclient
.ROClientException
, DbException
) as e
:
393 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
395 except Exception as e
:
396 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
400 db_wim_update
["_admin.operationalState"] = "ERROR"
401 db_wim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
404 self
.update_db_2("wim_accounts", wim_id
, db_wim_update
)
405 except DbException
as e
:
406 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
407 self
.lcm_tasks
.remove("wim_account", wim_id
, order_id
)
409 async def edit(self
, wim_content
, order_id
):
410 wim_id
= wim_content
["_id"]
411 logging_text
= "Task wim_edit={} ".format(wim_id
)
412 self
.logger
.debug(logging_text
+ "Enter")
417 step
= "Getting wim-id='{}' from db".format(wim_id
)
419 db_wim
= self
.db
.get_one("wim_accounts", {"_id": wim_id
})
421 # look if previous tasks in process
422 task_name
, task_dependency
= self
.lcm_tasks
.lookfor_related("wim_account", wim_id
, order_id
)
424 step
= "Waiting for related tasks to be completed: {}".format(task_name
)
425 self
.logger
.debug(logging_text
+ step
)
426 # TODO write this to database
427 _
, pending
= await asyncio
.wait(task_dependency
, timeout
=3600)
429 raise LcmException("Timeout waiting related tasks to be completed")
431 if db_wim
.get("_admin") and db_wim
["_admin"].get("deployed") and db_wim
["_admin"]["deployed"].get("RO"):
433 RO_wim_id
= db_wim
["_admin"]["deployed"]["RO"]
434 step
= "Editing wim at RO"
435 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
436 wim_RO
= deepcopy(wim_content
)
437 wim_RO
.pop("_id", None)
438 wim_RO
.pop("_admin", None)
439 schema_version
= wim_RO
.pop("schema_version", None)
440 wim_RO
.pop("schema_type", None)
441 wim_RO
.pop("wim_tenant_name", None)
442 if "wim_type" in wim_RO
:
443 wim_RO
["type"] = wim_RO
.pop("wim_type")
444 wim_RO
.pop("wim_user", None)
445 wim_RO
.pop("wim_password", None)
446 # TODO make a deep update of wim_port_mapping
448 await RO
.edit("wim", RO_wim_id
, descriptor
=wim_RO
)
450 step
= "Editing wim-account at RO tenant"
452 if "config" in wim_content
:
453 if "wim_port_mapping" in wim_content
["config"]:
454 del wim_content
["config"]["wim_port_mapping"]
455 if not wim_content
["config"]:
456 del wim_content
["config"]
457 if "wim_tenant_name" in wim_content
:
458 wim_account_RO
["wim_tenant_name"] = wim_content
["wim_tenant_name"]
459 if "wim_password" in wim_content
:
460 wim_account_RO
["wim_password"] = wim_content
["wim_password"]
461 if wim_content
.get("wim_password"):
462 wim_account_RO
["wim_password"] = self
.db
.decrypt(wim_content
["wim_password"],
463 schema_version
=schema_version
,
465 if "config" in wim_content
:
466 wim_account_RO
["config"] = wim_content
["config"]
467 if wim_content
.get("config"):
468 for p
in self
.wim_config_encrypted
:
469 if wim_content
["config"].get(p
):
470 wim_account_RO
["config"][p
] = self
.db
.decrypt(wim_content
["config"][p
],
471 schema_version
=schema_version
,
474 if "wim_user" in wim_content
:
475 wim_content
["wim_username"] = wim_content
["wim_user"]
476 # wim_account must be edited always even if empty in order to ensure changes are translated to RO
477 # wim_thread. RO will remove and relaunch a new thread for this wim_account
478 await RO
.edit("wim_account", RO_wim_id
, descriptor
=wim_account_RO
)
479 db_wim_update
["_admin.operationalState"] = "ENABLED"
481 self
.logger
.debug(logging_text
+ "Exit Ok RO_wim_id={}".format(RO_wim_id
))
484 except (ROclient
.ROClientException
, DbException
) as e
:
485 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
487 except Exception as e
:
488 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
492 db_wim_update
["_admin.operationalState"] = "ERROR"
493 db_wim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
496 self
.update_db_2("wim_accounts", wim_id
, db_wim_update
)
497 except DbException
as e
:
498 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
499 self
.lcm_tasks
.remove("wim_account", wim_id
, order_id
)
501 async def delete(self
, wim_id
, order_id
):
502 logging_text
= "Task wim_delete={} ".format(wim_id
)
503 self
.logger
.debug(logging_text
+ "Enter")
507 step
= "Getting wim from db"
509 db_wim
= self
.db
.get_one("wim_accounts", {"_id": wim_id
})
510 if db_wim
.get("_admin") and db_wim
["_admin"].get("deployed") and db_wim
["_admin"]["deployed"].get("RO"):
511 RO_wim_id
= db_wim
["_admin"]["deployed"]["RO"]
512 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
513 step
= "Detaching wim from RO tenant"
515 await RO
.detach("wim_account", RO_wim_id
)
516 except ROclient
.ROClientException
as e
:
517 if e
.http_code
== 404: # not found
518 self
.logger
.debug(logging_text
+ "RO_wim_id={} already detached".format(RO_wim_id
))
522 step
= "Deleting wim from RO"
524 await RO
.delete("wim", RO_wim_id
)
525 except ROclient
.ROClientException
as e
:
526 if e
.http_code
== 404: # not found
527 self
.logger
.debug(logging_text
+ "RO_wim_id={} already deleted".format(RO_wim_id
))
532 self
.logger
.error(logging_text
+ "Nohing to remove at RO")
533 self
.db
.del_one("wim_accounts", {"_id": wim_id
})
535 self
.logger
.debug(logging_text
+ "Exit Ok")
538 except (ROclient
.ROClientException
, DbException
) as e
:
539 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
541 except Exception as e
:
542 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
545 self
.lcm_tasks
.remove("wim_account", wim_id
, order_id
)
547 db_wim_update
["_admin.operationalState"] = "ERROR"
548 db_wim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
550 if db_wim
and db_wim_update
:
551 self
.update_db_2("wim_accounts", wim_id
, db_wim_update
)
552 except DbException
as e
:
553 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
554 self
.lcm_tasks
.remove("wim_account", wim_id
, order_id
)
557 class SdnLcm(LcmBase
):
559 def __init__(self
, db
, msg
, fs
, lcm_tasks
, ro_config
, loop
):
561 Init, Connect to database, filesystem storage, and messaging
562 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
566 self
.logger
= logging
.getLogger('lcm.sdn')
568 self
.lcm_tasks
= lcm_tasks
569 self
.ro_config
= ro_config
571 super().__init
__(db
, msg
, fs
, self
.logger
)
573 async def create(self
, sdn_content
, order_id
):
574 sdn_id
= sdn_content
["_id"]
575 logging_text
= "Task sdn_create={} ".format(sdn_id
)
576 self
.logger
.debug(logging_text
+ "Enter")
582 step
= "Getting sdn from db"
583 db_sdn
= self
.db
.get_one("sdns", {"_id": sdn_id
})
584 db_sdn_update
["_admin.deployed.RO"] = None
586 step
= "Creating sdn at RO"
587 db_sdn_update
["_admin.detailed-status"] = step
588 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
590 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
591 sdn_RO
= deepcopy(sdn_content
)
592 sdn_RO
.pop("_id", None)
593 sdn_RO
.pop("_admin", None)
594 schema_version
= sdn_RO
.pop("schema_version", None)
595 sdn_RO
.pop("schema_type", None)
596 sdn_RO
.pop("description", None)
597 if sdn_RO
.get("password"):
598 sdn_RO
["password"] = self
.db
.decrypt(sdn_RO
["password"], schema_version
=schema_version
, salt
=sdn_id
)
600 desc
= await RO
.create("sdn", descriptor
=sdn_RO
)
601 RO_sdn_id
= desc
["uuid"]
602 db_sdn_update
["_admin.deployed.RO"] = RO_sdn_id
603 db_sdn_update
["_admin.operationalState"] = "ENABLED"
604 self
.logger
.debug(logging_text
+ "Exit Ok RO_sdn_id={}".format(RO_sdn_id
))
607 except (ROclient
.ROClientException
, DbException
) as e
:
608 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
610 except Exception as e
:
611 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
615 db_sdn_update
["_admin.operationalState"] = "ERROR"
616 db_sdn_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
618 if db_sdn
and db_sdn_update
:
619 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
620 except DbException
as e
:
621 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
622 self
.lcm_tasks
.remove("sdn", sdn_id
, order_id
)
624 async def edit(self
, sdn_content
, order_id
):
625 sdn_id
= sdn_content
["_id"]
626 logging_text
= "Task sdn_edit={} ".format(sdn_id
)
627 self
.logger
.debug(logging_text
+ "Enter")
631 step
= "Getting sdn from db"
633 db_sdn
= self
.db
.get_one("sdns", {"_id": sdn_id
})
635 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get("RO"):
636 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
637 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
638 step
= "Editing sdn at RO"
639 sdn_RO
= deepcopy(sdn_content
)
640 sdn_RO
.pop("_id", None)
641 sdn_RO
.pop("_admin", None)
642 schema_version
= sdn_RO
.pop("schema_version", None)
643 sdn_RO
.pop("schema_type", None)
644 sdn_RO
.pop("description", None)
645 if sdn_RO
.get("password"):
646 sdn_RO
["password"] = self
.db
.decrypt(sdn_RO
["password"], schema_version
=schema_version
, salt
=sdn_id
)
648 await RO
.edit("sdn", RO_sdn_id
, descriptor
=sdn_RO
)
649 db_sdn_update
["_admin.operationalState"] = "ENABLED"
651 self
.logger
.debug(logging_text
+ "Exit Ok RO_sdn_id={}".format(RO_sdn_id
))
654 except (ROclient
.ROClientException
, DbException
) as e
:
655 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
657 except Exception as e
:
658 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
662 db_sdn
["_admin.operationalState"] = "ERROR"
663 db_sdn
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
666 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
667 except DbException
as e
:
668 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
669 self
.lcm_tasks
.remove("sdn", sdn_id
, order_id
)
671 async def delete(self
, sdn_id
, order_id
):
672 logging_text
= "Task sdn_delete={} ".format(sdn_id
)
673 self
.logger
.debug(logging_text
+ "Enter")
677 step
= "Getting sdn from db"
679 db_sdn
= self
.db
.get_one("sdns", {"_id": sdn_id
})
680 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get("RO"):
681 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
682 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
683 step
= "Deleting sdn from RO"
685 await RO
.delete("sdn", RO_sdn_id
)
686 except ROclient
.ROClientException
as e
:
687 if e
.http_code
== 404: # not found
688 self
.logger
.debug(logging_text
+ "RO_sdn_id={} already deleted".format(RO_sdn_id
))
693 self
.logger
.error(logging_text
+ "Skipping. There is not RO information at database")
694 self
.db
.del_one("sdns", {"_id": sdn_id
})
696 self
.logger
.debug("sdn_delete task sdn_id={} Exit Ok".format(sdn_id
))
699 except (ROclient
.ROClientException
, DbException
) as e
:
700 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
702 except Exception as e
:
703 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
707 db_sdn
["_admin.operationalState"] = "ERROR"
708 db_sdn
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
710 if db_sdn
and db_sdn_update
:
711 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
712 except DbException
as e
:
713 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
714 self
.lcm_tasks
.remove("sdn", sdn_id
, order_id
)