def _do_update_plan(self, context, plan_id, values): LOG.info("Update plan <%s> with values: %s", plan_id, values) allowed_properties = [ 'task_status', 'plan_status', 'stack_id', 'updated_resources', 'sys_clone', 'copy_data' ] # Verify the keys and values for k, v in values.items(): if k not in allowed_properties: msg = ("Update plan failed. %s field " "not found or unsupported to update." % k) LOG.error(msg) raise exception.PlanUpdateError(message=msg) elif k == 'plan_status' and v not in p_status.PLAN_STATUS: msg = "Update plan failed. '%s' plan_status unsupported." % v LOG.error(msg) raise exception.PlanUpdateError(message=msg) # If values contain updated_resources, set update time. if 'updated_resources' in values: values['updated_at'] = timeutils.utcnow() # Update in database plan_cls.update_plan_to_db(context, plan_id, values) LOG.info("Update plan with id of %s succeed!", plan_id)
def _do_update_plan(self, context, plan_id, values): LOG.info("Update plan <%s> with values: %s", plan_id, values) allowed_properties = ['task_status', 'plan_status', 'stack_id', 'updated_resources', 'sys_clone', 'copy_data'] # Verify the keys and values for k, v in values.items(): if k not in allowed_properties: msg = ("Update plan failed. %s field " "not found or unsupported to update." % k) LOG.error(msg) raise exception.PlanUpdateError(message=msg) elif k == 'plan_status' and v not in p_status.PLAN_STATUS: msg = "Update plan failed. '%s' plan_status unsupported." % v LOG.error(msg) raise exception.PlanUpdateError(message=msg) # If values contain updated_resources, set update time. if 'updated_resources' in values: values['updated_at'] = timeutils.utcnow() # Update in database plan_cls.update_plan_to_db(context, plan_id, values) LOG.info("Update plan with id of %s succeed!", plan_id)
def _delete_plan(self, context, plan_id): LOG.info("Begin to delete plan with id of %s", plan_id) plan = db_api.plan_get(context, plan_id) if not plan: LOG.error('Delete plan %s failed' % plan_id) raise exception.PlanNotFound(plan_id=plan_id) plan_cls.update_plan_to_db(context, plan_id, {'plan_status': p_status.DELETING}) # delete heat stack info self.heat_api.clear_table(context, plan['stack_id'], plan_id) # delete template info try: db_api.plan_template_delete(context, plan_id) except exception.PlanNotFoundInDb: LOG.warn('Plan does not have template :%s', plan_id) except Exception as e: LOG.error('Delete plan %(id)s template info failed: %(err)s', { 'id': plan_id, 'err': e }) raise try: db_api.plan_cloned_resource_delete(context, plan_id) except exception.PlanNotFoundInDb: LOG.warn('Plan does not have cloned resources :%s', plan_id) except Exception as e: LOG.error('Delete plan %(id)s cloned resources failed: %(err)s', { 'id': plan_id, 'err': e }) raise try: db_api.plan_availability_zone_mapper_delete(context, plan_id) except exception.PlanNotFoundInDb: LOG.warn('Plan does not have az map :%s', plan_id) except Exception as e: LOG.error('Delete plan %(id)s az map failed: %(err)s', { 'id': plan_id, 'err': e }) raise # delete plan info try: db_api.plan_delete(context, plan_id) except exception.PlanNotFoundInDb: LOG.warn('Plan does not have az map :%s', plan_id) except Exception as e: LOG.error('Delete plan %(id)s az map failed: %(err)s', { 'id': plan_id, 'err': e }) raise LOG.info("Delete plan with id of %s succeed!", plan_id)
def build_plan_by_template(self, context, plan_dict, template): LOG.info("Begin to build plan <%s> by template.", plan_dict['plan_id']) # extract resources plan = plan_cls.Plan.from_dict(plan_dict) plan_id = plan.plan_id resources = {} template_res = template.get('resources') for key, value in template_res.items(): res_id = value.get('extra_properties', {}).get('id', '') if not res_id: res_id = uuidutils.generate_uuid() template_res[key].get('extra_properties', {}).pop('id', '') resource_obj = resource.Resource(key, value.get('type'), res_id, properties= value.get('properties'), extra_properties= value.get('extra_properties')) resource_obj.rebuild_parameter(template.get('parameters')) resources[key] = resource_obj plan.original_resources = resources plan.rebuild_dependencies(is_original=True) plan.plan_status = p_status.AVAILABLE # Resources of migrate plan are not allowed to be modified, # so 'updated fields' are empty. if plan.plan_type == "clone": plan.updated_resources = copy.deepcopy(resources) plan.updated_dependencies = \ copy.deepcopy(plan.original_dependencies) plan_dict = plan.to_dict() update_values = { 'plan_status': p_status.AVAILABLE, 'original_resources': plan_dict['original_resources'], 'updated_resources': plan_dict['updated_resources'] } try: # Update to database plan_cls.update_plan_to_db(context, plan_id, update_values) LOG.info("Create plan by template finished. Plan_id is %s" % plan_id) except Exception as e: msg = "Create plan by template failed! %s" % unicode(e) LOG.error(msg) # Roll back: change plan status to error plan_cls.update_plan_to_db(context, plan_id, {'plan_status': p_status.ERROR}) raise exception.PlanCreateFailed(message=msg)
def force_delete_plan(self, context, plan_id): try: plan_cls.update_plan_to_db(context, plan_id, {'plan_status': p_status.DELETING}) rsp = self.plan_rpcapi.force_delete_plan(context, plan_id) except Exception as e: LOG.error('Force delete plan %(id)s error: %(err)s', {'id': plan_id, 'err': unicode(e)}) raise return rsp
def update_plan_resources(self, context, plan_id, resources): LOG.info("Update resources of plan <%s> with values: %s", plan_id, resources) # Get plan object plan_dict = self.get_plan_by_id(context, plan_id) plan = plan_cls.Plan.from_dict(plan_dict) updated_res = copy.deepcopy(plan.updated_resources) updated_dep = copy.deepcopy(plan.updated_dependencies) resources_list = copy.deepcopy(resources) # Update resources for res in resources: if res.get('action') == 'delete': # Remind: dep delete and add resource_id = res.pop('resource_id', None) updated_res.pop(resource_id) for key, value in updated_dep.items(): if resource_id in value.dependencies: msg = 'have resource denpend on the %s ' \ 'resource ,delete failed' % resource_id raise exception.PlanResourcesUpdateError(message=msg) dependencies = updated_dep.get(resource_id).dependencies if dependencies: self._remove_org_depends(dependencies, updated_dep, updated_res) elif res.get('action') == 'add': # Remind: dep delete and add LOG.debug('the add resource info is %s' % res) resource_id = res.pop('resource_id', None) id = res.get('id') type = res.get('resource_type') self._resource_id_to_actual_id(updated_res) updated_res = self._extract_resources(context, id, type, updated_res) self._actual_id_to_resource_id(updated_res) elif res.get('action') == 'edit': self._edit_plan_resource(context, plan, updated_res, updated_dep, res, resources_list) # Update to memory plan.updated_resources = updated_res # plan.updated_resources = # self._actual_id_to_resource_id(context, updated_res) plan.rebuild_dependencies() # Update to database updated_resources = {} for k, v in updated_res.items(): updated_resources[k] = v.to_dict() plan_cls.update_plan_to_db(context, plan_id, {"updated_resources": updated_resources}) LOG.info("Update resource of plan <%s> succeed.", plan_id)
def build_plan_by_template(self, context, plan_dict, template): LOG.info("Begin to build plan <%s> by template.", plan_dict['plan_id']) # extract resources plan = plan_cls.Plan.from_dict(plan_dict) plan_id = plan.plan_id resources = {} template_res = template.get('resources') for key, value in template_res.items(): res_id = value.get('extra_properties', {}).get('id', '') if not res_id: res_id = uuidutils.generate_uuid() template_res[key].get('extra_properties', {}).pop('id', '') resource_obj = resource.Resource( key, value.get('type'), res_id, properties=value.get('properties'), extra_properties=value.get('extra_properties')) resource_obj.rebuild_parameter(template.get('parameters')) resources[key] = resource_obj plan.original_resources = resources plan.rebuild_dependencies(is_original=True) plan.plan_status = p_status.AVAILABLE # Resources of migrate plan are not allowed to be modified, # so 'updated fields' are empty. if plan.plan_type == "clone": plan.updated_resources = copy.deepcopy(resources) plan.updated_dependencies = \ copy.deepcopy(plan.original_dependencies) plan_dict = plan.to_dict() update_values = { 'plan_status': p_status.AVAILABLE, 'original_resources': plan_dict['original_resources'], 'updated_resources': plan_dict['updated_resources'] } try: # Update to database plan_cls.update_plan_to_db(context, plan_id, update_values) LOG.info("Create plan by template finished. Plan_id is %s" % plan_id) except Exception as e: msg = "Create plan by template failed! %s" % unicode(e) LOG.error(msg) # Roll back: change plan status to error plan_cls.update_plan_to_db(context, plan_id, {'plan_status': p_status.ERROR}) raise exception.PlanCreateFailed(message=msg)
def _delete_plan(self, context, plan_id): LOG.info("Begin to delete plan with id of %s", plan_id) plan = db_api.plan_get(context, plan_id) if not plan: LOG.error('Delete plan %s failed' % plan_id) raise exception.PlanNotFound(plan_id=plan_id) plan_cls.update_plan_to_db(context, plan_id, {'plan_status': p_status.DELETING}) # delete heat stack info self.heat_api.clear_table(context, plan['stack_id'], plan_id) # delete template info try: db_api.plan_template_delete(context, plan_id) except exception.PlanNotFoundInDb: LOG.warn('Plan does not have template :%s', plan_id) except Exception as e: LOG.error('Delete plan %(id)s template info failed: %(err)s', {'id': plan_id, 'err': e}) raise try: db_api.plan_cloned_resource_delete(context, plan_id) except exception.PlanNotFoundInDb: LOG.warn('Plan does not have cloned resources :%s', plan_id) except Exception as e: LOG.error('Delete plan %(id)s cloned resources failed: %(err)s', {'id': plan_id, 'err': e}) raise try: db_api.plan_availability_zone_mapper_delete(context, plan_id) except exception.PlanNotFoundInDb: LOG.warn('Plan does not have az map :%s', plan_id) except Exception as e: LOG.error('Delete plan %(id)s az map failed: %(err)s', {'id': plan_id, 'err': e}) raise # delete plan info try: db_api.plan_delete(context, plan_id) except exception.PlanNotFoundInDb: LOG.warn('Plan does not have az map :%s', plan_id) except Exception as e: LOG.error('Delete plan %(id)s az map failed: %(err)s', {'id': plan_id, 'err': e}) raise LOG.info("Delete plan with id of %s succeed!", plan_id)
def delete_plan(self, context, plan_id): allowed_status = (p_status.INITIATING, p_status.CREATING, p_status.AVAILABLE, p_status.ERROR, p_status.FINISHED, p_status.EXPIRED) try: plan = db_api.plan_get(context, plan_id) if plan['plan_status'] not in allowed_status: msg = ("Plan isn't allowed to be deleted in %s status." % plan['plan_status']) LOG.error(msg) raise exception.PlanDeleteError(message=msg) except exception.PlanNotFoundInDb: LOG.error('The plan %s could not be found.', plan_id) raise exception.PlanNotFound(plan_id=plan_id) LOG.info("Begin to delete plan with id of %s", plan_id) plan_cls.update_plan_to_db(context, plan_id, {'plan_status': p_status.DELETING}) return self.plan_rpcapi.delete_plan(context, plan_id)
def test_update_plan_to_db(self, mock_plan_update): fake_plan_dict = copy.deepcopy(fake_object.fake_plan_dict) plan.update_plan_to_db(self.context, fake_plan_dict['plan_id'], fake_plan_dict) mock_plan_update.assert_called_once()