def _generate(self, namespace_id, params) -> List[ResourceData]: resource_list = [] # instance_entity like {"Deployment": [1, 2]} instance_entity = self.res_ctx.instance_entity for kind in instance_entity: for entity_id in instance_entity[kind]: config_generator = GENERATOR_DICT.get(kind)(entity_id, namespace_id, is_validate=True, **params) config = config_generator.get_config_profile() try: manifest = json.loads(config) except Exception: manifest = config resource_list.append( ResourceData( kind=manifest.get('kind'), name=getitems(manifest, 'metadata.name'), namespace=getitems(manifest, 'metadata.namespace'), manifest=manifest, version=self.res_ctx.show_version.name, revision=self.res_ctx.show_version.latest_revision, ) ) return resource_list
def generate_namespace_config(namespace_id, instance_entity, is_save, is_validate=True, **params): """生成单个namespace下的所有配置文件 """ # 将版本修改为可见版本 show_version_id = params.get('show_version_id') show_version_name = ShowVersion.objects.get(id=show_version_id).name params['version'] = show_version_name # 查询命名空间相关的参数 project_id = params.get('project_id') access_token = params.get('access_token') has_image_secret, cluster_version, context = get_ns_variable(access_token, project_id, namespace_id) params['has_image_secret'] = has_image_secret params['cluster_version'] = cluster_version params['context'] = context version_config = {} for item in instance_entity: item_id_list = instance_entity[item] item_config = [] for item_id in item_id_list: generator = GENERATOR_DICT.get(item)( item_id, namespace_id, is_validate, **params) file_content = generator.get_config_profile() file_name = generator.resource_show_name try: show_config = json.loads(file_content) except Exception: show_config = file_content _config_content = { 'name': file_name, 'config': show_config, 'context': generator.context, } if is_save: save_kwargs = { 'instance_id': params.get('instance_id'), 'namespace': namespace_id, 'category': item, 'config': file_content, 'creator': params.get('username'), 'variables': json.dumps(params.get('variable_dict')), # 更新时,需要将其他参数恢复为默认值 "updator": params.get('username'), "updated": timezone.now(), "created": timezone.now(), "is_deleted": False, "deleted_time": None, "is_bcs_success": True, "ins_state": InsState.NO_INS.value, } is_update_save_kwargs = False if item == 'metric': # 获取 Metric ID metric_id = generator.metric_id save_kwargs['ref_id'] = metric_id obj_module = MetricConfig else: save_kwargs.update({ "oper_type": "create", "status": "Running", "last_config": "", }) obj_module = InstanceConfig # 判断db中是否已经有记录,有则做更新操作 _exist_ins_confg = obj_module.objects.filter( name=file_name, namespace=namespace_id, category=item) if _exist_ins_confg.exists(): # 更新第一条数据 _instance_config = _exist_ins_confg.first() update_id = _instance_config.id # 将其他数据设置为 is_deleted:True _exist_ins_confg.exclude(id=update_id).update( is_deleted=True, deleted_time=timezone.now() ) is_update_save_kwargs = True # db中已经有记录,则实例化前不更新,实例化成功、失败后再更新 # _exist_ins_confg.filter(id=update_id).update(**save_kwargs) else: _instance_config = obj_module.objects.create(**save_kwargs) _config_content['instance_config_id'] = _instance_config.id _config_content['save_kwargs'] = save_kwargs _config_content['is_update_save_kwargs'] = is_update_save_kwargs item_config.append(_config_content) version_config[item] = item_config return version_config
def update_resource(self, request, project_id, cluster_id, namespace, name): """更新 """ access_token = request.user.token.access_token project_kind = request.project.kind if project_kind == MESOS_VALUE: # mesos 相关数据 slz_class = self.mesos_slz s_sys_con = self.mesos_sys_config s_cate = self.mesos_cate else: if namespace in constants.K8S_SYS_NAMESPACE: return Response({ "code": 400, "message": _("不允许操作系统命名空间[{}]").format(','.join( constants.K8S_SYS_NAMESPACE)), "data": {} }) # k8s 相关数据 slz_class = self.k8s_slz s_sys_con = self.k8s_sys_config s_cate = self.k8s_cate request_data = request.data or {} request_data['project_id'] = project_id # 验证请求参数 slz = slz_class(data=request.data) slz.is_valid(raise_exception=True) data = slz.data config = json.loads(data['config']) namespace_id = data['namespace_id'] username = request.user.username # 检查是否有命名空间的使用权限 perm = bcs_perm.Namespace(request, project_id, namespace_id) perm.can_use(raise_exception=True) # 对配置文件做处理 gparams = { "access_token": access_token, "project_id": project_id, "username": username } generator = GENERATOR_DICT.get(s_cate)(0, namespace_id, **gparams) config = generator.handle_db_config(db_config=config) # 获取上下文信息 context = generator.context now_time = context.get('SYS_UPDATE_TIME') instance_id = data.get('instance_id', 0) context.update({ 'SYS_CREATOR': data.get('creator', ''), 'SYS_CREATE_TIME': data.get('create_time', ''), 'SYS_INSTANCE_ID': instance_id }) # 生成配置文件 sys_config = copy.deepcopy(s_sys_con) resource_config = update_nested_dict(config, sys_config) resource_config = json.dumps(resource_config) try: config_profile = render_mako_context(resource_config, context) except Exception: logger.exception(u"配置文件变量替换出错\nconfig:%s\ncontext:%s" % (resource_config, context)) raise ValidationError(_("配置文件中有未替换的变量")) config_profile = generator.format_config_profile(config_profile) service_name = config.get('metadata', {}).get('name') _config_content = { 'name': service_name, 'config': json.loads(config_profile), 'context': context } # 更新db中的数据 config_objs = InstanceConfig.objects.filter( namespace=namespace_id, category=s_cate, name=service_name, ) if config_objs.exists(): config_objs.update( creator=username, updator=username, oper_type='update', updated=now_time, is_deleted=False, ) _instance_config = config_objs.first() else: _instance_config = InstanceConfig.objects.create( namespace=namespace_id, category=s_cate, name=service_name, config=config_profile, instance_id=instance_id, creator=username, updator=username, oper_type='update', updated=now_time, is_deleted=False) _config_content['instance_config_id'] = _instance_config.id configuration = {namespace_id: {s_cate: [_config_content]}} driver = get_scheduler_driver(access_token, project_id, configuration, request.project.kind) result = driver.instantiation(is_update=True) failed = [] if isinstance(result, dict): failed = result.get('failed') or [] # 添加操作审计 activity_client.ContextActivityLogClient( project_id=project_id, user=username, resource_type="instance", resource=service_name, resource_id=_instance_config.id, extra=json.dumps(configuration), description=_("更新{}[{}]命名空间[{}]").format( self.category, service_name, namespace)).log_modify( activity_status="failed" if failed else "succeed") if failed: return Response({ "code": 400, "message": _("{}[{}]在命名空间[{}]更新失败,请联系集群管理员解决").format( self.category, service_name, namespace), "data": {} }) return Response({"code": 0, "message": "OK", "data": {}})