@gcnv/gcnv-mcp-server 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/GEMINI.md +253 -0
  2. package/LICENSE +201 -0
  3. package/README.md +493 -0
  4. package/build/index.js +185 -0
  5. package/build/logger.js +19 -0
  6. package/build/registry/register-tools.js +110 -0
  7. package/build/registry/tool-registry.js +39 -0
  8. package/build/tools/active-directory-tools.js +132 -0
  9. package/build/tools/backup-policy-tools.js +140 -0
  10. package/build/tools/backup-tools.js +206 -0
  11. package/build/tools/backup-vault-tools.js +197 -0
  12. package/build/tools/handlers/active-directory-handler.js +327 -0
  13. package/build/tools/handlers/backup-handler.js +534 -0
  14. package/build/tools/handlers/backup-policy-handler.js +275 -0
  15. package/build/tools/handlers/backup-vault-handler.js +374 -0
  16. package/build/tools/handlers/host-group-handler.js +413 -0
  17. package/build/tools/handlers/kms-config-handler.js +321 -0
  18. package/build/tools/handlers/operation-handler.js +254 -0
  19. package/build/tools/handlers/quota-rule-handler.js +411 -0
  20. package/build/tools/handlers/replication-handler.js +504 -0
  21. package/build/tools/handlers/snapshot-handler.js +320 -0
  22. package/build/tools/handlers/storage-pool-handler.js +534 -0
  23. package/build/tools/handlers/volume-handler.js +562 -0
  24. package/build/tools/host-group-tools.js +134 -0
  25. package/build/tools/kms-config-tools.js +156 -0
  26. package/build/tools/operation-tools.js +64 -0
  27. package/build/tools/quota-rule-tools.js +166 -0
  28. package/build/tools/replication-tools.js +227 -0
  29. package/build/tools/snapshot-tools.js +124 -0
  30. package/build/tools/storage-pool-tools.js +271 -0
  31. package/build/tools/volume-tools.js +479 -0
  32. package/build/types/tool.js +1 -0
  33. package/build/utils/netapp-client-factory.js +64 -0
  34. package/gemini-extension.json +12 -0
  35. package/package.json +73 -0
@@ -0,0 +1,320 @@
1
+ import { NetAppClientFactory } from '../../utils/netapp-client-factory.js';
2
+ import { logger } from '../../logger.js';
3
+ const log = logger.child({ module: 'snapshot-handler' });
4
+ // Helper to format snapshot data for responses
5
+ function formatSnapshotData(snapshot) {
6
+ const result = {};
7
+ if (!snapshot)
8
+ return result;
9
+ if (snapshot.name) {
10
+ // Extract snapshotId from name (last part after last slash)
11
+ const nameParts = snapshot.name.split('/');
12
+ result.name = snapshot.name;
13
+ result.snapshotId = nameParts[nameParts.length - 1];
14
+ // Extract volumeId from name
15
+ const volumeMatch = snapshot.name.match(/\/volumes\/([^/]+)\/snapshots\//);
16
+ if (volumeMatch && volumeMatch[1]) {
17
+ result.volumeId = volumeMatch[1];
18
+ }
19
+ }
20
+ // Copy basic properties
21
+ if (snapshot.state)
22
+ result.state = snapshot.state;
23
+ // Format timestamps if they exist
24
+ if (snapshot.createTime) {
25
+ result.createTime = new Date(snapshot.createTime.seconds * 1000);
26
+ }
27
+ // Copy optional properties
28
+ if (snapshot.description)
29
+ result.description = snapshot.description;
30
+ if (snapshot.labels)
31
+ result.labels = snapshot.labels;
32
+ return result;
33
+ }
34
+ // Create Snapshot Handler
35
+ export const createSnapshotHandler = async (args) => {
36
+ try {
37
+ const { projectId, location, volumeId, snapshotId, description, labels } = args;
38
+ // Create a new NetApp client using the factory
39
+ const netAppClient = NetAppClientFactory.createClient();
40
+ // Format the parent path for the snapshot
41
+ const parent = `projects/${projectId}/locations/${location}/volumes/${volumeId}`;
42
+ // Create the snapshot request
43
+ const request = {
44
+ parent,
45
+ snapshotId,
46
+ snapshot: {
47
+ description,
48
+ labels,
49
+ },
50
+ };
51
+ log.info({ request }, 'Create Snapshot request');
52
+ // Call the API to create a snapshot
53
+ const [operation] = await netAppClient.createSnapshot(request);
54
+ log.info({ operation }, 'Create Snapshot operation');
55
+ return {
56
+ content: [
57
+ {
58
+ type: 'text',
59
+ text: JSON.stringify({
60
+ name: `projects/${projectId}/locations/${location}/volumes/${volumeId}/snapshots/${snapshotId}`,
61
+ operation: operation,
62
+ }, null, 2),
63
+ },
64
+ ],
65
+ structuredContent: {
66
+ name: `projects/${projectId}/locations/${location}/volumes/${volumeId}/snapshots/${snapshotId}`,
67
+ operationId: operation.name || '',
68
+ },
69
+ };
70
+ }
71
+ catch (error) {
72
+ log.error({ err: error }, 'Error creating snapshot');
73
+ return {
74
+ isError: true,
75
+ content: [
76
+ {
77
+ type: 'text',
78
+ text: `Error creating snapshot: ${error.message || 'Unknown error'}`,
79
+ },
80
+ ],
81
+ };
82
+ }
83
+ };
84
+ // Delete Snapshot Handler
85
+ export const deleteSnapshotHandler = async (args) => {
86
+ try {
87
+ const { projectId, location, volumeId, snapshotId } = args;
88
+ // Create a new NetApp client using the factory
89
+ const netAppClient = NetAppClientFactory.createClient();
90
+ // Format the name for the snapshot
91
+ const name = `projects/${projectId}/locations/${location}/volumes/${volumeId}/snapshots/${snapshotId}`;
92
+ // Call the API to delete the snapshot
93
+ const request = { name };
94
+ log.info({ request }, 'Delete Snapshot request');
95
+ const [operation] = await netAppClient.deleteSnapshot(request);
96
+ log.info({ operation }, 'Delete Snapshot operation');
97
+ return {
98
+ content: [
99
+ {
100
+ type: 'text',
101
+ text: `Snapshot '${snapshotId}' deletion operation started.`,
102
+ },
103
+ ],
104
+ structuredContent: {
105
+ success: true,
106
+ operationId: operation.name || '',
107
+ },
108
+ };
109
+ }
110
+ catch (error) {
111
+ log.error({ err: error }, 'Error deleting snapshot');
112
+ return {
113
+ isError: true,
114
+ content: [
115
+ {
116
+ type: 'text',
117
+ text: `Error deleting snapshot: ${error.message || 'Unknown error'}`,
118
+ },
119
+ ],
120
+ structuredContent: {
121
+ success: false,
122
+ },
123
+ };
124
+ }
125
+ };
126
+ // Get Snapshot Handler
127
+ export const getSnapshotHandler = async (args) => {
128
+ try {
129
+ const { projectId, location, volumeId, snapshotId } = args;
130
+ // Create a new NetApp client using the factory
131
+ const netAppClient = NetAppClientFactory.createClient();
132
+ // Format the name for the snapshot
133
+ const name = `projects/${projectId}/locations/${location}/volumes/${volumeId}/snapshots/${snapshotId}`;
134
+ // Call the API to get the snapshot
135
+ log.info({ name }, 'Get Snapshot request');
136
+ const [snapshot] = await netAppClient.getSnapshot({ name });
137
+ log.info({ snapshot }, 'Get Snapshot response');
138
+ // Format the snapshot data
139
+ const formattedSnapshot = formatSnapshotData(snapshot);
140
+ return {
141
+ content: [
142
+ {
143
+ type: 'text',
144
+ text: JSON.stringify(formattedSnapshot, null, 2),
145
+ },
146
+ ],
147
+ structuredContent: formattedSnapshot,
148
+ };
149
+ }
150
+ catch (error) {
151
+ log.error({ err: error }, 'Error getting snapshot');
152
+ return {
153
+ isError: true,
154
+ content: [
155
+ {
156
+ type: 'text',
157
+ text: `Error getting snapshot: ${error.message || 'Unknown error'}`,
158
+ },
159
+ ],
160
+ };
161
+ }
162
+ };
163
+ // List Snapshots Handler
164
+ export const listSnapshotsHandler = async (args) => {
165
+ try {
166
+ const { projectId, location, volumeId, filter, pageSize, pageToken } = args;
167
+ // Create a new NetApp client using the factory
168
+ const netAppClient = NetAppClientFactory.createClient();
169
+ // Format the parent path
170
+ const parent = `projects/${projectId}/locations/${location}/volumes/${volumeId}`;
171
+ // Create the request object
172
+ const request = { parent };
173
+ if (filter)
174
+ request.filter = filter;
175
+ if (pageSize)
176
+ request.pageSize = pageSize;
177
+ if (pageToken)
178
+ request.pageToken = pageToken;
179
+ // Call the API to list snapshots
180
+ log.info({ request }, 'List Snapshots request');
181
+ const [snapshots, , nextPageToken] = await netAppClient.listSnapshots(request);
182
+ log.info({ snapshots, nextPageToken }, 'List Snapshots response');
183
+ const formattedSnapshots = snapshots.map(formatSnapshotData);
184
+ return {
185
+ content: [
186
+ {
187
+ type: 'text',
188
+ text: JSON.stringify({
189
+ snapshots: snapshots,
190
+ nextPageToken: nextPageToken || '',
191
+ }, null, 2),
192
+ },
193
+ ],
194
+ structuredContent: {
195
+ snapshots: formattedSnapshots,
196
+ nextPageToken: nextPageToken || '',
197
+ },
198
+ };
199
+ }
200
+ catch (error) {
201
+ log.error({ err: error }, 'Error listing snapshots');
202
+ return {
203
+ isError: true,
204
+ content: [
205
+ {
206
+ type: 'text',
207
+ text: `Error listing snapshots: ${error.message || 'Unknown error'}`,
208
+ },
209
+ ],
210
+ structuredContent: {
211
+ snapshots: [],
212
+ nextPageToken: '',
213
+ },
214
+ };
215
+ }
216
+ };
217
+ // Revert Volume to Snapshot Handler
218
+ export const revertVolumeToSnapshotHandler = async (args) => {
219
+ try {
220
+ const { projectId, location, volumeId, snapshotId } = args;
221
+ // Create a new NetApp client using the factory
222
+ const netAppClient = NetAppClientFactory.createClient();
223
+ // Format the name for the snapshot
224
+ const snapshot = `projects/${projectId}/locations/${location}/volumes/${volumeId}/snapshots/${snapshotId}`;
225
+ const volume = `projects/${projectId}/locations/${location}/volumes/${volumeId}`;
226
+ // Call the API to revert to snapshot
227
+ const request = {
228
+ name: volume,
229
+ snapshot,
230
+ };
231
+ log.info({ request }, 'Revert to Snapshot request');
232
+ const [operation] = await netAppClient.revertVolume(request);
233
+ log.info({ operation }, 'Revert to Snapshot operation');
234
+ return {
235
+ content: [
236
+ {
237
+ type: 'text',
238
+ text: `Volume '${volumeId}' revert to snapshot '${snapshotId}' operation started.`,
239
+ },
240
+ ],
241
+ structuredContent: {
242
+ success: true,
243
+ operationId: operation.name || '',
244
+ },
245
+ };
246
+ }
247
+ catch (error) {
248
+ log.error({ err: error }, 'Error reverting to snapshot');
249
+ return {
250
+ isError: true,
251
+ content: [
252
+ {
253
+ type: 'text',
254
+ text: `Error reverting to snapshot: ${error.message || 'Unknown error'}`,
255
+ },
256
+ ],
257
+ structuredContent: {
258
+ success: false,
259
+ },
260
+ };
261
+ }
262
+ };
263
+ // Update Snapshot Handler
264
+ export const updateSnapshotHandler = async (args) => {
265
+ try {
266
+ const { projectId, location, volumeId, snapshotId, description, labels } = args;
267
+ // Create a new NetApp client using the factory
268
+ const netAppClient = NetAppClientFactory.createClient();
269
+ // Format the name for the snapshot
270
+ const name = `projects/${projectId}/locations/${location}/volumes/${volumeId}/snapshots/${snapshotId}`;
271
+ // Prepare the update mask based on provided fields
272
+ const updateMask = [];
273
+ const snapshot = { name };
274
+ if (description !== undefined) {
275
+ snapshot.description = description;
276
+ updateMask.push('description');
277
+ }
278
+ if (labels !== undefined) {
279
+ snapshot.labels = labels;
280
+ updateMask.push('labels');
281
+ }
282
+ // Call the API to update the snapshot
283
+ const request = {
284
+ snapshot,
285
+ updateMask: {
286
+ paths: updateMask,
287
+ },
288
+ };
289
+ log.info({ request }, 'Update Snapshot request');
290
+ const [operation] = await netAppClient.updateSnapshot(request);
291
+ log.info({ operation }, 'Update Snapshot operation');
292
+ return {
293
+ content: [
294
+ {
295
+ type: 'text',
296
+ text: JSON.stringify({
297
+ message: `Snapshot '${snapshotId}' update operation started`,
298
+ operation: operation,
299
+ }, null, 2),
300
+ },
301
+ ],
302
+ structuredContent: {
303
+ name: name,
304
+ operationId: operation.name || '',
305
+ },
306
+ };
307
+ }
308
+ catch (error) {
309
+ log.error({ err: error }, 'Error updating snapshot');
310
+ return {
311
+ isError: true,
312
+ content: [
313
+ {
314
+ type: 'text',
315
+ text: `Error updating snapshot: ${error.message || 'Unknown error'}`,
316
+ },
317
+ ],
318
+ };
319
+ }
320
+ };