Skip to content

Commit 76f6320

Browse files
authored
feat(console): support get app from target namespace (#1507)
* feat: support get app from target namespace * fix: type error
1 parent cb97532 commit 76f6320

File tree

5 files changed

+72
-83
lines changed

5 files changed

+72
-83
lines changed

web/console/helpers/urlUtil.ts

Lines changed: 30 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
import { remove, isEmpty } from '../src/modules/common/utils';
22
import { ResourceInfo } from '../src/modules/common';
33
import { resourceConfig } from '../config';
4+
import { isObject } from 'lodash';
45

5-
export function parseQueryString(str: string = '') {
6-
let result = {};
6+
export function parseQueryString(str = '') {
7+
const result = {};
78
str
89
.replace(/^\?*/, '')
910
.split('&')
1011
.forEach(item => {
11-
let keyVal = item.split('=');
12+
const keyVal = item.split('=');
1213
if (keyVal.length > 0) {
13-
let key = decodeURIComponent(keyVal[0]);
14+
const key = decodeURIComponent(keyVal[0]);
1415
result[key] = keyVal[1] ? decodeURIComponent(keyVal[1]) : '';
1516
}
1617
});
1718
return result;
1819
}
1920

2021
export function buildQueryString(obj: any = {}) {
21-
let keys = remove(Object.keys(obj), value => value === '');
22-
let queryStr = keys.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`).join('&');
22+
const keys = remove(Object.keys(obj), value => value === '');
23+
const queryStr = keys.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`).join('&');
2324

2425
if (queryStr) {
2526
return '?' + queryStr;
@@ -46,46 +47,25 @@ export const reduceK8sQueryString = ({
4647
k8sQueryObj = {},
4748
restfulPath = ''
4849
}: {
49-
k8sQueryObj: any;
50+
k8sQueryObj: Record<string, string | number | boolean | Record<string, string | number | boolean>>;
5051
restfulPath?: string;
5152
}) => {
52-
let operator = '?';
53-
let queryString = '';
54-
if (!isEmpty(k8sQueryObj)) {
55-
let queryKeys = Object.keys(k8sQueryObj);
56-
queryKeys.forEach((queryKey, index) => {
57-
if (index !== 0) {
58-
queryString += '&';
59-
}
60-
61-
// 这里去判断每种资源的query,eg:fieldSelector、limit等
62-
let specificQuery = k8sQueryObj[queryKey];
63-
64-
if (typeof specificQuery === 'object') {
65-
// 这里是对于 query的字段里面,还有多种过滤条件,比如fieldSelector支持 involvedObject.name=*,involvedObject.kind=*
66-
let specificKeys = Object.keys(specificQuery),
67-
specificString = '';
68-
specificKeys.forEach((speKey, index) => {
69-
if (index !== 0) {
70-
specificString += ',';
71-
}
72-
specificString += speKey + '=' + specificQuery[speKey];
73-
});
74-
if (specificString) {
75-
queryString += queryKey + '=' + specificString;
76-
}
77-
} else {
78-
queryString += queryKey + '=' + k8sQueryObj[queryKey];
79-
}
80-
});
81-
}
82-
83-
/** 如果原本的url里面已经有 ? 了,则我们这里的query的内容,必须是拼接在后面,而不能直接加多一个 ? */
84-
if (restfulPath.includes('?')) {
85-
operator = '&';
86-
}
87-
88-
return queryString ? `${operator}${queryString}` : '';
53+
const queryString = Object.entries(k8sQueryObj)
54+
.map(([key, value]) => {
55+
// 也许value是object,即labelSelector 或者 fieldSelector
56+
value = isObject(value)
57+
? Object.entries(value)
58+
.map(([key, value]) => `${key}${value && '='}${value}`)
59+
.join(',')
60+
: value;
61+
62+
return `${key}=${encodeURIComponent(`${value}`)}`;
63+
})
64+
.join('&');
65+
66+
const preFix = restfulPath.includes('?') ? '&' : '?';
67+
68+
return queryString ? `${preFix}${queryString}` : '';
8969
};
9070

9171
interface K8sRestfulPathOptions {
@@ -114,7 +94,6 @@ interface K8sRestfulPathOptions {
11494
logAgentName?: string;
11595

11696
meshId?: string;
117-
11897
}
11998

12099
/**
@@ -134,12 +113,12 @@ export const reduceK8sRestfulPath = (options: K8sRestfulPathOptions) => {
134113
extraResource = '',
135114
clusterId = '',
136115
meshId = '',
137-
logAgentName = '',
116+
logAgentName = ''
138117
} = options;
139118

140119
namespace = namespace.replace(new RegExp(`^${clusterId}-`), '');
141-
let url: string = '';
142-
let isAddon = resourceInfo.requestType && resourceInfo.requestType.addon ? resourceInfo.requestType.addon : false;
120+
let url = '';
121+
const isAddon = resourceInfo.requestType && resourceInfo.requestType.addon ? resourceInfo.requestType.addon : false;
143122

144123
/**
145124
* addon 和 非 addon的资源,请求的url 不太一样
@@ -153,12 +132,12 @@ export const reduceK8sRestfulPath = (options: K8sRestfulPathOptions) => {
153132
*/
154133
if (isAddon) {
155134
// 兼容新旧日志组件
156-
let baseInfo: ResourceInfo = resourceConfig()[logAgentName ? 'logagent' : 'cluster'];
157-
let baseValue = logAgentName || clusterId;
135+
const baseInfo: ResourceInfo = resourceConfig()[logAgentName ? 'logagent' : 'cluster'];
136+
const baseValue = logAgentName || clusterId;
158137
url = `/${baseInfo.basicEntry}/${baseInfo.group}/${baseInfo.version}/${baseInfo.requestType['list']}/${baseValue}/${resourceInfo.requestType['list']}`;
159138

160139
if (extraResource || resourceInfo['namespaces'] || specificName) {
161-
let queryArr: string[] = [];
140+
const queryArr: string[] = [];
162141
resourceInfo.namespaces && namespace && queryArr.push(`namespace=${namespace}`);
163142
specificName && queryArr.push(`name=${specificName}`);
164143
extraResource && queryArr.push(`action=${extraResource}`);

web/console/package-lock.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/console/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
"@babel/preset-env": "^7.0.0",
7878
"@babel/preset-react": "^7.0.0",
7979
"@types/jquery": "^3.5.5",
80+
"@types/lodash": "^4.14.172",
8081
"@types/marked": "^0.6.3",
8182
"@types/node": "^11.11.1",
8283
"@types/react": "^16.9.56",

web/console/src/modules/application/WebAPI.ts

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ import {
4646
export async function fetchClusterList(query: QueryState<void>) {
4747
const resourceInfo: ResourceInfo = resourceConfig()['cluster'];
4848
const url = reduceK8sRestfulPath({ resourceInfo });
49-
let rr: RequestResult = await GET({ url });
50-
let objs: Cluster[] = !rr.error && rr.data.items ? rr.data.items : [];
49+
const rr: RequestResult = await GET({ url });
50+
const objs: Cluster[] = !rr.error && rr.data.items ? rr.data.items : [];
5151
const result: RecordSet<Cluster> = {
5252
recordCount: objs.length,
5353
records: objs
@@ -63,8 +63,8 @@ export async function fetchNamespaceList(query: QueryState<NamespaceFilter>) {
6363
const { keyword, filter } = query;
6464
const resourceInfo: ResourceInfo = resourceConfig()['ns'];
6565
const url = reduceK8sRestfulPath({ resourceInfo });
66-
let rr: RequestResult = await GET({ url, clusterId: filter.cluster });
67-
let objs: Namespace[] = !rr.error && rr.data.items ? rr.data.items : [];
66+
const rr: RequestResult = await GET({ url, clusterId: filter.cluster });
67+
const objs: Namespace[] = !rr.error && rr.data.items ? rr.data.items : [];
6868
const result: RecordSet<Namespace> = {
6969
recordCount: objs.length,
7070
records: objs
@@ -80,8 +80,8 @@ export async function fetchProjectNamespaceList(query: QueryState<ProjectNamespa
8080
const { keyword, filter } = query;
8181
const resourceInfo: ResourceInfo = resourceConfig()['namespaces'];
8282
const url = reduceK8sRestfulPath({ resourceInfo, specificName: filter.projectId, extraResource: 'namespaces' });
83-
let rr: RequestResult = await GET({ url });
84-
let objs: ProjectNamespace[] = !rr.error && rr.data.items ? rr.data.items : [];
83+
const rr: RequestResult = await GET({ url });
84+
const objs: ProjectNamespace[] = !rr.error && rr.data.items ? rr.data.items : [];
8585
const result: RecordSet<ProjectNamespace> = {
8686
recordCount: objs.length,
8787
records: objs
@@ -96,12 +96,18 @@ export async function fetchProjectNamespaceList(query: QueryState<ProjectNamespa
9696
*/
9797
export async function fetchAppList(query: QueryState<AppFilter>) {
9898
const { keyword, filter } = query;
99-
const queryObj = {};
99+
const queryObj = {
100+
fieldSelector: {
101+
'spec.targetNamespace': filter.namespace,
102+
'spec.targetCluster': filter.cluster
103+
}
104+
};
100105
const resourceInfo: ResourceInfo = resourceConfig()['app'];
101-
const url = reduceK8sRestfulPath({ resourceInfo, namespace: filter.namespace, isSpecialNamespace: true });
106+
const url = reduceK8sRestfulPath({ resourceInfo: { ...resourceInfo, namespaces: undefined } });
102107
const queryString = reduceK8sQueryString({ k8sQueryObj: queryObj });
103-
let rr: RequestResult = await GET({ url: url + queryString, clusterId: filter.cluster, keyword });
104-
let objs: App[] = !rr.error && rr.data.items ? rr.data.items : [];
108+
109+
const rr: RequestResult = await GET({ url: url + queryString, clusterId: filter.cluster, keyword });
110+
const objs: App[] = !rr.error && rr.data.items ? rr.data.items : [];
105111
const result: RecordSet<App> = {
106112
recordCount: objs.length,
107113
records: objs
@@ -121,7 +127,7 @@ export async function fetchApp(filter: AppDetailFilter) {
121127
specificName: filter.name,
122128
isSpecialNamespace: true
123129
});
124-
let rr: RequestResult = await GET({ url, clusterId: filter.cluster });
130+
const rr: RequestResult = await GET({ url, clusterId: filter.cluster });
125131
return rr.data;
126132
}
127133

@@ -137,7 +143,7 @@ export async function updateApp([appInfo]) {
137143
specificName: appInfo.metadata.name,
138144
isSpecialNamespace: true
139145
});
140-
let rr: RequestResult = await PUT({ url, bodyData: appInfo });
146+
const rr: RequestResult = await PUT({ url, bodyData: appInfo });
141147
return operationResult(rr.data, rr.error);
142148
}
143149

@@ -152,7 +158,7 @@ export async function addApp([appInfo]) {
152158
namespace: appInfo.metadata.namespace,
153159
isSpecialNamespace: true
154160
});
155-
let rr: RequestResult = await POST({ url, bodyData: appInfo });
161+
const rr: RequestResult = await POST({ url, bodyData: appInfo });
156162
return operationResult(rr.data, rr.error);
157163
}
158164

@@ -161,14 +167,14 @@ export async function addApp([appInfo]) {
161167
* @param group
162168
*/
163169
export async function deleteApp([app]: App[]) {
164-
let resourceInfo: ResourceInfo = resourceConfig()['app'];
170+
const resourceInfo: ResourceInfo = resourceConfig()['app'];
165171
const url = reduceK8sRestfulPath({
166172
resourceInfo,
167173
namespace: app.metadata.namespace,
168174
specificName: app.metadata.name,
169175
isSpecialNamespace: true
170176
});
171-
let rr: RequestResult = await DELETE({ url });
177+
const rr: RequestResult = await DELETE({ url });
172178
return operationResult(rr.data, rr.error);
173179
}
174180

@@ -185,7 +191,7 @@ export async function fetchAppResource(filter: AppResourceFilter) {
185191
extraResource: 'resources',
186192
isSpecialNamespace: true
187193
});
188-
let rr: RequestResult = await GET({ url, clusterId: filter.cluster });
194+
const rr: RequestResult = await GET({ url, clusterId: filter.cluster });
189195
return rr.data;
190196
}
191197

@@ -202,7 +208,7 @@ export async function fetchAppHistory(filter: AppHistoryFilter) {
202208
extraResource: 'histories',
203209
isSpecialNamespace: true
204210
});
205-
let rr: RequestResult = await GET({ url, clusterId: filter.cluster });
211+
const rr: RequestResult = await GET({ url, clusterId: filter.cluster });
206212
return rr.data;
207213
}
208214

@@ -211,7 +217,7 @@ export async function fetchAppHistory(filter: AppHistoryFilter) {
211217
* @param group
212218
*/
213219
export async function rollbackApp([app]: History[]) {
214-
let resourceInfo: ResourceInfo = resourceConfig()['app'];
220+
const resourceInfo: ResourceInfo = resourceConfig()['app'];
215221
const namespace = (app.involvedObject && app.involvedObject.metadata && app.involvedObject.metadata.namespace) || '';
216222
const name = (app.involvedObject && app.involvedObject.metadata && app.involvedObject.metadata.name) || '';
217223
const cluster = (app.involvedObject && app.involvedObject.spec && app.involvedObject.spec.targetCluster) || '';
@@ -227,7 +233,7 @@ export async function rollbackApp([app]: History[]) {
227233
isSpecialNamespace: true
228234
});
229235
const queryString = reduceK8sQueryString({ k8sQueryObj: queryObj });
230-
let rr: RequestResult = await POST({ url: url + queryString, bodyData: {}, clusterId: cluster });
236+
const rr: RequestResult = await POST({ url: url + queryString, bodyData: {}, clusterId: cluster });
231237
return operationResult(rr.data, rr.error);
232238
}
233239

@@ -250,18 +256,15 @@ export async function fetchChartList(query: QueryState<ChartFilter>) {
250256
}
251257
: {};
252258
const resourceInfo: ResourceInfo = resourceConfig()['chart'];
253-
let opts = { resourceInfo: resourceInfo };
254-
if (filter.namespace) {
255-
opts['namespace'] = filter.namespace;
256-
opts['isSpecialNamespace'] = true;
257-
}
259+
const opts = { resourceInfo: { ...resourceInfo, namespaces: undefined } };
260+
258261
const url = reduceK8sRestfulPath(opts);
259262
const queryString = reduceK8sQueryString({ k8sQueryObj: queryObj });
260-
let rr: RequestResult = await GET({
263+
const rr: RequestResult = await GET({
261264
url: url + queryString,
262265
keyword
263266
});
264-
let objs: Chart[] = !rr.error && rr.data.items ? rr.data.items : [];
267+
const objs: Chart[] = !rr.error && rr.data.items ? rr.data.items : [];
265268
const result: RecordSet<Chart> = {
266269
recordCount: objs.length,
267270
records: objs
@@ -288,7 +291,7 @@ export async function fetchChartInfo(filter: ChartInfoFilter) {
288291
isSpecialNamespace: true
289292
});
290293
const queryString = reduceK8sQueryString({ k8sQueryObj: queryObj });
291-
let rr: RequestResult = await GET({
294+
const rr: RequestResult = await GET({
292295
url: url + '/' + filter.chartVersion + queryString
293296
});
294297
return rr.data;
@@ -304,8 +307,8 @@ export async function fetchChartGroupList(query: QueryState<ChartGroupFilter>) {
304307
const resourceInfo: ResourceInfo = resourceConfig()['chartgroup'];
305308
const url = reduceK8sRestfulPath({ resourceInfo });
306309
const queryString = reduceK8sQueryString({ k8sQueryObj: queryObj });
307-
let rr: RequestResult = await GET({ url: url + queryString, keyword });
308-
let objs: ChartGroup[] = !rr.error && rr.data.items ? rr.data.items : [];
310+
const rr: RequestResult = await GET({ url: url + queryString, keyword });
311+
const objs: ChartGroup[] = !rr.error && rr.data.items ? rr.data.items : [];
309312
const result: RecordSet<ChartGroup> = {
310313
recordCount: objs.length,
311314
records: objs
@@ -377,11 +380,11 @@ export async function fetchPortalProjectList(query: QueryState<void>) {
377380
};
378381
const resourceInfo: ResourceInfo = resourceConfig()['portal'];
379382
const url = reduceK8sRestfulPath({ resourceInfo });
380-
let rr: RequestResult = await GET({ url });
383+
const rr: RequestResult = await GET({ url });
381384
if (rr.error) {
382385
return empty;
383386
}
384-
let items = Object.keys(rr.data.projects).map(key => {
387+
const items = Object.keys(rr.data.projects).map(key => {
385388
return {
386389
id: key,
387390
metadata: {

web/console/src/modules/registry/WebAPI.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ export async function fetchChartList(query: QueryState<ChartFilter>) {
709709
}
710710
: {};
711711
const resourceInfo: ResourceInfo = resourceConfig()['chart'];
712-
const opts = { resourceInfo: resourceInfo };
712+
const opts = { resourceInfo: { ...resourceInfo, namespaces: undefined } };
713713
// if (filter.namespace) {
714714
// opts['namespace'] = filter.namespace;
715715
// opts['isSpecialNamespace'] = true;

0 commit comments

Comments
 (0)