Beispiel #1
0
 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', ''))
Beispiel #2
0
 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'))
Beispiel #3
0
 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')))
Beispiel #4
0
 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', ''))
Beispiel #5
0
 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')))
Beispiel #6
0
 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)}
Beispiel #8
0
    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))
Beispiel #9
0
        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
Beispiel #10
0
    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,
                }]
            }
        })
Beispiel #11
0
 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', ''))
Beispiel #12
0
    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))