Skip to content

Commit 061fea1

Browse files
dsy3502zhangjing57
authored andcommitted
fix list resource
1 parent 1d4b349 commit 061fea1

File tree

3 files changed

+145
-39
lines changed

3 files changed

+145
-39
lines changed

dingo_command/api/k8s/resource.py

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -104,43 +104,32 @@ async def create_resources(
104104
raise HTTPException(status_code=500, detail=f"查询资源 '{resource_type}' 失败。")
105105
return JSONResponse(content=jsonable_encoder(resources)) # 确保复杂对象可以被序列化
106106

107-
@router.get("/k8s/namespace/{namespace}/{resource}/list", summary="查询资源列表", description="查询资源列表")
108-
async def list_resources(
109-
cluster_id:str = Query(None, description="集群id"),
110-
namespace: str = Path(..., description="Kubernetes 资源名称"),
111-
resource: str = Path(..., description="Kubernetes 资源类型"),
112-
search_terms: str = Query(None, description="搜索关键词"),
113-
page: str = Query(None, description="页码"),
114-
page_size: str = Query(None, description="每页大小"),
115-
sort_by: str = Query(None, description="排序字段"),
116-
sort_order: str = Query(None, description="排序顺序"),
107+
108+
@router.post("/k8s/{resource_type}", summary="创建资源", description="创建资源")
109+
async def create_resources(
110+
resource: CreateResourceRequest,
111+
resource_type: str = Path(..., description="Kubernetes 资源类型"),
117112
token: str = Depends(get_token),
118-
):
113+
) -> List[Dict[str, Any]]:
119114
#根据cluster_id获取对应的kubeconfig,然后获取kubeclient
120115

121116
"""
122117
根据提供的参数查询 Kubernetes 资源。
123118
"""
124-
k8sclient = get_k8s_client_by_cluster(cluster_id)
125-
#将search_terms按照逗号分开
126-
search_terms_list = search_terms.split(",") if search_terms else []
127-
resources = k8sclient.list_resource(
128-
resource_type=resource,
129-
namespace=namespace,
130-
search_terms=search_terms_list,
131-
page=page,
132-
page_size=page_size,
133-
sort_by=sort_by,
134-
sort_order=sort_order
119+
k8sclient = get_k8s_client_by_cluster(resource.cluster_id)
120+
resources = k8sclient.create_resource(
121+
resource_body=resource.template,
122+
resource_type=resource_type,
123+
135124
)
136125
if resources is None:
137-
raise HTTPException(status_code=500, detail=f"查询资源 '{resource}' 失败。")
138-
#将resources转为json返回
139-
return resources
126+
raise HTTPException(status_code=500, detail=f"查询资源 '{resource_type}' 失败。")
127+
return JSONResponse(content=jsonable_encoder(resources)) # 确保复杂对象可以被序列化
140128

141129
@router.get("/k8s/{resource}/list", summary="查询资源列表", description="查询资源列表")
142130
async def list_resources(
143131
cluster_id:str = Query(None, description="集群id"),
132+
namespace:str = Query(None, description="集群id"),
144133
resource: str = Path(..., description="Kubernetes 资源类型"),
145134
search_terms: str = Query(None, description="搜索关键词"),
146135
page: str = Query(None, description="页码"),
@@ -149,11 +138,17 @@ async def list_resources(
149138
sort_order: str = Query(None, description="排序顺序"),
150139
token: str = Depends(get_token),
151140
):
141+
#根据cluster_id获取对应的kubeconfig,然后获取kubeclient
142+
143+
"""
144+
根据提供的参数查询 Kubernetes 资源。
145+
"""
152146
k8sclient = get_k8s_client_by_cluster(cluster_id)
153147
#将search_terms按照逗号分开
154148
search_terms_list = search_terms.split(",") if search_terms else []
155149
resources = k8sclient.list_resource(
156150
resource_type=resource,
151+
namespace=namespace,
157152
search_terms=search_terms_list,
158153
page=page,
159154
page_size=page_size,

dingo_command/common/k8s_client.py

Lines changed: 120 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,116 @@ def _get_k8s_server_version(self) -> str:
6666
print(f"获取 Kubernetes 版本信息失败: {e}")
6767
# 默认假设为较新版本
6868
return "1.25"
69-
69+
def _infer_kind_from_resource_type(self, resource_type: str) -> str:
70+
"""
71+
根据资源类型(复数形式)推断对应的 Kind(单数形式)。
72+
73+
Args:
74+
resource_type (str): 资源类型的复数形式,如 "pods", "deployments" 等
75+
76+
Returns:
77+
str: 推断出的 Kind
78+
"""
79+
# 常见的复数到单数的映射
80+
resource_kind_mapping = {
81+
# Core API resources
82+
'pods': 'Pod',
83+
'services': 'Service',
84+
'configmaps': 'ConfigMap',
85+
'secrets': 'Secret',
86+
'serviceaccounts': 'ServiceAccount',
87+
'events': 'Event',
88+
'nodes': 'Node',
89+
'persistentvolumes': 'PersistentVolume',
90+
'persistentvolumeclaims': 'PersistentVolumeClaim',
91+
'namespaces': 'Namespace',
92+
'endpoints': 'Endpoints',
93+
'limitranges': 'LimitRange',
94+
'resourcequotas': 'ResourceQuota',
95+
'replicationcontrollers': 'ReplicationController',
96+
'bindings': 'Binding',
97+
'componentstatuses': 'ComponentStatus',
98+
99+
# Apps API resources
100+
'deployments': 'Deployment',
101+
'replicasets': 'ReplicaSet',
102+
'daemonsets': 'DaemonSet',
103+
'statefulsets': 'StatefulSet',
104+
105+
# Networking API resources
106+
'ingresses': 'Ingress',
107+
'networkpolicies': 'NetworkPolicy',
108+
'ingressclasses': 'IngressClass',
109+
110+
# RBAC API resources
111+
'roles': 'Role',
112+
'rolebindings': 'RoleBinding',
113+
'clusterroles': 'ClusterRole',
114+
'clusterrolebindings': 'ClusterRoleBinding',
115+
116+
# Batch API resources
117+
'jobs': 'Job',
118+
'cronjobs': 'CronJob',
119+
120+
# Autoscaling API resources
121+
'horizontalpodautoscalers': 'HorizontalPodAutoscaler',
122+
123+
# Policy API resources
124+
'poddisruptionbudgets': 'PodDisruptionBudget',
125+
'podsecuritypolicies': 'PodSecurityPolicy',
126+
127+
# Storage API resources
128+
'storageclasses': 'StorageClass',
129+
'volumeattachments': 'VolumeAttachment',
130+
'csinodes': 'CSINode',
131+
'csidrivers': 'CSIDriver',
132+
'csistoragecapacities': 'CSIStorageCapacity',
133+
134+
# Node API resources
135+
'runtimeclasses': 'RuntimeClass',
136+
137+
# API extensions resources
138+
'customresourcedefinitions': 'CustomResourceDefinition',
139+
140+
# Admission registration resources
141+
'mutatingwebhookconfigurations': 'MutatingWebhookConfiguration',
142+
'validatingwebhookconfigurations': 'ValidatingWebhookConfiguration',
143+
144+
# Certificates API resources
145+
'certificatesigningrequests': 'CertificateSigningRequest',
146+
147+
# Coordination API resources
148+
'leases': 'Lease',
149+
150+
# Discovery API resources
151+
'endpointslices': 'EndpointSlice',
152+
}
153+
154+
# 先查找直接映射
155+
if resource_type.lower() in resource_kind_mapping:
156+
return resource_kind_mapping[resource_type.lower()]
157+
158+
# 如果没有直接映射,尝试通过 dynamic client 发现
159+
try:
160+
for api_resource in self._dynamic_client.resources.search(name=resource_type):
161+
return api_resource.kind
162+
except Exception:
163+
pass
164+
165+
# 如果还是找不到,使用简单的规则转换
166+
# 去掉末尾的 's',然后首字母大写
167+
if resource_type.endswith('s') and len(resource_type) > 1:
168+
kind = resource_type[:-1].capitalize()
169+
# 处理一些特殊情况
170+
if kind.endswith('ie'):
171+
kind = kind[:-2] + 'y' # policies -> policy -> Policy
172+
elif kind.endswith('sse'):
173+
kind = kind[:-1] # classes -> classe -> class -> Class
174+
return kind
175+
else:
176+
# 如果没有找到合适的映射,返回原始资源类型的大写形式
177+
return resource_type.capitalize()
178+
70179
def _infer_api_version(self, resource_type: str) -> str:
71180
"""
72181
根据资源类型和 Kubernetes 版本推断 API 版本。
@@ -183,7 +292,7 @@ def _infer_api_version(self, resource_type: str) -> str:
183292
# 对于未知的资源类型,尝试使用 dynamic client 的发现功能
184293
try:
185294
# 尝试通过 API 发现找到资源
186-
for api_resource in self._dynamic_client.resources.search(kind=resource_type):
295+
for api_resource in self._dynamic_client.resources.search(kind=self._infer_kind_from_resource_type(resource_type)):
187296
return api_resource.group_version
188297
# 如果没有找到,抛出错误
189298
raise ValueError(f"无法推断资源 '{resource_type}' 的 API 版本,请明确提供 'api_version' 参数。")
@@ -305,7 +414,7 @@ def _get_resource(
305414
if not api_version:
306415
api_version = self._infer_api_version(resource_type)
307416

308-
resource_client = self._dynamic_client.resources.get(api_version=api_version, kind=resource_type)
417+
resource_client = self._dynamic_client.resources.get(api_version=api_version, kind=self._infer_kind_from_resource_type(resource_type))
309418

310419
# 构建查询参数
311420
params = {
@@ -360,7 +469,7 @@ def get_resource(
360469
if not api_version:
361470
api_version = self._infer_api_version(resource_type)
362471

363-
resource_client = self._dynamic_client.resources.get(api_version=api_version, kind=resource_type)
472+
resource_client = self._dynamic_client.resources.get(api_version=api_version, kind=self._infer_kind_from_resource_type(resource_type))
364473

365474
# 检查资源是否为命名空间级别
366475
if resource_client.namespaced and not namespace:
@@ -549,7 +658,7 @@ def list_resource(
549658
if not api_version:
550659
api_version = self._infer_api_version(resource_type)
551660

552-
resource_client = self._dynamic_client.resources.get(api_version=api_version, kind=resource_type)
661+
resource_client = self._dynamic_client.resources.get(api_version=api_version, kind=self._infer_kind_from_resource_type(resource_type))
553662

554663
# 构建查询参数
555664
params = {
@@ -670,7 +779,7 @@ def create_resource(
670779
try:
671780
# 获取 dynamic client resource
672781
# 获取 resource 对象
673-
resource = self._dynamic_client.resources.get(api_version=resolved_api_version, kind=resource_type)
782+
resource = self._dynamic_client.resources.get(api_version=resolved_api_version, kind=self._infer_kind_from_resource_type(resource_type))
674783

675784
#resource_client = self._dynamic_client.resources.get(api_version=resolved_api_version, kind=resource_type)
676785
res = self._dynamic_client.create(resource, body = resource_body, namespace=namespace)
@@ -743,7 +852,7 @@ def find_resource_api_version(self, resource_type: str) -> Optional[str]:
743852
"""
744853
try:
745854
# 搜索匹配的资源
746-
for api_resource in self._dynamic_client.resources.search(kind=resource_type):
855+
for api_resource in self._dynamic_client.resources.search(kind=self._infer_kind_from_resource_type(resource_type)):
747856
return api_resource.group_version
748857
return None
749858
except Exception as e:
@@ -763,7 +872,7 @@ def validate_resource_and_api_version(self, resource_type: str, api_version: str
763872
"""
764873
try:
765874
# 尝试获取资源客户端
766-
self._dynamic_client.resources.get(api_version=api_version, kind=resource_type)
875+
self._dynamic_client.resources.get(api_version=api_version, kind=self._infer_kind_from_resource_type(resource_type))
767876
return True
768877
except Exception:
769878
return False
@@ -783,7 +892,7 @@ def get_resource_info(self, resource_type: str, api_version: Optional[str] = Non
783892
if not api_version:
784893
api_version = self._infer_api_version(resource_type)
785894

786-
resource_client = self._dynamic_client.resources.get(api_version=api_version, kind=resource_type)
895+
resource_client = self._dynamic_client.resources.get(api_version=api_version, kind=self._infer_kind_from_resource_type(resource_type))
787896

788897
return {
789898
"name": resource_client.name,
@@ -831,7 +940,7 @@ def delete_resource(
831940
if not api_version:
832941
api_version = self._infer_api_version(resource_type)
833942

834-
resource_client = self._dynamic_client.resources.get(api_version=api_version, kind=resource_type)
943+
resource_client = self._dynamic_client.resources.get(api_version=api_version, kind=self._infer_kind_from_resource_type(resource_type))
835944

836945
# 检查资源是否为命名空间级别
837946
if resource_client.namespaced and not namespace:
@@ -987,7 +1096,7 @@ def update_resource(
9871096
try:
9881097
# 获取 dynamic client resource
9891098
# 获取 resource 对象
990-
resource = self._dynamic_client.resources.get(api_version=resolved_api_version, kind=resource_type)
1099+
resource = self._dynamic_client.resources.get(api_version=resolved_api_version, kind=self._infer_kind_from_resource_type(resource_type))
9911100

9921101
#resource_client = self._dynamic_client.resources.get(api_version=resolved_api_version, kind=resource_type)
9931102
res = self._dynamic_client.replace(resource, body = resource_body, namespace=namespace)

dingo_command/common/network.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ def get_network_ports(network_name):
2424
return None
2525
return ports[0]
2626

27-
def assign_ports_to_ovs(port):
27+
def assign_ports_to_ovs(port, node_ip):
28+
#ssh到node_ip上执行命令cmd命令
29+
2830
iface = port['name']
2931
mac = port['mac_address']
3032
iface_id = port['id']
@@ -112,8 +114,8 @@ def init_cluster_network(project_id:str, subnet_id:str):
112114
})
113115

114116
# 将端口分配到 OVS
115-
assign_ports_to_ovs(port)
116-
print(f"控制节点 {node['name']} 的网络端口已分配到 OVS")
117+
assign_ports_to_ovs(port, node)
118+
print(f"控制节点 {node['name']} 的网络端口已分配到 OVS")
117119
cmd = f"ip route add {node['name']} {cidr} via {port_ip} dev dingo-port-{node['name']}"
118120
subprocess.run(cmd, shell=True, check=True)
119121

0 commit comments

Comments
 (0)