def common_patch(self): ctx_cluster = CtxCluster.create(TEST_CLUSTER_ID, TEST_PROJECT_ID, token='token') Pod(ctx_cluster).update_or_create( namespace=TEST_NAMESPACE, name=self.pod_name, body=gen_pod_body(self.pod_name) ) yield Pod(ctx_cluster).delete(namespace=TEST_NAMESPACE, name=self.pod_name)
def env_info(self, request, project_id, cluster_id, namespace, pod_name, container_name): """ 获取 Pod 环境变量配置信息 """ response_data = [] try: env_resp = Pod(request.ctx_cluster, cache_client=False).exec_command( namespace, pod_name, container_name, ['/bin/sh', '-c', 'env']) # docker 环境变量格式: key=val for info in env_resp.splitlines(): if not info: continue partition_ret = info.partition('=') response_data.append({ 'name': partition_ret[0], 'value': partition_ret[2] }) except ApiException as e: # 在 Pod 中执行命令失败,可能原因有 Pod 未就绪等 logger.warning('尝试在 Pod 中执行命令失败: %s', e) except Exception as e: # 若解析失败,仅保留错误信息,不抛出异常 logger.error('解析容器环境变量失败: %s', e) return Response(response_data)
def secrets(self, request, project_id, cluster_id, namespace, name): """获取 Pod Secret 信息""" # 检查是否有查看命名空间域资源权限 self._validate_perm(request.user.username, project_id, cluster_id, namespace, DashboardAction.View) response_data = Pod(request.ctx_cluster).filter_related_resources( Secret(request.ctx_cluster), namespace, name) return Response(response_data)
def retrieve(self, request, project_id, cluster_id, namespace, pod_name, container_name): """ 获取 Pod 下单个容器详细信息 """ pod_manifest = Pod(request.ctx_cluster).fetch_manifest( namespace, pod_name) response_data = ContainerRespBuilder(pod_manifest, container_name).build() return Response(response_data)
def list(self, request, project_id, cluster_id, namespace=None): """ 获取 Pod 列表,支持 labelSelector """ params = self.params_validate(ListPodsSLZ) client = Pod(request.ctx_cluster) response_data = ListApiRespBuilder(client, namespace=namespace, **params).build() return Response(response_data)
def persistent_volume_claims(self, request, project_id, cluster_id, namespace, name): """获取 Pod Persistent Volume Claim 信息""" # 检查是否有查看命名空间域资源权限 self._validate_perm(request.user.username, project_id, cluster_id, namespace, DashboardAction.View) response_data = Pod(request.ctx_cluster).filter_related_resources( PersistentVolumeClaim(request.ctx_cluster), namespace, name) return Response(response_data)
def get_pod(self, request, project_id_or_code, cluster_id, namespace, pod_name): """ 获取指定 Pod 信息,以列表格式返回 """ pod = Pod(request.ctx_cluster).get( namespace=namespace, name=pod_name, formatter=ResourceDefaultFormatter()) # 保持接口格式不变,如果查询不到则返回空列表 response_data = [pod] if pod else [] return Response(response_data)
def list_pods_by_deployment(self, request, project_id_or_code, cluster_id, namespace, deploy_name): # TODO 增加用户对层级资源project/cluster/namespace的权限校验(由于粒度没有细化到Deployment) deployment = Deployment(request.ctx_cluster).get(namespace=namespace, name=deploy_name, is_format=False) labels_string = make_labels_string(getitems(deployment.data.to_dict(), 'spec.selector.matchLabels', {})) pods = Pod(request.ctx_cluster).list( namespace=namespace, label_selector=labels_string, is_format=False, owner_kind=K8sResourceKind.Deployment.value, owner_name=deploy_name, )['items'] return Response(ResourceDefaultFormatter().format_list(pods))
def env_info(self, request, project_id, cluster_id, namespace, pod_name, container_name): """ 获取 Pod 环境变量配置信息 """ env_resp = Pod(request.ctx_cluster).exec_command(namespace, pod_name, container_name, ['/bin/sh', '-c', 'env']) try: # docker 环境变量格式: key=val response_data = [] for info in env_resp.splitlines(): if not info: continue partition_ret = info.partition('=') response_data.append({'name': partition_ret[0], 'value': partition_ret[2]}) except Exception as e: # 若解析失败,仅保留错误信息,不抛出异常 logger.error('解析容器环境变量失败: %s', e) response_data = [] return Response(response_data)
def reschedule(self, request, project_id, cluster_id, namespace, name): """ 重新调度 Pod(仅对有父级资源的 Pod 有效) """ # 操作类接口统一检查集群操作权限 validate_cluster_perm(request, project_id, cluster_id) client = Pod(request.ctx_cluster) request.audit_ctx.update_fields( resource_type=self.resource_client.kind.lower(), resource=f'{namespace}/{name}') # 检查 Pod 配置,必须有父级资源才可以重新调度 pod_manifest = client.fetch_manifest(namespace, name) if not getitems(pod_manifest, 'metadata.ownerReferences'): raise OwnerReferencesNotExist( _('Pod {}/{} 不存在父级资源,无法被重新调度').format(namespace, name)) # 重新调度的原理是直接删除 Pod,利用父级资源重新拉起服务 try: response_data = client.delete(name=name, namespace=namespace).to_dict() except DynamicApiError as e: raise DeleteResourceError(_('重新调度 Pod 失败: {}').format(e.summary())) return Response(response_data)
def secrets(self, request, project_id, cluster_id, namespace, name): """ 获取 Pod Secret 信息 """ response_data = Pod(request.ctx_cluster).filter_related_resources( Secret(request.ctx_cluster), namespace, name) return Response(response_data)
def configmaps(self, request, project_id, cluster_id, namespace, name): """ 获取 Pod ConfigMap 信息 """ response_data = Pod(request.ctx_cluster).filter_related_resources( ConfigMap(request.ctx_cluster), namespace, name) return Response(response_data)
def persistent_volume_claims(self, request, project_id, cluster_id, namespace, name): """ 获取 Pod Persistent Volume Claim 信息 """ response_data = Pod(request.ctx_cluster).filter_related_resources( PersistentVolumeClaim(request.ctx_cluster), namespace, name) return Response(response_data)
def list(self, request, project_id, cluster_id, namespace, pod_name): """ 获取 Pod 下所有的容器信息 """ pod_manifest = Pod(request.ctx_cluster).fetch_manifest(namespace, pod_name) response_data = ContainerRespBuilder(pod_manifest).build_list() return Response(response_data)
def retrieve(self, request, project_id, cluster_id, namespace, pod_name, container_name): """获取 Pod 下单个容器详细信息""" self._validate_perm(request.user.username, project_id, cluster_id, namespace, DashboardAction.View) pod_manifest = Pod(request.ctx_cluster).fetch_manifest(namespace, pod_name) response_data = ContainerRespBuilder(pod_manifest, container_name).build() return Response(response_data)
def retrieve(self, request, project_id, cluster_id, namespace, pod_name): """ 获取单个 Pod 详细信息 """ client = Pod(request.ctx_cluster) response_data = RetrieveApiRespBuilder(client, namespace, pod_name).build() return Response(response_data)