def rollback_secret(self, ns, cluster_id, spec): """删除使用 """ client = mesos.MesosClient(self.access_token, self.project_id, cluster_id, env=None) name = spec['metadata']['name'] result = client.delete_secret(ns, name) if result.get('code') != 0: raise ComponentError(result.get('message', ''))
def handler_update_k8sservice(self, ns, cluster_id, spec): client = K8SClient(self.access_token, self.project_id, cluster_id, env=None) deployment_name = spec['metadata']['name'] result = client.update_service(ns, deployment_name, spec) if result.get('code') != 0: if result.get('code') == 4001: raise ConfigError( "配置文件格式错误:%s" % result.get('message')) raise ComponentError( "更新K8sService失败,%s, 请联系管理员解决" % result.get('message'))
def handler_k8sservice(self, ns, cluster_id, spec): client = K8SClient(self.access_token, self.project_id, cluster_id, env=None) result = client.create_service(ns, spec) if result.get('code') != 0: if result.get('code') == 4001: raise ConfigError( _("配置文件格式错误:{}").format(result.get('message'))) raise ComponentError( _("创建K8sService失败,{}, 请联系管理员解决").format(result.get('message')))
def rollback_metric(self, ns, cluster_id, spec): """回滚metric""" client = mesos.MesosClient(self.access_token, self.project_id, cluster_id, env=None) name = spec['name'] result = client.delete_metrics(namespace=ns, metric_name=name, cluster_type='k8s') if result.get('code') != 0: raise ComponentError(result.get('message', ''))
def handler_update_k8singress(self, ns, cluster_id, spec): client = K8SClient(self.access_token, self.project_id, cluster_id, env=None) deployment_name = spec['metadata']['name'] result = client.update_ingress(ns, deployment_name, spec) if result.get('code') != 0: if result.get('code') == 4001: raise ConfigError( _("配置文件格式错误:{}".format(result.get('message')))) raise ComponentError( _("更新K8sIngress失败,{}, 请联系管理员解决").format(result.get('message')))
def handler_update_k8sconfigmap(self, ns, cluster_id, spec): client = K8SClient(self.access_token, self.project_id, cluster_id, env=None) name = spec['metadata']['name'] result = client.update_configmap(ns, name, spec) if result.get('code') != 0: if result.get('code') == 4001: raise ConfigError( _("配置文件格式错误:{}").format(result.get('message'))) raise ComponentError( _("更新K8sConfigMap失败,{}").format(result.get('message')))
def _wrapped_func(*args, **kwargs): # 判断是否抛异常 raise_exception = kwargs.pop("raise_exception", True) try: resp = func(*args, **kwargs) format_func = FORMAT_FUNC.get(f) if format_func: # 获取内容 if isinstance(resp, Response): content = resp.text elif isinstance(resp, six.string_types): content = resp else: raise ValueError( _("返回值[{}]必须是字符串或者Response对象").format(resp)) # 解析格式 err_msg = kwargs.get("err_msg", None) try: resp = format_func(content) except Exception as e: logger.exception("请求第三方失败,使用【%s】格式解析 %s 异常,%s", f, content, e) error = ComponentError(err_msg or e) # 设置response, 上层使用可进一步判断 error.response = resp raise error if handle_resp: if resp.get("code") != ErrorCode.NoError: raise APIError(resp.get("message")) return resp.get("data") return resp except Exception as e: if raise_exception: raise return {"message": str(e)}
def deep_delete_statefulset(self, namespace, name): # 查询pod 信息 pod_name_list = self.get_pods_by_upper_res(namespace, name) result = self.delete_statefulset(namespace, name) err_msg = [] if result.get('code') != 0: if "not found" not in result.get('message', ''): err_msg.append(result.get('message', '')) # 删除 pods for _pod_name in pod_name_list: del_pod_res = self.delete_pod(namespace, _pod_name) if del_pod_res.get('code') != 0: logger.error("k8s_deep_delete delete_pod [ns:%s,name:%s]出错:%s" % ( namespace, _pod_name, del_pod_res.get('message', ''))) if "not found" not in del_pod_res.get('message', ''): err_msg.append(del_pod_res.get('message', '')) if err_msg: raise ComponentError(';'.join(err_msg))
def _wrapped_func(*args, **kwargs): resp = func(*args, **kwargs) format_func = FORMAT_FUNC.get(f) if format_func: # 获取内容 if isinstance(resp, Response): content = resp.text elif isinstance(resp, six.string_types): content = resp else: raise ValueError(_("返回值[{}]必须是字符串或者Respose对象").format(resp)) # 解析格式 err_msg = kwargs.get('err_msg', None) try: resp = format_func(content) except Exception as error: logger.exception( "请求第三方失败,使用【%s】格式解析 %s 异常,%s", f, content, error) raise ComponentError(err_msg or error) return resp
def get_service_info(self, request, project_id, cluster_id, namespace, name): # noqa """获取单个 service 的信息""" project_kind = request.project.kind access_token = request.user.token.access_token params = { "env": "mesos" if project_kind == MESOS_VALUE else "k8s", "namespace": namespace, "name": name, } if project_kind == MESOS_VALUE: client = mesos.MesosClient(access_token, project_id, cluster_id, env=None) resp = client.get_services(params) # 跳转到模板集页面需要的参数 template_cate = 'mesos' relate_app_cate = 'application' else: client = k8s.K8SClient(access_token, project_id, cluster_id, env=None) resp = client.get_service(params) template_cate = 'k8s' relate_app_cate = 'deployment' if resp.get("code") != ErrorCode.NoError: raise ComponentError(resp.get("message")) resp_data = resp.get("data", []) if not resp_data: return APIResponse({ "code": 400, "message": _("查询不到 Service[{}] 的信息").format(name) }) s_data = resp_data[0].get('data', {}) labels = s_data.get('metadata', {}).get('labels') or {} # 获取命名空间的id namespace_id = app_utils.get_namespace_id(access_token, project_id, (cluster_id, namespace), cluster_id=cluster_id) instance_id = labels.get(LABLE_INSTANCE_ID) # 是否关联LB lb_balance = labels.get('BCSBALANCE') if lb_balance: s_data['isLinkLoadBalance'] = True s_data['metadata']['lb_labels'] = {'BCSBALANCE': lb_balance} else: s_data['isLinkLoadBalance'] = False lb_name = labels.get('BCSGROUP') # 获取模板集信息 template_id = labels.get(LABLE_TEMPLATE_ID) try: lasetest_ver = ShowVersion.objects.filter( template_id=template_id).order_by('-updated').first() show_version_name = lasetest_ver.name version_id = lasetest_ver.real_version_id version_entity = VersionedEntity.objects.get(id=version_id) except Exception: return APIResponse({ "code": 400, "message": _("模板集[id:{}]没有可用的版本,无法更新service").format(template_id) }) entity = version_entity.get_entity() # 获取更新人和创建人 annotations = s_data.get('metadata', {}).get('annotations', {}) creator = annotations.get(ANNOTATIONS_CREATOR, '') updator = annotations.get(ANNOTATIONS_UPDATOR, '') create_time = annotations.get(ANNOTATIONS_CREATE_TIME, '') update_time = annotations.get(ANNOTATIONS_UPDATE_TIME, '') # k8s 更新需要获取版本号 resource_version = s_data.get('metadata', {}).get('resourceVersion') or '' web_cache = annotations.get(ANNOTATIONS_WEB_CACHE) if not web_cache: # 备注中无,则从模板中获取,兼容mesos之前实例化过的模板数据 _services = entity.get('service') if entity else None _services_id_list = _services.split(',') if _services else [] _s = Service.objects.filter(id__in=_services_id_list, name=name).first() try: web_cache = _s.get_config.get('webCache') except Exception: pass else: try: web_cache = json.loads(web_cache) except Exception: pass s_data['webCache'] = web_cache deploy_tag_list = web_cache.get('deploy_tag_list') or [] app_weight = {} if project_kind == MESOS_VALUE: # 处理 mesos 中Service的关联数据 apps = entity.get('application') if entity else None application_id_list = apps.split(',') if apps else [] apps = Application.objects.filter(id__in=application_id_list) if apps: # 关联应用的权重 for key in labels: if key.startswith('BCS-WEIGHT-'): app_name = key[11:] _app = apps.filter(name=app_name).first() if _app: weight = int(labels[key]) app_weight[_app.app_id] = weight else: # 处理 k8s 中Service的关联数据 if not deploy_tag_list: _servs = entity.get('K8sService') if entity else None _serv_id_list = _servs.split(',') if _servs else [] _k8s_s = K8sService.objects.filter(id__in=_serv_id_list, name=name).first() if _k8s_s: deploy_tag_list = _k8s_s.get_deploy_tag_list() # 标签 和 备注 去除后台自动添加的 or_annotations = s_data.get('metadata', {}).get('annotations', {}) or_labels = s_data.get('metadata', {}).get('labels', {}) if or_labels: pub_keys = PUBLIC_LABELS.keys() show_labels = { key: or_labels[key] for key in or_labels if key not in pub_keys } s_data['metadata']['labels'] = show_labels if or_annotations: pub_an_keys = PUBLIC_ANNOTATIONS.keys() show_annotations = { key: or_annotations[key] for key in or_annotations if key not in pub_an_keys } remove_key(show_annotations, ANNOTATIONS_WEB_CACHE) s_data['metadata']['annotations'] = show_annotations return APIResponse({ "data": { 'service': [{ 'name': name, 'app_id': app_weight.keys(), 'app_weight': app_weight, 'deploy_tag_list': deploy_tag_list, 'config': s_data, 'version': version_id, 'lb_name': lb_name, 'instance_id': instance_id, 'namespace_id': namespace_id, 'cluster_id': cluster_id, 'namespace': namespace, 'creator': creator, 'updator': updator, 'create_time': create_time, 'update_time': update_time, 'show_version_name': show_version_name, 'resource_version': resource_version, 'template_id': template_id, 'template_cate': template_cate, 'relate_app_cate': relate_app_cate, }] } })
def rollback_k8sconfigmap(self, ns, cluster_id, spec): client = K8SClient(self.access_token, self.project_id, cluster_id, env=None) name = spec['metadata']['name'] result = client.delete_configmap(ns, name) if result.get('code') != 0: raise ComponentError(result.get('message', ''))
def deep_delete_deployment(self, namespace, name): """删除Deployment,级联删除rs&pod """ # 1. 查询rs extra_encode = self.get_extra_encode(name) rs_res = self.get_rs({ "extra": extra_encode, "field": "resourceName,namespace", "namespace": namespace }) logger.info("k8s_deep_delete 查询[ns:%s,name:%s]rs:%s" % (namespace, name, rs_res)) if rs_res.get("code") != 0: logger.error("k8s_deep_delete 查询[ns:%s,name:%s]rs出错:%s" % (namespace, name, rs_res.get('message', ''))) rs_name_lit = [] pod_name_list = [] rs_data = rs_res.get("data") or [] for _rs in rs_data: _rs_name = _rs.get('resourceName') rs_name_lit.append(_rs_name) # 2. 查询pod 信息 _pod_name_list = self.get_pods_by_upper_res(namespace, _rs_name) pod_name_list.extend(_pod_name_list) err_msg = [] # 3. 删除 Deployment deploy_res = self.delete_deployment(namespace, name) if deploy_res.get('code') != 0: logger.error( "k8s_deep_delete delete_deployment [ns:%s,name:%s]出错:%s" % (namespace, name, deploy_res.get('message', ''))) if "not found" not in deploy_res.get('message', ''): err_msg.append(deploy_res.get('message', '')) # 3. 删除rs for _r_name in rs_name_lit: del_rs_res = self.delete_rs(namespace, _r_name) logger.info("k8s_deep_delete delete_rs [ns:%s,name:%s]:%s" % (namespace, _r_name, del_rs_res)) if del_rs_res.get('code') != 0: logger.error( "k8s_deep_delete delete_rs [ns:%s,name:%s]出错:%s" % (namespace, _r_name, del_rs_res.get('message', ''))) if "not found" not in del_rs_res.get('message', ''): err_msg.append(del_rs_res.get('message', '')) # 4. 删除 pods for _pod_name in pod_name_list: del_pod_res = self.delete_pod(namespace, _pod_name) logger.info("k8s_deep_delete delete_pod [ns:%s,name:%s]:%s" % (namespace, _pod_name, del_pod_res)) if del_pod_res.get('code') != 0: logger.error( "k8s_deep_delete delete_pod [ns:%s,name:%s]出错:%s" % (namespace, _pod_name, del_pod_res.get('message', ''))) if "not found" not in del_pod_res.get('message', ''): err_msg.append(del_pod_res.get('message', '')) if err_msg: raise ComponentError(';'.join(err_msg))