self.lcm_tasks.unlock_HA.assert_not_called()
self.lcm_tasks.remove.assert_called_with("vca", "id", "order-id")
+ def test_vca_lcm_edit_success_no_config(self):
+ vca_content = {
+ "op_id": "order-id",
+ "_id": "id",
+ "description": "test-description",
+ }
+ db_vca = {
+ "_id": "vca-id",
+ "secret": "secret",
+ "cacert": "cacert",
+ "schema_version": "1.11",
+ }
+ order_id = "order-id"
+ self.lcm_tasks.lock_HA.return_value = True
+ self.vca_lcm.db.get_one.return_value = db_vca
+ self.vca_lcm.n2vc.validate_vca = AsyncMock()
+ self.vca_lcm.update_db_2 = Mock()
+ self.loop.run_until_complete(self.vca_lcm.edit(vca_content, order_id))
+ self.vca_lcm.n2vc.validate_vca.assert_not_called()
+ self.lcm_tasks.unlock_HA.assert_called_with(
+ "vca",
+ "edit",
+ "order-id",
+ operationState="COMPLETED",
+ detailed_status="Edited",
+ )
+ self.vca_lcm.update_db_2.assert_called_with(
+ "vca",
+ "id",
+ {},
+ )
+ self.lcm_tasks.remove.assert_called_with("vca", "id", "order-id")
+
+ def test_vca_lcm_edit_success_config(self):
+ vca_content = {"op_id": "order-id", "_id": "id", "cacert": "editcacert"}
+ db_vca = {
+ "_id": "vca-id",
+ "secret": "secret",
+ "cacert": "cacert",
+ "schema_version": "1.11",
+ }
+ order_id = "order-id"
+ self.lcm_tasks.lock_HA.return_value = True
+ self.vca_lcm.db.get_one.return_value = db_vca
+ self.vca_lcm.n2vc.validate_vca = AsyncMock()
+ self.vca_lcm.update_db_2 = Mock()
+ self.loop.run_until_complete(self.vca_lcm.edit(vca_content, order_id))
+ self.vca_lcm.n2vc.validate_vca.assert_called()
+ self.lcm_tasks.unlock_HA.assert_called_with(
+ "vca",
+ "edit",
+ "order-id",
+ operationState="COMPLETED",
+ detailed_status="Edited",
+ )
+ self.vca_lcm.update_db_2.assert_called_with(
+ "vca",
+ "id",
+ {
+ "_admin.operationalState": "ENABLED",
+ "_admin.detailed-status": "Connectivity: ok",
+ },
+ )
+ self.lcm_tasks.remove.assert_called_with("vca", "id", "order-id")
+
+ def test_vca_lcm_edit_exception_no_config(self):
+ vca_content = {
+ "op_id": "order-id",
+ "_id": "id",
+ "description": "new-description",
+ }
+ db_vca = {
+ "_id": "vca-id",
+ "secret": "secret",
+ "cacert": "cacert",
+ "schema_version": "1.11",
+ }
+ order_id = "order-id"
+ self.lcm_tasks.lock_HA.return_value = True
+ self.vca_lcm.db.get_one.return_value = db_vca
+ self.vca_lcm.n2vc.validate_vca = AsyncMock()
+ # validate_vca should not be called in this case
+ self.vca_lcm.n2vc.validate_vca.side_effect = Exception("failed")
+ self.vca_lcm.update_db_2 = Mock()
+ self.loop.run_until_complete(self.vca_lcm.edit(vca_content, order_id))
+ self.lcm_tasks.lock_HA.assert_called_with("vca", "edit", "order-id")
+ self.lcm_tasks.unlock_HA.assert_called_with(
+ "vca",
+ "edit",
+ "order-id",
+ operationState="COMPLETED",
+ detailed_status="Edited",
+ )
+ self.lcm_tasks.remove.assert_called_with("vca", "id", "order-id")
+
+ def test_vca_lcm_edit_exception_config(self):
+ vca_content = {"op_id": "order-id", "_id": "id", "user": "new-user"}
+ db_vca = {
+ "_id": "vca-id",
+ "secret": "secret",
+ "cacert": "cacert",
+ "schema_version": "1.11",
+ }
+ order_id = "order-id"
+ self.lcm_tasks.lock_HA.return_value = True
+ self.vca_lcm.db.get_one.return_value = db_vca
+ self.vca_lcm.n2vc.validate_vca = AsyncMock()
+ # validate_vca should be called in this case
+ self.vca_lcm.n2vc.validate_vca.side_effect = Exception("failed")
+ self.vca_lcm.update_db_2 = Mock()
+ self.loop.run_until_complete(self.vca_lcm.edit(vca_content, order_id))
+ self.lcm_tasks.lock_HA.assert_called_with("vca", "edit", "order-id")
+ self.lcm_tasks.unlock_HA.assert_called_with(
+ "vca",
+ "edit",
+ "order-id",
+ operationState="FAILED",
+ detailed_status="Failed with exception: failed",
+ )
+ self.vca_lcm.update_db_2.assert_called_with(
+ "vca",
+ "id",
+ {
+ "_admin.operationalState": "ERROR",
+ "_admin.detailed-status": "Failed with exception: failed",
+ },
+ )
+ self.lcm_tasks.remove.assert_called_with("vca", "id", "order-id")
+
+ def test_vca_lcm_edit_db_exception(self):
+ vca_content = {
+ "op_id": "order-id",
+ "_id": "id",
+ "description": "new-description",
+ }
+ db_vca = {
+ "_id": "vca-id",
+ "secret": "secret",
+ "cacert": "cacert",
+ "schema_version": "1.11",
+ }
+ order_id = "order-id"
+ self.lcm_tasks.lock_HA.return_value = True
+ self.vca_lcm.db.get_one.return_value = db_vca
+ self.vca_lcm.n2vc.validate_vca = AsyncMock()
+ self.vca_lcm.update_db_2 = Mock()
+ self.vca_lcm.update_db_2.side_effect = DbException("failed")
+ self.loop.run_until_complete(self.vca_lcm.edit(vca_content, order_id))
+ self.vca_lcm.n2vc.validate_vca.assert_not_called()
+ self.lcm_tasks.lock_HA.assert_called_with("vca", "edit", "order-id")
+ self.vca_lcm.update_db_2.assert_called_with(
+ "vca",
+ "id",
+ {},
+ )
+ self.lcm_tasks.unlock_HA.assert_not_called()
+ self.lcm_tasks.remove.assert_called_with("vca", "id", "order-id")
+
def test_vca_lcm_delete(self):
vca_content = {"op_id": "order-id", "_id": "id"}
order_id = "order-id"
)
return db_vca
+ async def _validate_vca(self, db_vca_id: str) -> None:
+ task = asyncio.ensure_future(
+ asyncio.wait_for(
+ self.n2vc.validate_vca(db_vca_id),
+ timeout=self.timeout_create,
+ )
+ )
+ await asyncio.wait([task], return_when=asyncio.FIRST_COMPLETED)
+ if task.exception():
+ raise task.exception()
+
+ def _is_vca_config_update(self, update_options) -> bool:
+ return any(
+ word in update_options.keys()
+ for word in [
+ "cacert",
+ "endpoints",
+ "lxd-cloud",
+ "lxd-credentials",
+ "k8s-cloud",
+ "k8s-credentials",
+ "model-config",
+ "user",
+ "secret",
+ ]
+ )
+
async def create(self, vca_content, order_id):
op_id = vca_content.pop("op_id", None)
if not self.lcm_tasks.lock_HA("vca", "create", op_id):
)
db_vca = self._get_vca_by_id(vca_id)
- task = asyncio.ensure_future(
- asyncio.wait_for(
- self.n2vc.validate_vca(db_vca["_id"]),
- timeout=self.timeout_create,
- )
- )
-
- await asyncio.wait([task], return_when=asyncio.FIRST_COMPLETED)
- if task.exception():
- raise task.exception()
+ await self._validate_vca(db_vca["_id"])
self.logger.debug(
"Task vca_create={} {}".format(
vca_id, "vca registered and validated successfully"
)
self.lcm_tasks.remove("vca", vca_id, order_id)
+ async def edit(self, vca_content, order_id):
+ op_id = vca_content.pop("op_id", None)
+ if not self.lcm_tasks.lock_HA("vca", "edit", op_id):
+ return
+
+ vca_id = vca_content["_id"]
+ self.logger.debug("Task vca_edit={} {}".format(vca_id, "Enter"))
+
+ db_vca = None
+ db_vca_update = {}
+
+ operation_state = "FAILED"
+ operation_details = ""
+ try:
+ self.logger.debug(
+ "Task vca_edit={} {}".format(vca_id, "Getting vca from db")
+ )
+ db_vca = self._get_vca_by_id(vca_id)
+ if self._is_vca_config_update(vca_content):
+ await self._validate_vca(db_vca["_id"])
+ self.logger.debug(
+ "Task vca_edit={} {}".format(
+ vca_id, "vca registered and validated successfully"
+ )
+ )
+ db_vca_update["_admin.operationalState"] = "ENABLED"
+ db_vca_update["_admin.detailed-status"] = "Connectivity: ok"
+
+ operation_details = "Edited"
+ operation_state = "COMPLETED"
+
+ self.logger.debug(
+ "Task vca_edit={} {}".format(
+ vca_id, "Done. Result: {}".format(operation_state)
+ )
+ )
+
+ except Exception as e:
+ error_msg = "Failed with exception: {}".format(e)
+ self.logger.error("Task vca_edit={} {}".format(vca_id, error_msg))
+ db_vca_update["_admin.operationalState"] = "ERROR"
+ db_vca_update["_admin.detailed-status"] = error_msg
+ operation_state = "FAILED"
+ operation_details = error_msg
+ finally:
+ try:
+ self.update_db_2("vca", vca_id, db_vca_update)
+
+ # Register the operation and unlock
+ self.lcm_tasks.unlock_HA(
+ "vca",
+ "edit",
+ op_id,
+ operationState=operation_state,
+ detailed_status=operation_details,
+ )
+ except DbException as e:
+ self.logger.error(
+ "Task vca_edit={} {}".format(
+ vca_id, "Cannot update database: {}".format(e)
+ )
+ )
+ self.lcm_tasks.remove("vca", vca_id, order_id)
+
async def delete(self, vca_content, order_id):
# HA tasks and backward compatibility: