2 # -*- coding: utf-8 -*-
6 import logging
.handlers
8 from lcm_utils
import LcmException
, LcmBase
9 from osm_common
.dbbase
import DbException
10 from copy
import deepcopy
12 __author__
= "Alfonso Tierno"
15 class VimLcm(LcmBase
):
17 def __init__(self
, db
, msg
, fs
, lcm_tasks
, ro_config
, loop
):
19 Init, Connect to database, filesystem storage, and messaging
20 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
24 self
.logger
= logging
.getLogger('lcm.vim')
26 self
.lcm_tasks
= lcm_tasks
27 self
.ro_config
= ro_config
29 super().__init
__(db
, msg
, fs
, self
.logger
)
31 async def create(self
, vim_content
, order_id
):
32 vim_id
= vim_content
["_id"]
33 logging_text
= "Task vim_create={} ".format(vim_id
)
34 self
.logger
.debug(logging_text
+ "Enter")
40 step
= "Getting vim-id='{}' from db".format(vim_id
)
41 db_vim
= self
.db
.get_one("vim_accounts", {"_id": vim_id
})
42 db_vim_update
["_admin.deployed.RO"] = None
43 if vim_content
.get("config") and vim_content
["config"].get("sdn-controller"):
44 step
= "Getting sdn-controller-id='{}' from db".format(vim_content
["config"]["sdn-controller"])
45 db_sdn
= self
.db
.get_one("sdns", {"_id": vim_content
["config"]["sdn-controller"]})
46 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get("RO"):
47 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
49 raise LcmException("sdn-controller={} is not available. Not deployed at RO".format(
50 vim_content
["config"]["sdn-controller"]))
52 step
= "Creating vim at RO"
53 db_vim_update
["_admin.detailed-status"] = step
54 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
55 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
56 vim_RO
= deepcopy(vim_content
)
57 vim_RO
.pop("_id", None)
58 vim_RO
.pop("_admin", None)
59 vim_RO
.pop("schema_version", None)
60 vim_RO
.pop("schema_type", None)
61 vim_RO
.pop("vim_tenant_name", None)
62 vim_RO
["type"] = vim_RO
.pop("vim_type")
63 vim_RO
.pop("vim_user", None)
64 vim_RO
.pop("vim_password", None)
66 vim_RO
["config"]["sdn-controller"] = RO_sdn_id
67 desc
= await RO
.create("vim", descriptor
=vim_RO
)
68 RO_vim_id
= desc
["uuid"]
69 db_vim_update
["_admin.deployed.RO"] = RO_vim_id
71 step
= "Creating vim_account at RO"
72 db_vim_update
["_admin.detailed-status"] = step
73 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
75 vim_account_RO
= {"vim_tenant_name": vim_content
["vim_tenant_name"],
76 "vim_username": vim_content
["vim_user"],
77 "vim_password": vim_content
["vim_password"]
79 if vim_RO
.get("config"):
80 vim_account_RO
["config"] = vim_RO
["config"]
81 if "sdn-controller" in vim_account_RO
["config"]:
82 del vim_account_RO
["config"]["sdn-controller"]
83 if "sdn-port-mapping" in vim_account_RO
["config"]:
84 del vim_account_RO
["config"]["sdn-port-mapping"]
85 desc
= await RO
.attach_datacenter(RO_vim_id
, descriptor
=vim_account_RO
)
86 db_vim_update
["_admin.deployed.RO-account"] = desc
["uuid"]
87 db_vim_update
["_admin.operationalState"] = "ENABLED"
88 db_vim_update
["_admin.detailed-status"] = "Done"
90 # await asyncio.sleep(15) # TODO remove. This is for test
91 self
.logger
.debug(logging_text
+ "Exit Ok RO_vim_id={}".format(RO_vim_id
))
94 except (ROclient
.ROClientException
, DbException
) as e
:
95 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
97 except Exception as e
:
98 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
102 db_vim_update
["_admin.operationalState"] = "ERROR"
103 db_vim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
105 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
106 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
108 async def edit(self
, vim_content
, order_id
):
109 vim_id
= vim_content
["_id"]
110 logging_text
= "Task vim_edit={} ".format(vim_id
)
111 self
.logger
.debug(logging_text
+ "Enter")
117 step
= "Getting vim-id='{}' from db".format(vim_id
)
119 db_vim
= self
.db
.get_one("vim_accounts", {"_id": vim_id
})
121 # look if previous tasks in process
122 task_name
, task_dependency
= self
.lcm_tasks
.lookfor_related("vim_account", vim_id
, order_id
)
124 step
= "Waiting for related tasks to be completed: {}".format(task_name
)
125 self
.logger
.debug(logging_text
+ step
)
126 # TODO write this to database
127 await asyncio
.wait(task_dependency
, timeout
=3600)
129 if db_vim
.get("_admin") and db_vim
["_admin"].get("deployed") and db_vim
["_admin"]["deployed"].get("RO"):
130 if vim_content
.get("config") and vim_content
["config"].get("sdn-controller"):
131 step
= "Getting sdn-controller-id='{}' from db".format(vim_content
["config"]["sdn-controller"])
132 db_sdn
= self
.db
.get_one("sdns", {"_id": vim_content
["config"]["sdn-controller"]})
134 # look if previous tasks in process
135 task_name
, task_dependency
= self
.lcm_tasks
.lookfor_related("sdn", db_sdn
["_id"])
137 step
= "Waiting for related tasks to be completed: {}".format(task_name
)
138 self
.logger
.debug(logging_text
+ step
)
139 # TODO write this to database
140 await asyncio
.wait(task_dependency
, timeout
=3600)
142 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get(
144 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
146 raise LcmException("sdn-controller={} is not available. Not deployed at RO".format(
147 vim_content
["config"]["sdn-controller"]))
149 RO_vim_id
= db_vim
["_admin"]["deployed"]["RO"]
150 step
= "Editing vim at RO"
151 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
152 vim_RO
= deepcopy(vim_content
)
153 vim_RO
.pop("_id", None)
154 vim_RO
.pop("_admin", None)
155 vim_RO
.pop("schema_version", None)
156 vim_RO
.pop("schema_type", None)
157 vim_RO
.pop("vim_tenant_name", None)
158 if "vim_type" in vim_RO
:
159 vim_RO
["type"] = vim_RO
.pop("vim_type")
160 vim_RO
.pop("vim_user", None)
161 vim_RO
.pop("vim_password", None)
163 vim_RO
["config"]["sdn-controller"] = RO_sdn_id
164 # TODO make a deep update of sdn-port-mapping
166 await RO
.edit("vim", RO_vim_id
, descriptor
=vim_RO
)
168 step
= "Editing vim-account at RO tenant"
170 if "config" in vim_content
:
171 if "sdn-controller" in vim_content
["config"]:
172 del vim_content
["config"]["sdn-controller"]
173 if "sdn-port-mapping" in vim_content
["config"]:
174 del vim_content
["config"]["sdn-port-mapping"]
175 if not vim_content
["config"]:
176 del vim_content
["config"]
177 for k
in ("vim_tenant_name", "vim_password", "config"):
179 vim_account_RO
[k
] = vim_content
[k
]
180 if "vim_user" in vim_content
:
181 vim_content
["vim_username"] = vim_content
["vim_user"]
182 # vim_account must be edited always even if empty in order to ensure changes are translated to RO
183 # vim_thread. RO will remove and relaunch a new thread for this vim_account
184 await RO
.edit("vim_account", RO_vim_id
, descriptor
=vim_account_RO
)
185 db_vim_update
["_admin.operationalState"] = "ENABLED"
187 self
.logger
.debug(logging_text
+ "Exit Ok RO_vim_id={}".format(RO_vim_id
))
190 except (ROclient
.ROClientException
, DbException
) as e
:
191 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
193 except Exception as e
:
194 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
198 db_vim_update
["_admin.operationalState"] = "ERROR"
199 db_vim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
201 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
202 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
204 async def delete(self
, vim_id
, order_id
):
205 logging_text
= "Task vim_delete={} ".format(vim_id
)
206 self
.logger
.debug(logging_text
+ "Enter")
210 step
= "Getting vim from db"
212 db_vim
= self
.db
.get_one("vim_accounts", {"_id": vim_id
})
213 if db_vim
.get("_admin") and db_vim
["_admin"].get("deployed") and db_vim
["_admin"]["deployed"].get("RO"):
214 RO_vim_id
= db_vim
["_admin"]["deployed"]["RO"]
215 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
216 step
= "Detaching vim from RO tenant"
218 await RO
.detach_datacenter(RO_vim_id
)
219 except ROclient
.ROClientException
as e
:
220 if e
.http_code
== 404: # not found
221 self
.logger
.debug(logging_text
+ "RO_vim_id={} already detached".format(RO_vim_id
))
225 step
= "Deleting vim from RO"
227 await RO
.delete("vim", RO_vim_id
)
228 except ROclient
.ROClientException
as e
:
229 if e
.http_code
== 404: # not found
230 self
.logger
.debug(logging_text
+ "RO_vim_id={} already deleted".format(RO_vim_id
))
235 self
.logger
.error(logging_text
+ "Nohing to remove at RO")
236 self
.db
.del_one("vim_accounts", {"_id": vim_id
})
237 self
.logger
.debug(logging_text
+ "Exit Ok")
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)
247 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
249 db_vim_update
["_admin.operationalState"] = "ERROR"
250 db_vim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
252 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
253 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
256 class SdnLcm(LcmBase
):
258 def __init__(self
, db
, msg
, fs
, lcm_tasks
, ro_config
, loop
):
260 Init, Connect to database, filesystem storage, and messaging
261 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
265 self
.logger
= logging
.getLogger('lcm.sdn')
267 self
.lcm_tasks
= lcm_tasks
268 self
.ro_config
= ro_config
270 super().__init
__(db
, msg
, fs
, self
.logger
)
272 async def create(self
, sdn_content
, order_id
):
273 sdn_id
= sdn_content
["_id"]
274 logging_text
= "Task sdn_create={} ".format(sdn_id
)
275 self
.logger
.debug(logging_text
+ "Enter")
281 step
= "Getting sdn from db"
282 db_sdn
= self
.db
.get_one("sdns", {"_id": sdn_id
})
283 db_sdn_update
["_admin.deployed.RO"] = None
285 step
= "Creating sdn at RO"
286 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
287 sdn_RO
= deepcopy(sdn_content
)
288 sdn_RO
.pop("_id", None)
289 sdn_RO
.pop("_admin", None)
290 sdn_RO
.pop("schema_version", None)
291 sdn_RO
.pop("schema_type", None)
292 sdn_RO
.pop("description", None)
293 desc
= await RO
.create("sdn", descriptor
=sdn_RO
)
294 RO_sdn_id
= desc
["uuid"]
295 db_sdn_update
["_admin.deployed.RO"] = RO_sdn_id
296 db_sdn_update
["_admin.operationalState"] = "ENABLED"
297 self
.logger
.debug(logging_text
+ "Exit Ok RO_sdn_id={}".format(RO_sdn_id
))
300 except (ROclient
.ROClientException
, DbException
) as e
:
301 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
303 except Exception as e
:
304 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
308 db_sdn_update
["_admin.operationalState"] = "ERROR"
309 db_sdn_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
311 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
312 self
.lcm_tasks
.remove("sdn", sdn_id
, order_id
)
314 async def edit(self
, sdn_content
, order_id
):
315 sdn_id
= sdn_content
["_id"]
316 logging_text
= "Task sdn_edit={} ".format(sdn_id
)
317 self
.logger
.debug(logging_text
+ "Enter")
321 step
= "Getting sdn from db"
323 db_sdn
= self
.db
.get_one("sdns", {"_id": sdn_id
})
324 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get("RO"):
325 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
326 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
327 step
= "Editing sdn at RO"
328 sdn_RO
= deepcopy(sdn_content
)
329 sdn_RO
.pop("_id", None)
330 sdn_RO
.pop("_admin", None)
331 sdn_RO
.pop("schema_version", None)
332 sdn_RO
.pop("schema_type", None)
333 sdn_RO
.pop("description", None)
335 await RO
.edit("sdn", RO_sdn_id
, descriptor
=sdn_RO
)
336 db_sdn_update
["_admin.operationalState"] = "ENABLED"
338 self
.logger
.debug(logging_text
+ "Exit Ok RO_sdn_id".format(RO_sdn_id
))
341 except (ROclient
.ROClientException
, DbException
) as e
:
342 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
344 except Exception as e
:
345 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
349 db_sdn
["_admin.operationalState"] = "ERROR"
350 db_sdn
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
352 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
353 self
.lcm_tasks
.remove("sdn", sdn_id
, order_id
)
355 async def delete(self
, sdn_id
, order_id
):
356 logging_text
= "Task sdn_delete={} ".format(sdn_id
)
357 self
.logger
.debug(logging_text
+ "Enter")
361 step
= "Getting sdn from db"
363 db_sdn
= self
.db
.get_one("sdns", {"_id": sdn_id
})
364 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get("RO"):
365 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
366 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
367 step
= "Deleting sdn from RO"
369 await RO
.delete("sdn", RO_sdn_id
)
370 except ROclient
.ROClientException
as e
:
371 if e
.http_code
== 404: # not found
372 self
.logger
.debug(logging_text
+ "RO_sdn_id={} already deleted".format(RO_sdn_id
))
377 self
.logger
.error(logging_text
+ "Skipping. There is not RO information at database")
378 self
.db
.del_one("sdns", {"_id": sdn_id
})
379 self
.logger
.debug("sdn_delete task sdn_id={} Exit Ok".format(sdn_id
))
382 except (ROclient
.ROClientException
, DbException
) as e
:
383 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
385 except Exception as e
:
386 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
390 db_sdn
["_admin.operationalState"] = "ERROR"
391 db_sdn
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
393 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
394 self
.lcm_tasks
.remove("sdn", sdn_id
, order_id
)