ydb-embedded-ui 4.0.0 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/components/ClusterInfo/ClusterInfo.tsx +3 -3
  3. package/dist/{containers/Nodes/NodesTable.scss → components/NodeHostWrapper/NodeHostWrapper.scss} +4 -6
  4. package/dist/components/NodeHostWrapper/NodeHostWrapper.tsx +60 -0
  5. package/dist/containers/AsideNavigation/AsideNavigation.tsx +1 -11
  6. package/dist/containers/Header/Header.tsx +1 -1
  7. package/dist/containers/Nodes/getNodesColumns.tsx +7 -46
  8. package/dist/containers/Storage/StorageNodes/StorageNodes.scss +0 -24
  9. package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +2 -39
  10. package/dist/containers/Tenants/Tenants.js +1 -1
  11. package/dist/services/api.ts +383 -0
  12. package/dist/store/reducers/{cluster.js → cluster/cluster.ts} +9 -14
  13. package/dist/store/reducers/cluster/types.ts +13 -0
  14. package/dist/store/reducers/executeTopQueries.ts +2 -2
  15. package/dist/store/reducers/index.ts +5 -4
  16. package/dist/store/reducers/settings.js +1 -14
  17. package/dist/store/reducers/{tenants.js → tenants/tenants.ts} +14 -9
  18. package/dist/store/reducers/tenants/types.ts +17 -0
  19. package/dist/store/utils.ts +3 -2
  20. package/dist/types/api/acl.ts +25 -0
  21. package/dist/types/api/cluster.ts +3 -0
  22. package/dist/types/api/compute.ts +5 -3
  23. package/dist/types/api/netInfo.ts +48 -0
  24. package/dist/types/api/nodes.ts +5 -3
  25. package/dist/types/api/pdisk.ts +11 -2
  26. package/dist/types/api/storage.ts +5 -3
  27. package/dist/types/api/tenant.ts +18 -3
  28. package/dist/types/api/vdisk.ts +10 -2
  29. package/dist/types/api/whoami.ts +19 -0
  30. package/dist/types/window.d.ts +5 -0
  31. package/dist/utils/hooks/useTypedSelector.ts +2 -2
  32. package/dist/utils/nodes.ts +3 -1
  33. package/package.json +1 -1
  34. package/dist/services/api.d.ts +0 -87
  35. package/dist/services/api.js +0 -278
@@ -0,0 +1,48 @@
1
+ import type {EFlag} from './enums';
2
+
3
+ /**
4
+ * endpoint: /viewer/json/netinfo
5
+ *
6
+ * source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/protos/viewer.proto
7
+ */
8
+ export interface TNetInfo {
9
+ Overall: EFlag;
10
+ Tenants?: TNetTenantInfo[];
11
+ }
12
+
13
+ interface TNetTenantInfo {
14
+ Overall: EFlag;
15
+ Name: string;
16
+ Nodes?: TNetNodeInfo[];
17
+ }
18
+
19
+ interface TNetNodeInfo {
20
+ NodeId: number;
21
+ Overall: EFlag;
22
+ Peers?: TNetNodePeerInfo[];
23
+ NodeType: ENodeType;
24
+ DataCenter: string;
25
+ Rack: string;
26
+ Host: string;
27
+ Port: number;
28
+ }
29
+
30
+ interface TNetNodePeerInfo {
31
+ NodeId: number;
32
+ PeerName: string;
33
+ Connected: boolean;
34
+ ConnectStatus: EFlag;
35
+ /** uint64 */
36
+ ChangeTime: string;
37
+ NodeType: ENodeType;
38
+ DataCenter: string;
39
+ Rack: string;
40
+ Host: string;
41
+ Port: number;
42
+ }
43
+
44
+ enum ENodeType {
45
+ UnknownNodeType,
46
+ Static,
47
+ Dynamic,
48
+ }
@@ -3,9 +3,11 @@ import {TPDiskStateInfo} from './pdisk';
3
3
  import {TTabletStateInfo} from './tablet';
4
4
  import {TVDiskStateInfo} from './vdisk';
5
5
 
6
- // endpoint: /viewer/json/nodes
7
- // source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/protos/viewer.proto
8
-
6
+ /**
7
+ * endpoint: /viewer/json/nodes
8
+ *
9
+ * source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/protos/viewer.proto
10
+ */
9
11
  export interface TNodesInfo {
10
12
  Overall?: EFlag;
11
13
  Nodes?: TNodeInfo[];
@@ -1,7 +1,16 @@
1
1
  import {EFlag} from './enums';
2
2
 
3
- // endpoint: /viewer/json/pdiskinfo
4
- // source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/protos/node_whiteboard.proto
3
+ /**
4
+ * endpoint: /viewer/json/pdiskinfo
5
+ *
6
+ * source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/protos/node_whiteboard.proto
7
+ */
8
+ export interface TEvPDiskStateResponse {
9
+ PDiskStateInfo?: TPDiskStateInfo[];
10
+ /** uint64 */
11
+ ResponseTime?: string;
12
+ ResponseDuration?: number;
13
+ }
5
14
 
6
15
  export interface TPDiskStateInfo {
7
16
  PDiskId?: number;
@@ -1,9 +1,11 @@
1
1
  import {EFlag} from './enums';
2
2
  import {TVDiskStateInfo} from './vdisk';
3
3
 
4
- // endpoint: /viewer/json/storage
5
- // source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/protos/viewer.proto
6
-
4
+ /**
5
+ * endpoint: /viewer/json/storage
6
+ *
7
+ * source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/protos/viewer.proto
8
+ */
7
9
  export interface TStorageInfo {
8
10
  Overall?: EFlag;
9
11
  StoragePools?: TStoragePoolInfo[];
@@ -2,13 +2,20 @@ import {EFlag} from './enums';
2
2
  import {TPoolStats, TSystemStateInfo} from './nodes';
3
3
  import {TTabletStateInfo} from './tablet';
4
4
 
5
- // endpoint: /viewer/json/tenantinfo
6
- // source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/protos/viewer.proto
7
-
5
+ /**
6
+ * endpoint: /viewer/json/tenants
7
+ *
8
+ * source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/protos/viewer.proto
9
+ */
8
10
  export interface TTenants {
9
11
  Tenants?: TTenant[];
10
12
  }
11
13
 
14
+ /**
15
+ * endpoint: /viewer/json/tenantinfo
16
+ *
17
+ * source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/protos/viewer.proto
18
+ */
12
19
  export interface TTenantInfo {
13
20
  TenantInfo?: TTenant[];
14
21
  Errors?: string[];
@@ -47,6 +54,9 @@ export interface TTenant {
47
54
  CoresUsed: number;
48
55
  /** uint64 */
49
56
  StorageGroups: string;
57
+
58
+ MonitoringEndpoint?: string; // additional
59
+ ControlPlane?: ControlPlane; // additional
50
60
  }
51
61
 
52
62
  interface THiveDomainStatsStateCount {
@@ -107,6 +117,11 @@ interface TTenantResource {
107
117
  Count: number;
108
118
  }
109
119
 
120
+ /** incomplete */
121
+ interface ControlPlane {
122
+ name?: string;
123
+ }
124
+
110
125
  export enum ETenantType {
111
126
  'UnknownTenantType' = 'UnknownTenantType',
112
127
  'Domain' = 'Domain',
@@ -1,8 +1,16 @@
1
1
  import {EFlag} from './enums';
2
2
  import {TPDiskStateInfo} from './pdisk';
3
3
 
4
- // endpoint: /viewer/json/vdiskinfo
5
- // source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/protos/node_whiteboard.proto
4
+ /**
5
+ * endpoint: /viewer/json/vdiskinfo
6
+ *
7
+ * source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/protos/node_whiteboard.proto
8
+ */
9
+ export interface TEvVDiskStateResponse {
10
+ VDiskStateInfo?: TVDiskStateInfo[];
11
+ ResponseTime?: string;
12
+ ResponseDuration?: number;
13
+ }
6
14
 
7
15
  export interface TVDiskStateInfo {
8
16
  VDiskId?: TVDiskID;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * endpoint: /viewer/json/whoami
3
+ *
4
+ * source: https://github.com/ydb-platform/ydb/blob/main/ydb/library/aclib/protos/aclib.proto
5
+ */
6
+ export interface TUserToken {
7
+ UserSID?: string;
8
+ GroupSIDs?: TProtoHashTable;
9
+ OriginalUserToken?: string;
10
+ AuthType?: string;
11
+ }
12
+
13
+ interface TProtoHashTable {
14
+ Buckets?: TProtoHashBucket[];
15
+ }
16
+
17
+ interface TProtoHashBucket {
18
+ Values?: string[];
19
+ }
@@ -37,4 +37,9 @@ interface Window {
37
37
  custom_backend?: string;
38
38
 
39
39
  __REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: typeof import('redux').compose;
40
+
41
+ userSettings?: Record<string, string | undefined>;
42
+ systemSettings?: Record<string, string | undefined>;
43
+
44
+ api: import('../services/api').YdbEmbeddedAPI;
40
45
  }
@@ -1,5 +1,5 @@
1
1
  import {TypedUseSelectorHook, useSelector} from 'react-redux';
2
2
 
3
- import {IRootState} from '../../store';
3
+ import {RootState} from '../../store';
4
4
 
5
- export const useTypedSelector: TypedUseSelectorHook<IRootState> = useSelector;
5
+ export const useTypedSelector: TypedUseSelectorHook<RootState> = useSelector;
@@ -15,6 +15,8 @@ export const NodesUptimeFilterTitles = {
15
15
  export const isUnavailableNode = (node: INodesPreparedEntity | TSystemStateInfo) =>
16
16
  !node.SystemState || node.SystemState === EFlag.Grey;
17
17
 
18
+ export type NodeAddress = Pick<TSystemStateInfo, 'Host' | 'Endpoints'>;
19
+
18
20
  export interface AdditionalNodesInfo extends Record<string, unknown> {
19
- getNodeRef?: Function;
21
+ getNodeRef?: (node?: NodeAddress) => string;
20
22
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ydb-embedded-ui",
3
- "version": "4.0.0",
3
+ "version": "4.1.0",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -1,87 +0,0 @@
1
- type AxiosOptions = {
2
- concurrentId?: string;
3
- };
4
-
5
- interface Window {
6
- api: {
7
- getSchema: (
8
- params: {path: string},
9
- axiosOptions?: AxiosOptions,
10
- ) => Promise<import('../types/api/schema').TEvDescribeSchemeResult>;
11
- getDescribe: (
12
- params: {path: string},
13
- axiosOptions?: AxiosOptions,
14
- ) => Promise<import('../types/api/schema').TEvDescribeSchemeResult>;
15
- getStorageInfo: (
16
- params: {
17
- tenant: string;
18
- filter: string;
19
- nodeId: string;
20
- },
21
- axiosOptions?: AxiosOptions,
22
- ) => Promise<import('../types/api/storage').TStorageInfo>;
23
- getNodes: (
24
- params: import('../types/store/nodes').INodesApiRequestParams,
25
- axiosOptions?: AxiosOptions,
26
- ) => Promise<import('../types/api/nodes').TNodesInfo>;
27
- getCompute: (path: string) => Promise<import('../types/api/compute').TComputeInfo>;
28
- sendQuery: <
29
- Action extends import('../types/api/query').Actions,
30
- Schema extends import('../types/api/query').Schemas = undefined,
31
- >(
32
- params: {
33
- query?: string;
34
- database?: string;
35
- action?: Action;
36
- stats?: string;
37
- schema?: Schema;
38
- },
39
- axiosOptions?: AxiosOptions,
40
- ) => Promise<import('../types/api/query').QueryAPIResponse<Action, Schema>>;
41
- getExplainQuery: <Action extends import('../types/api/query').ExplainActions = 'explain'>(
42
- query: string,
43
- database: string,
44
- action?: Action,
45
- ) => Promise<import('../types/api/query').ExplainResponse<Action>>;
46
- getExplainQueryAst: (
47
- query: string,
48
- database: string,
49
- ) => Promise<import('../types/api/query').ExplainResponse<'explain-ast'>>;
50
- getHealthcheckInfo: (
51
- database: string,
52
- ) => Promise<import('../types/api/healthcheck').HealthCheckAPIResponse>;
53
- getTenantInfo: (params: {
54
- path: string;
55
- }) => Promise<import('../types/api/tenant').TTenantInfo>;
56
- getClusterInfo: () => Promise<import('../types/api/cluster').TClusterInfo>;
57
- getTabletsInfo: (params: {
58
- nodes?: string[];
59
- path?: string;
60
- }) => Promise<import('../types/api/tablet').TEvTabletStateResponse>;
61
- getTabletDescribe: (
62
- tenantId?: import('../types/api/tablet').TDomainKey,
63
- ) => Promise<import('../types/api/schema').TEvDescribeSchemeResult>;
64
- getTablet: (params: {
65
- id?: string;
66
- }) => Promise<import('../types/api/tablet').TEvTabletStateResponse>;
67
- getTabletHistory: (params: {
68
- id?: string;
69
- }) => Promise<import('../types/api/tablet').UnmergedTEvTabletStateResponse>;
70
- getHeatmapData: (params: {
71
- path: string;
72
- }) => Promise<import('../types/api/schema').TEvDescribeSchemeResult>;
73
- getTopic: (params: {
74
- path?: string;
75
- }) => Promise<import('../types/api/topic').DescribeTopicResult>;
76
- getConsumer: (params: {
77
- path?: string;
78
- consumer?: string;
79
- }) => Promise<import('../types/api/consumer').DescribeConsumerResult>;
80
- getHostInfo: () => Promise<import('../types/api/systemState').TEvSystemStateResponse>;
81
- getNodeInfo: (
82
- id?: string,
83
- ) => Promise<import('../types/api/systemState').TEvSystemStateResponse>;
84
- getNodesList: () => Promise<import('../types/api/nodesList').TEvNodesInfo>;
85
- [method: string]: Function;
86
- };
87
- }
@@ -1,278 +0,0 @@
1
- import AxiosWrapper from '@gravity-ui/axios-wrapper';
2
-
3
- import {backend as BACKEND} from '../store';
4
-
5
- const config = {withCredentials: !window.custom_backend};
6
-
7
- const {settingsApi} = window.web_version ? window.systemSettings : {};
8
-
9
- export class YdbEmbeddedAPI extends AxiosWrapper {
10
- getPath(path) {
11
- return `${BACKEND}${path}`;
12
- }
13
- getClusterInfo() {
14
- return this.get(this.getPath('/viewer/json/cluster'), {tablets: true});
15
- }
16
- getNodeInfo(id) {
17
- return this.get(this.getPath('/viewer/json/sysinfo?enums=true'), {
18
- node_id: id,
19
- });
20
- }
21
- getTenants() {
22
- return this.get(this.getPath('/viewer/json/tenantinfo'), {
23
- tablets: 1,
24
- storage: 1,
25
- });
26
- }
27
- getTenantInfo({path}) {
28
- return this.get(this.getPath('/viewer/json/tenantinfo'), {
29
- path,
30
- tablets: true,
31
- storage: true,
32
- });
33
- }
34
- getNodes({tenant, filter, storage, type = 'any', tablets = true}, {concurrentId} = {}) {
35
- return this.get(
36
- this.getPath('/viewer/json/nodes?enums=true'),
37
- {
38
- tenant,
39
- with: filter,
40
- storage,
41
- type,
42
- tablets,
43
- },
44
- {
45
- concurrentId,
46
- },
47
- );
48
- }
49
- getCompute(path) {
50
- return this.get(this.getPath('/viewer/json/compute?enums=true'), {path});
51
- }
52
- getStorageInfo({tenant, filter, nodeId}, {concurrentId} = {}) {
53
- return this.get(
54
- this.getPath(`/viewer/json/storage?enums=true`),
55
- {
56
- tenant,
57
- node_id: nodeId,
58
- with: filter,
59
- },
60
- {
61
- concurrentId,
62
- },
63
- );
64
- }
65
- getPdiskInfo(nodeId, pdiskId) {
66
- return this.get(this.getPath('/viewer/json/pdiskinfo?enums=true'), {
67
- filter: `(NodeId=${nodeId}${pdiskId ? `;PDiskId=${pdiskId}` : ''})`,
68
- });
69
- }
70
- getVdiskInfo({vdiskId, pdiskId, nodeId}) {
71
- return this.get(this.getPath('/viewer/json/vdiskinfo?enums=true'), {
72
- filter: `(VDiskId=${vdiskId ?? ''};PDiskId=${pdiskId ?? ''};NodeId=${nodeId ?? ''})`,
73
- });
74
- }
75
- getGroupInfo(groupId) {
76
- return this.get(this.getPath('/viewer/json/storage?enums=true'), {
77
- group_id: groupId,
78
- });
79
- }
80
- getHostInfo() {
81
- return this.get(this.getPath('/viewer/json/sysinfo?node_id=.&enums=true'));
82
- }
83
- getTabletsInfo({nodes = [], path}) {
84
- const filter = nodes.length > 0 && `(NodeId=[${nodes.join(',')}])`;
85
- return this.get(this.getPath('/viewer/json/tabletinfo'), {
86
- filter,
87
- path,
88
- enums: true,
89
- });
90
- }
91
- getSchema({path}, {concurrentId} = {}) {
92
- return this.get(
93
- this.getPath('/viewer/json/describe'),
94
- {
95
- path,
96
- enums: true,
97
- backup: false,
98
- private: true,
99
- partition_config: true,
100
- partition_stats: true,
101
- partitioning_info: true,
102
- subs: 1,
103
- },
104
- {concurrentId: concurrentId || `getSchema|${path}`},
105
- );
106
- }
107
- getDescribe({path}, {concurrentId} = {}) {
108
- return this.get(
109
- this.getPath('/viewer/json/describe'),
110
- {
111
- path,
112
- enums: true,
113
- partition_stats: true,
114
- subs: 0,
115
- },
116
- {concurrentId: concurrentId || `getDescribe|${path}`},
117
- );
118
- }
119
- getSchemaAcl({path}) {
120
- return this.get(
121
- this.getPath('/viewer/json/acl'),
122
- {
123
- path,
124
- },
125
- {concurrentId: `getSchemaAcl|${path}`},
126
- );
127
- }
128
- getHeatmapData({path}) {
129
- return this.get(this.getPath('/viewer/json/describe'), {
130
- path,
131
- enums: true,
132
- backup: false,
133
- children: false,
134
- partition_config: false,
135
- partition_stats: true,
136
- });
137
- }
138
- getNetwork(path) {
139
- return this.get(this.getPath('/viewer/json/netinfo'), {
140
- enums: true,
141
- path,
142
- });
143
- }
144
- getTopic({path}, {concurrentId} = {}) {
145
- return this.get(
146
- this.getPath('/viewer/json/describe_topic'),
147
- {
148
- enums: true,
149
- include_stats: true,
150
- path,
151
- },
152
- {concurrentId: concurrentId || 'getTopic'},
153
- );
154
- }
155
- getConsumer({path, consumer}, {concurrentId} = {}) {
156
- return this.get(
157
- this.getPath('/viewer/json/describe_consumer'),
158
- {
159
- enums: true,
160
- include_stats: true,
161
- path,
162
- consumer,
163
- },
164
- {concurrentId: concurrentId || 'getConsumer'},
165
- );
166
- }
167
- getPoolInfo(poolName) {
168
- return this.get(this.getPath('/viewer/json/storage'), {
169
- pool: poolName,
170
- enums: true,
171
- });
172
- }
173
- getTablet({id}) {
174
- return this.get(this.getPath(`/viewer/json/tabletinfo?filter=(TabletId=${id})`), {
175
- enums: true,
176
- });
177
- }
178
- getTabletHistory({id}) {
179
- return this.get(this.getPath(`/viewer/json/tabletinfo?filter=(TabletId=${id})`), {
180
- enums: true,
181
- merge: false,
182
- });
183
- }
184
- getNodesList() {
185
- return this.get(this.getPath('/viewer/json/nodelist'), {enums: true});
186
- }
187
- getTenantsList() {
188
- return this.get(this.getPath('/viewer/json/tenants'), {
189
- enums: true,
190
- state: 0,
191
- });
192
- }
193
- sendQuery({query, database, action, stats, schema}, {concurrentId} = {}) {
194
- return this.post(
195
- this.getPath(`/viewer/json/query${schema ? `?schema=${schema}` : ''}`),
196
- {
197
- query,
198
- database,
199
- action,
200
- stats,
201
- timeout: 600000,
202
- },
203
- null,
204
- {
205
- concurrentId,
206
- timeout: 9 * 60 * 1000,
207
- },
208
- );
209
- }
210
- getExplainQuery(query, database, action = 'explain') {
211
- return this.post(this.getPath('/viewer/json/query'), {
212
- query,
213
- database,
214
- action,
215
- timeout: 600000,
216
- });
217
- }
218
- getExplainQueryAst(query, database) {
219
- return this.post(this.getPath('/viewer/json/query'), {
220
- query,
221
- database,
222
- action: 'explain-ast',
223
- timeout: 600000,
224
- });
225
- }
226
- getHotKeys(path, enableSampling) {
227
- return this.get(this.getPath('/viewer/json/hotkeys'), {
228
- path,
229
- enable_sampling: enableSampling,
230
- });
231
- }
232
- getHealthcheckInfo(database) {
233
- return this.get(this.getPath('/viewer/json/healthcheck'), {
234
- tenant: database,
235
- });
236
- }
237
- killTablet(id) {
238
- return this.get(this.getPath(`/tablets?KillTabletID=${id}`));
239
- }
240
- stopTablet(id, hiveId) {
241
- return this.get(
242
- this.getPath(`/tablets/app?TabletID=${hiveId}&page=StopTablet&tablet=${id}`),
243
- );
244
- }
245
- resumeTablet(id, hiveId) {
246
- return this.get(
247
- this.getPath(`/tablets/app?TabletID=${hiveId}&page=ResumeTablet&tablet=${id}`),
248
- );
249
- }
250
- getTabletDescribe(tenantId) {
251
- return this.get(this.getPath('/viewer/json/describe'), {
252
- schemeshard_id: tenantId?.SchemeShard,
253
- path_id: tenantId?.PathId,
254
- });
255
- }
256
- postSetting(name, value) {
257
- return this.request({
258
- method: 'PATCH',
259
- url: settingsApi,
260
- data: {[name]: value},
261
- });
262
- }
263
- authenticate(user, password) {
264
- return this.post(this.getPath('/login'), {
265
- user,
266
- password,
267
- });
268
- }
269
- logout() {
270
- return this.post(this.getPath('/logout'), {});
271
- }
272
- whoami() {
273
- return this.get(this.getPath('/viewer/json/whoami'));
274
- }
275
- }
276
-
277
- const api = new YdbEmbeddedAPI({config: config});
278
- window.api = api;