@gcnv/gcnv-mcp-server 1.0.3
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.
- package/GEMINI.md +200 -0
- package/LICENSE +201 -0
- package/README.md +374 -0
- package/build/index.js +185 -0
- package/build/logger.js +19 -0
- package/build/registry/register-tools.js +101 -0
- package/build/registry/tool-registry.js +27 -0
- package/build/tools/active-directory-tools.js +124 -0
- package/build/tools/backup-policy-tools.js +140 -0
- package/build/tools/backup-tools.js +178 -0
- package/build/tools/backup-vault-tools.js +147 -0
- package/build/tools/handlers/active-directory-handler.js +321 -0
- package/build/tools/handlers/backup-handler.js +451 -0
- package/build/tools/handlers/backup-policy-handler.js +275 -0
- package/build/tools/handlers/backup-vault-handler.js +370 -0
- package/build/tools/handlers/kms-config-handler.js +327 -0
- package/build/tools/handlers/operation-handler.js +254 -0
- package/build/tools/handlers/quota-rule-handler.js +411 -0
- package/build/tools/handlers/replication-handler.js +504 -0
- package/build/tools/handlers/snapshot-handler.js +320 -0
- package/build/tools/handlers/storage-pool-handler.js +346 -0
- package/build/tools/handlers/volume-handler.js +353 -0
- package/build/tools/kms-config-tools.js +162 -0
- package/build/tools/operation-tools.js +64 -0
- package/build/tools/quota-rule-tools.js +166 -0
- package/build/tools/replication-tools.js +227 -0
- package/build/tools/snapshot-tools.js +124 -0
- package/build/tools/storage-pool-tools.js +215 -0
- package/build/tools/volume-tools.js +216 -0
- package/build/types/tool.js +1 -0
- package/build/utils/netapp-client-factory.js +53 -0
- package/gemini-extension.json +12 -0
- package/package.json +66 -0
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
import { NetAppClientFactory } from '../../utils/netapp-client-factory.js';
|
|
2
|
+
import { protos } from '@google-cloud/netapp';
|
|
3
|
+
import { logger } from '../../logger.js';
|
|
4
|
+
const log = logger.child({ module: 'replication-handler' });
|
|
5
|
+
// Helper to format replication data for responses
|
|
6
|
+
function formatReplicationData(replication) {
|
|
7
|
+
const result = {};
|
|
8
|
+
if (!replication)
|
|
9
|
+
return result;
|
|
10
|
+
if (replication.name) {
|
|
11
|
+
// Extract replicationId from name (last part after last slash)
|
|
12
|
+
const nameParts = replication.name.split('/');
|
|
13
|
+
result.name = replication.name;
|
|
14
|
+
result.replicationId = nameParts[nameParts.length - 1];
|
|
15
|
+
}
|
|
16
|
+
// Copy basic properties
|
|
17
|
+
if (replication.sourceVolume)
|
|
18
|
+
result.sourceVolume = replication.sourceVolume;
|
|
19
|
+
if (replication.destinationVolume)
|
|
20
|
+
result.destinationVolume = replication.destinationVolume;
|
|
21
|
+
if (replication.state)
|
|
22
|
+
result.state = replication.state;
|
|
23
|
+
if (replication.healthy !== undefined)
|
|
24
|
+
result.healthy = replication.healthy;
|
|
25
|
+
// Format timestamps if they exist
|
|
26
|
+
if (replication.createTime) {
|
|
27
|
+
result.createTime = new Date(replication.createTime.seconds * 1000);
|
|
28
|
+
}
|
|
29
|
+
if (replication.lastReplicationTime) {
|
|
30
|
+
result.lastReplicationTime = new Date(replication.lastReplicationTime.seconds * 1000);
|
|
31
|
+
}
|
|
32
|
+
// Copy optional properties
|
|
33
|
+
if (replication.description)
|
|
34
|
+
result.description = replication.description;
|
|
35
|
+
if (replication.labels)
|
|
36
|
+
result.labels = replication.labels;
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
// Create Replication Handler
|
|
40
|
+
export const createReplicationHandler = async (args) => {
|
|
41
|
+
try {
|
|
42
|
+
const { projectId, location, replicationId, sourceVolumeId, destinationStoragePool, replicationSchedule, description, labels, } = args;
|
|
43
|
+
// Create a new NetApp client using the factory
|
|
44
|
+
const netAppClient = NetAppClientFactory.createClient();
|
|
45
|
+
// Format the parent path - for replications, parent is at the location level
|
|
46
|
+
const parent = `projects/${projectId}/locations/${location}/volumes/${sourceVolumeId}`;
|
|
47
|
+
// Format the source and destination volumes
|
|
48
|
+
const sourceVolume = `projects/${projectId}/locations/${location}/volumes/${sourceVolumeId}`;
|
|
49
|
+
const scheduleMap = {
|
|
50
|
+
EVERY_10_MINUTES: protos.google.cloud.netapp.v1.Replication.ReplicationSchedule.EVERY_10_MINUTES,
|
|
51
|
+
HOURLY: protos.google.cloud.netapp.v1.Replication.ReplicationSchedule.HOURLY,
|
|
52
|
+
DAILY: protos.google.cloud.netapp.v1.Replication.ReplicationSchedule.DAILY,
|
|
53
|
+
};
|
|
54
|
+
const scheduleValue = scheduleMap[replicationSchedule] ||
|
|
55
|
+
protos.google.cloud.netapp.v1.Replication.ReplicationSchedule.HOURLY;
|
|
56
|
+
// Create the final request
|
|
57
|
+
const request = {
|
|
58
|
+
parent,
|
|
59
|
+
replicationId,
|
|
60
|
+
replication: {
|
|
61
|
+
name: replicationId,
|
|
62
|
+
destinationVolumeParameters: {
|
|
63
|
+
storagePool: destinationStoragePool,
|
|
64
|
+
},
|
|
65
|
+
sourceVolume,
|
|
66
|
+
replicationSchedule: scheduleValue,
|
|
67
|
+
description: description || '',
|
|
68
|
+
labels: labels || {},
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
// Log the request to help debug
|
|
72
|
+
log.info({ request }, 'Create Replication request');
|
|
73
|
+
// Call the API to create a replication
|
|
74
|
+
const [operation] = await netAppClient.createReplication(request);
|
|
75
|
+
log.info({ operation }, 'Create Replication operation');
|
|
76
|
+
// Make the response more robust by checking operation properties
|
|
77
|
+
const operationName = operation && operation.name ? operation.name : 'Unknown';
|
|
78
|
+
return {
|
|
79
|
+
content: [
|
|
80
|
+
{
|
|
81
|
+
type: 'text',
|
|
82
|
+
text: `Created replication ${replicationId} successfully. Operation: ${operationName}`,
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
structuredContent: {
|
|
86
|
+
name: `projects/${projectId}/locations/${location}/volumes/${sourceVolumeId}/replications/${replicationId}`,
|
|
87
|
+
operationId: operationName,
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
log.error({ err: error }, 'Error creating replication');
|
|
93
|
+
return {
|
|
94
|
+
isError: true,
|
|
95
|
+
content: [
|
|
96
|
+
{
|
|
97
|
+
type: 'text',
|
|
98
|
+
text: `Error creating replication: ${error.message || 'Unknown error'}`,
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
// Delete Replication Handler
|
|
105
|
+
export const deleteReplicationHandler = async (args) => {
|
|
106
|
+
try {
|
|
107
|
+
const { projectId, location, volumeId, replicationId } = args;
|
|
108
|
+
// Create a new NetApp client using the factory
|
|
109
|
+
const netAppClient = NetAppClientFactory.createClient();
|
|
110
|
+
// Format the name for the replication
|
|
111
|
+
const name = `projects/${projectId}/locations/${location}/volumes/${volumeId}/replications/${replicationId}`;
|
|
112
|
+
// Call the API to delete the replication
|
|
113
|
+
const request = { name };
|
|
114
|
+
log.info({ request }, 'Delete Replication request');
|
|
115
|
+
const [operation] = await netAppClient.deleteReplication(request);
|
|
116
|
+
log.info({ operation }, 'Delete Replication operation');
|
|
117
|
+
return {
|
|
118
|
+
content: [
|
|
119
|
+
{
|
|
120
|
+
type: 'text',
|
|
121
|
+
text: JSON.stringify({
|
|
122
|
+
message: `Replication ${replicationId} deletion requested`,
|
|
123
|
+
operation: operation,
|
|
124
|
+
}, null, 2),
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
structuredContent: {
|
|
128
|
+
success: true,
|
|
129
|
+
operationId: operation.name || '',
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
log.error({ err: error }, 'Error deleting replication');
|
|
135
|
+
return {
|
|
136
|
+
isError: true,
|
|
137
|
+
content: [
|
|
138
|
+
{
|
|
139
|
+
type: 'text',
|
|
140
|
+
text: `Error deleting replication: ${error.message || 'Unknown error'}`,
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
structuredContent: {
|
|
144
|
+
success: false,
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
// Get Replication Handler
|
|
150
|
+
export const getReplicationHandler = async (args) => {
|
|
151
|
+
try {
|
|
152
|
+
const { projectId, location, volumeId, replicationId } = args;
|
|
153
|
+
// Create a new NetApp client using the factory
|
|
154
|
+
const netAppClient = NetAppClientFactory.createClient();
|
|
155
|
+
// Format the name for the replication
|
|
156
|
+
const name = `projects/${projectId}/locations/${location}/volumes/${volumeId}/replications/${replicationId}`;
|
|
157
|
+
// Call the API to get the replication
|
|
158
|
+
log.info({ name }, 'Get Replication request');
|
|
159
|
+
const [replication] = await netAppClient.getReplication({ name });
|
|
160
|
+
log.info({ replication }, 'Get Replication response');
|
|
161
|
+
// Format the response
|
|
162
|
+
const formattedReplication = formatReplicationData(replication);
|
|
163
|
+
return {
|
|
164
|
+
content: [
|
|
165
|
+
{
|
|
166
|
+
type: 'text',
|
|
167
|
+
text: JSON.stringify(formattedReplication, null, 2),
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
structuredContent: formattedReplication,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
log.error({ err: error }, 'Error getting replication');
|
|
175
|
+
return {
|
|
176
|
+
isError: true,
|
|
177
|
+
content: [
|
|
178
|
+
{
|
|
179
|
+
type: 'text',
|
|
180
|
+
text: `Error getting replication: ${error.message || 'Unknown error'}`,
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
// List Replications Handler
|
|
187
|
+
export const listReplicationsHandler = async (args) => {
|
|
188
|
+
try {
|
|
189
|
+
const { projectId, location, volumeId, filter, pageSize, pageToken } = args;
|
|
190
|
+
// Create a new NetApp client using the factory
|
|
191
|
+
const netAppClient = NetAppClientFactory.createClient();
|
|
192
|
+
// Format the parent path
|
|
193
|
+
const parent = `projects/${projectId}/locations/${location}/volumes/${volumeId}`;
|
|
194
|
+
// Create the list request
|
|
195
|
+
const request = { parent };
|
|
196
|
+
if (filter)
|
|
197
|
+
request.filter = filter;
|
|
198
|
+
if (pageSize)
|
|
199
|
+
request.pageSize = pageSize;
|
|
200
|
+
if (pageToken)
|
|
201
|
+
request.pageToken = pageToken;
|
|
202
|
+
// Call the API to list replications
|
|
203
|
+
log.info({ request }, 'List Replications request');
|
|
204
|
+
const [replications, , nextPageToken] = await netAppClient.listReplications(request);
|
|
205
|
+
log.info({ replications, nextPageToken }, 'List Replications response');
|
|
206
|
+
const formattedReplications = replications.map(formatReplicationData);
|
|
207
|
+
log.info({ formattedReplications }, 'Formatted replications');
|
|
208
|
+
return {
|
|
209
|
+
content: [
|
|
210
|
+
{
|
|
211
|
+
type: 'text',
|
|
212
|
+
text: JSON.stringify({ replications, nextPageToken }, null, 2),
|
|
213
|
+
},
|
|
214
|
+
],
|
|
215
|
+
structuredContent: {
|
|
216
|
+
replications: formattedReplications || [],
|
|
217
|
+
nextPageToken: nextPageToken || '',
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
log.error({ err: error }, 'Error listing replications');
|
|
223
|
+
return {
|
|
224
|
+
isError: true,
|
|
225
|
+
content: [
|
|
226
|
+
{
|
|
227
|
+
type: 'text',
|
|
228
|
+
text: `Error listing replications: ${error.message || 'Unknown error'}`,
|
|
229
|
+
},
|
|
230
|
+
],
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
// Update Replication Handler
|
|
235
|
+
export const updateReplicationHandler = async (args) => {
|
|
236
|
+
try {
|
|
237
|
+
const { projectId, location, volumeId, replicationId, description, labels } = args;
|
|
238
|
+
// Create a new NetApp client using the factory
|
|
239
|
+
const netAppClient = NetAppClientFactory.createClient();
|
|
240
|
+
// Format the name for the replication
|
|
241
|
+
const name = `projects/${projectId}/locations/${location}/volumes/${volumeId}/replications/${replicationId}`;
|
|
242
|
+
// Create update mask based on provided fields
|
|
243
|
+
const updateMask = [];
|
|
244
|
+
const replication = { name };
|
|
245
|
+
if (description !== undefined) {
|
|
246
|
+
replication.description = description;
|
|
247
|
+
updateMask.push('description');
|
|
248
|
+
}
|
|
249
|
+
if (labels !== undefined) {
|
|
250
|
+
replication.labels = labels;
|
|
251
|
+
updateMask.push('labels');
|
|
252
|
+
}
|
|
253
|
+
// Call the API to update the replication
|
|
254
|
+
const request = { replication, updateMask: { paths: updateMask } };
|
|
255
|
+
log.info({ request }, 'Update Replication request');
|
|
256
|
+
const [operation] = await netAppClient.updateReplication(request);
|
|
257
|
+
log.info({ operation }, 'Update Replication operation');
|
|
258
|
+
return {
|
|
259
|
+
content: [
|
|
260
|
+
{
|
|
261
|
+
type: 'text',
|
|
262
|
+
text: JSON.stringify({
|
|
263
|
+
message: `Replication ${replicationId} update requested`,
|
|
264
|
+
operation: operation,
|
|
265
|
+
}, null, 2),
|
|
266
|
+
},
|
|
267
|
+
],
|
|
268
|
+
structuredContent: {
|
|
269
|
+
name: `projects/${projectId}/locations/${location}/volumes/${volumeId}/replications/${replicationId}`,
|
|
270
|
+
operationId: operation.name || '',
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
log.error({ err: error }, 'Error updating replication');
|
|
276
|
+
return {
|
|
277
|
+
isError: true,
|
|
278
|
+
content: [
|
|
279
|
+
{
|
|
280
|
+
type: 'text',
|
|
281
|
+
text: `Error updating replication: ${error.message || 'Unknown error'}`,
|
|
282
|
+
},
|
|
283
|
+
],
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
// Resume Replication Handler
|
|
288
|
+
export const resumeReplicationHandler = async (args) => {
|
|
289
|
+
try {
|
|
290
|
+
const { projectId, location, volumeId, replicationId } = args;
|
|
291
|
+
// Create a new NetApp client using the factory
|
|
292
|
+
const netAppClient = NetAppClientFactory.createClient();
|
|
293
|
+
// Format the name for the replication
|
|
294
|
+
const name = `projects/${projectId}/locations/${location}/volumes/${volumeId}/replications/${replicationId}`;
|
|
295
|
+
// Call the API to resume the replication
|
|
296
|
+
const request = { name };
|
|
297
|
+
log.info({ request }, 'Resume Replication request');
|
|
298
|
+
const [operation] = await netAppClient.resumeReplication(request);
|
|
299
|
+
log.info({ operation }, 'Resume Replication operation');
|
|
300
|
+
return {
|
|
301
|
+
content: [
|
|
302
|
+
{
|
|
303
|
+
type: 'text',
|
|
304
|
+
text: JSON.stringify({
|
|
305
|
+
message: `Replication ${replicationId} resume requested`,
|
|
306
|
+
operation: operation,
|
|
307
|
+
}, null, 2),
|
|
308
|
+
},
|
|
309
|
+
],
|
|
310
|
+
structuredContent: {
|
|
311
|
+
name: `projects/${projectId}/locations/${location}/volumes/${volumeId}/replications/${replicationId}`,
|
|
312
|
+
operationId: operation.name || '',
|
|
313
|
+
},
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
log.error({ err: error }, 'Error resuming replication');
|
|
318
|
+
return {
|
|
319
|
+
isError: true,
|
|
320
|
+
content: [
|
|
321
|
+
{
|
|
322
|
+
type: 'text',
|
|
323
|
+
text: `Error resuming replication: ${error.message || 'Unknown error'}`,
|
|
324
|
+
},
|
|
325
|
+
],
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
// Stop Replication Handler
|
|
330
|
+
export const stopReplicationHandler = async (args) => {
|
|
331
|
+
try {
|
|
332
|
+
const { projectId, location, volumeId, replicationId } = args;
|
|
333
|
+
// Create a new NetApp client using the factory
|
|
334
|
+
const netAppClient = NetAppClientFactory.createClient();
|
|
335
|
+
// Format the name for the replication
|
|
336
|
+
const name = `projects/${projectId}/locations/${location}/volumes/${volumeId}/replications/${replicationId}`;
|
|
337
|
+
// Call the API to stop the replication
|
|
338
|
+
const request = { name };
|
|
339
|
+
log.info({ request }, 'Stop Replication request');
|
|
340
|
+
const [operation] = await netAppClient.stopReplication(request);
|
|
341
|
+
log.info({ operation }, 'Stop Replication operation');
|
|
342
|
+
return {
|
|
343
|
+
content: [
|
|
344
|
+
{
|
|
345
|
+
type: 'text',
|
|
346
|
+
text: JSON.stringify({
|
|
347
|
+
message: `Replication ${replicationId} stop requested`,
|
|
348
|
+
operation: operation,
|
|
349
|
+
}, null, 2),
|
|
350
|
+
},
|
|
351
|
+
],
|
|
352
|
+
structuredContent: {
|
|
353
|
+
name: `projects/${projectId}/locations/${location}/volumes/${volumeId}/replications/${replicationId}`,
|
|
354
|
+
operationId: operation.name || '',
|
|
355
|
+
},
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
catch (error) {
|
|
359
|
+
log.error({ err: error }, 'Error stopping replication');
|
|
360
|
+
return {
|
|
361
|
+
isError: true,
|
|
362
|
+
content: [
|
|
363
|
+
{
|
|
364
|
+
type: 'text',
|
|
365
|
+
text: `Error stopping replication: ${error.message || 'Unknown error'}`,
|
|
366
|
+
},
|
|
367
|
+
],
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
// Reverse Replication Direction Handler
|
|
372
|
+
export const reverseReplicationDirectionHandler = async (args) => {
|
|
373
|
+
try {
|
|
374
|
+
const { projectId, location, volumeId, replicationId } = args;
|
|
375
|
+
// Create a new NetApp client using the factory
|
|
376
|
+
const netAppClient = NetAppClientFactory.createClient();
|
|
377
|
+
// Format the name for the replication
|
|
378
|
+
const name = `projects/${projectId}/locations/${location}/volumes/${volumeId}/replications/${replicationId}`;
|
|
379
|
+
// Call the API to reverse replication direction
|
|
380
|
+
const request = { name };
|
|
381
|
+
log.info({ request }, 'Reverse Replication direction request');
|
|
382
|
+
const [operation] = await netAppClient.reverseReplicationDirection(request);
|
|
383
|
+
log.info({ operation }, 'Reverse Replication direction operation');
|
|
384
|
+
return {
|
|
385
|
+
content: [
|
|
386
|
+
{
|
|
387
|
+
type: 'text',
|
|
388
|
+
text: JSON.stringify({
|
|
389
|
+
message: `Replication ${replicationId} direction reversal requested`,
|
|
390
|
+
operation: operation,
|
|
391
|
+
}, null, 2),
|
|
392
|
+
},
|
|
393
|
+
],
|
|
394
|
+
structuredContent: {
|
|
395
|
+
name: `projects/${projectId}/locations/${location}/volumes/${volumeId}/replications/${replicationId}`,
|
|
396
|
+
operationId: operation.name || '',
|
|
397
|
+
},
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
catch (error) {
|
|
401
|
+
log.error({ err: error }, 'Error reversing replication direction');
|
|
402
|
+
return {
|
|
403
|
+
isError: true,
|
|
404
|
+
content: [
|
|
405
|
+
{
|
|
406
|
+
type: 'text',
|
|
407
|
+
text: `Error reversing replication direction: ${error.message || 'Unknown error'}`,
|
|
408
|
+
},
|
|
409
|
+
],
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
// Establish Peering Handler
|
|
414
|
+
export const establishPeeringHandler = async (args) => {
|
|
415
|
+
try {
|
|
416
|
+
const { projectId, location, volumeId, replicationId, peerClusterName, peerSvmName, peerVolumeName, peerIpAddresses, } = args;
|
|
417
|
+
// Create a new NetApp client using the factory
|
|
418
|
+
const netAppClient = NetAppClientFactory.createClient();
|
|
419
|
+
// Format the name for the replication
|
|
420
|
+
const name = `projects/${projectId}/locations/${location}/volumes/${volumeId}/replications/${replicationId}`;
|
|
421
|
+
// Call the API to establish peering
|
|
422
|
+
const request = {
|
|
423
|
+
name,
|
|
424
|
+
peerClusterName,
|
|
425
|
+
peerSvmName,
|
|
426
|
+
peerVolumeName,
|
|
427
|
+
};
|
|
428
|
+
if (peerIpAddresses && peerIpAddresses.length > 0) {
|
|
429
|
+
request.peerIpAddresses = peerIpAddresses;
|
|
430
|
+
}
|
|
431
|
+
log.info({ request }, 'Establish Replication Peering request');
|
|
432
|
+
const [operation] = await netAppClient.establishPeering(request);
|
|
433
|
+
log.info({ operation }, 'Establish Replication Peering operation');
|
|
434
|
+
return {
|
|
435
|
+
content: [
|
|
436
|
+
{
|
|
437
|
+
type: 'text',
|
|
438
|
+
text: JSON.stringify({
|
|
439
|
+
message: `Replication peering establishment requested for ${replicationId}`,
|
|
440
|
+
operation: operation,
|
|
441
|
+
}, null, 2),
|
|
442
|
+
},
|
|
443
|
+
],
|
|
444
|
+
structuredContent: {
|
|
445
|
+
name: name,
|
|
446
|
+
operationId: operation.name || '',
|
|
447
|
+
},
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
catch (error) {
|
|
451
|
+
log.error({ err: error }, 'Error establishing peering');
|
|
452
|
+
return {
|
|
453
|
+
isError: true,
|
|
454
|
+
content: [
|
|
455
|
+
{
|
|
456
|
+
type: 'text',
|
|
457
|
+
text: `Error establishing peering: ${error.message || 'Unknown error'}`,
|
|
458
|
+
},
|
|
459
|
+
],
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
};
|
|
463
|
+
// Sync Replication Handler
|
|
464
|
+
export const syncReplicationHandler = async (args) => {
|
|
465
|
+
try {
|
|
466
|
+
const { projectId, location, volumeId, replicationId } = args;
|
|
467
|
+
// Create a new NetApp client using the factory
|
|
468
|
+
const netAppClient = NetAppClientFactory.createClient();
|
|
469
|
+
// Format the name for the replication
|
|
470
|
+
const name = `projects/${projectId}/locations/${location}/volumes/${volumeId}/replications/${replicationId}`;
|
|
471
|
+
// Call the API to sync replication
|
|
472
|
+
const request = { name };
|
|
473
|
+
log.info({ request }, 'Sync Replication request');
|
|
474
|
+
const [operation] = await netAppClient.syncReplication(request);
|
|
475
|
+
log.info({ operation }, 'Sync Replication operation');
|
|
476
|
+
return {
|
|
477
|
+
content: [
|
|
478
|
+
{
|
|
479
|
+
type: 'text',
|
|
480
|
+
text: JSON.stringify({
|
|
481
|
+
message: `Replication sync requested for ${replicationId}`,
|
|
482
|
+
operation: operation,
|
|
483
|
+
}, null, 2),
|
|
484
|
+
},
|
|
485
|
+
],
|
|
486
|
+
structuredContent: {
|
|
487
|
+
name: name,
|
|
488
|
+
operationId: operation.name || '',
|
|
489
|
+
},
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
catch (error) {
|
|
493
|
+
log.error({ err: error }, 'Error syncing replication');
|
|
494
|
+
return {
|
|
495
|
+
isError: true,
|
|
496
|
+
content: [
|
|
497
|
+
{
|
|
498
|
+
type: 'text',
|
|
499
|
+
text: `Error syncing replication: ${error.message || 'Unknown error'}`,
|
|
500
|
+
},
|
|
501
|
+
],
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
};
|