Skip to content

Commit 583fb08

Browse files
committed
add admin skills
1 parent 6137746 commit 583fb08

13 files changed

Lines changed: 1283 additions & 0 deletions
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
---
2+
name: cloudsql-postgres-admin
3+
description: skill for performing administrative operations on cloudsql postgres
4+
---
5+
6+
## Usage
7+
8+
All scripts can be executed using Node.js. Replace `<param_name>` and `<param_value>` with actual values.
9+
10+
**Bash:**
11+
`node <skill_dir>/scripts/<script_name>.js '{"<param_name>": "<param_value>"}'`
12+
13+
**PowerShell:**
14+
`node <skill_dir>/scripts/<script_name>.js '{\"<param_name>\": \"<param_value>\"}'`
15+
16+
## Scripts
17+
18+
19+
### clone_instance
20+
21+
Clone an existing Cloud SQL instance into a new instance. The clone can be a direct copy of the source instance, or a point-in-time-recovery (PITR) clone from a specific timestamp. The call returns a Cloud SQL Operation object. Call wait_for_operation tool after this, make sure to use multiplier as 4 to poll the opertation status till it is marked DONE.
22+
23+
#### Parameters
24+
25+
| Name | Type | Description | Required | Default |
26+
| :--- | :--- | :--- | :--- | :--- |
27+
| project | string | The project ID | Yes | |
28+
| sourceInstanceName | string | The name of the instance to be cloned. | Yes | |
29+
| destinationInstanceName | string | The name of the new instance that will be created by cloning the source instance. | Yes | |
30+
| pointInTime | string | The timestamp in RFC 3339 format to which the source instance should be cloned. | No | |
31+
| preferredZone | string | The preferred zone for the new instance. | No | |
32+
| preferredSecondaryZone | string | The preferred secondary zone for the new instance. | No | |
33+
34+
35+
---
36+
37+
### create_backup
38+
39+
Creates a backup on a Cloud SQL instance.
40+
41+
#### Parameters
42+
43+
| Name | Type | Description | Required | Default |
44+
| :--- | :--- | :--- | :--- | :--- |
45+
| project | string | The project ID | Yes | |
46+
| instance | string | Cloud SQL instance ID. This does not include the project ID. | Yes | |
47+
| location | string | Location of the backup run. | No | |
48+
| backup_description | string | The description of this backup run. | No | |
49+
50+
51+
---
52+
53+
### create_database
54+
55+
56+
57+
#### Parameters
58+
59+
| Name | Type | Description | Required | Default |
60+
| :--- | :--- | :--- | :--- | :--- |
61+
| project | string | The project ID | Yes | |
62+
| instance | string | The ID of the instance where the database will be created. | Yes | |
63+
| name | string | The name for the new database. Must be unique within the instance. | Yes | |
64+
65+
66+
---
67+
68+
### create_instance
69+
70+
71+
72+
#### Parameters
73+
74+
| Name | Type | Description | Required | Default |
75+
| :--- | :--- | :--- | :--- | :--- |
76+
| project | string | The project ID | Yes | |
77+
| name | string | The name of the instance | Yes | |
78+
| databaseVersion | string | The database version for Postgres. If not specified, defaults to the latest available version (e.g., POSTGRES_17). | No | `POSTGRES_17` |
79+
| rootPassword | string | The root password for the instance | Yes | |
80+
| editionPreset | string | The edition of the instance. Can be `Production` or `Development`. This determines the default machine type and availability. Defaults to `Development`. | No | `Development` |
81+
82+
83+
---
84+
85+
### create_user
86+
87+
88+
89+
#### Parameters
90+
91+
| Name | Type | Description | Required | Default |
92+
| :--- | :--- | :--- | :--- | :--- |
93+
| project | string | The project ID | Yes | |
94+
| instance | string | The ID of the instance where the user will be created. | Yes | |
95+
| name | string | The name for the new user. Must be unique within the instance. | Yes | |
96+
| password | string | A secure password for the new user. Not required for IAM users. | No | |
97+
| iamUser | boolean | Set to true to create a Cloud IAM user. | Yes | |
98+
99+
100+
---
101+
102+
### get_instance
103+
104+
105+
106+
#### Parameters
107+
108+
| Name | Type | Description | Required | Default |
109+
| :--- | :--- | :--- | :--- | :--- |
110+
| projectId | string | The project ID | Yes | |
111+
| instanceId | string | The instance ID | Yes | |
112+
113+
114+
---
115+
116+
### list_databases
117+
118+
Lists all databases for a Cloud SQL instance.
119+
120+
#### Parameters
121+
122+
| Name | Type | Description | Required | Default |
123+
| :--- | :--- | :--- | :--- | :--- |
124+
| project | string | The project ID | Yes | |
125+
| instance | string | The instance ID | Yes | |
126+
127+
128+
---
129+
130+
### list_instances
131+
132+
Lists all type of Cloud SQL instances for a project.
133+
134+
#### Parameters
135+
136+
| Name | Type | Description | Required | Default |
137+
| :--- | :--- | :--- | :--- | :--- |
138+
| project | string | The project ID | Yes | |
139+
140+
141+
---
142+
143+
### postgres_upgrade_precheck
144+
145+
Analyzes a Cloud SQL PostgreSQL instance for major version upgrade readiness. Results are provided to guide customer actions:
146+
ERROR: Action Required. These are critical issues blocking the upgrade. Customers must resolve these using the provided actions_required steps before attempting the upgrade.
147+
WARNING: Review Recommended. These are potential issues. Customers should review the message and actions_required. While not blocking, addressing these is advised to prevent future problems or unexpected behavior post-upgrade.
148+
INFO: No Action Needed. Informational messages only. This pre-check helps customers proactively fix problems, preventing upgrade failures and ensuring a smoother transition.
149+
150+
#### Parameters
151+
152+
| Name | Type | Description | Required | Default |
153+
| :--- | :--- | :--- | :--- | :--- |
154+
| project | string | The project ID | Yes | |
155+
| instance | string | The name of the instance to check | Yes | |
156+
| targetDatabaseVersion | string | The target PostgreSQL version for the upgrade (e.g., POSTGRES_18). If not specified, defaults to the PostgreSQL 18. | No | `POSTGRES_18` |
157+
158+
159+
---
160+
161+
### restore_backup
162+
163+
Restores a backup on a Cloud SQL instance.
164+
165+
#### Parameters
166+
167+
| Name | Type | Description | Required | Default |
168+
| :--- | :--- | :--- | :--- | :--- |
169+
| target_project | string | The project ID | Yes | |
170+
| target_instance | string | Cloud SQL instance ID of the target instance. This does not include the project ID. | Yes | |
171+
| backup_id | string | Identifier of the backup being restored. Can be a BackupRun ID, backup name, or BackupDR backup name. Use the full backup ID as provided, do not try to parse it | Yes | |
172+
| source_project | string | GCP project ID of the instance that the backup belongs to. Only required if the backup_id is a BackupRun ID. | No | |
173+
| source_instance | string | Cloud SQL instance ID of the instance that the backup belongs to. Only required if the backup_id is a BackupRun ID. | No | |
174+
175+
176+
---
177+
178+
### wait_for_operation
179+
180+
181+
182+
#### Parameters
183+
184+
| Name | Type | Description | Required | Default |
185+
| :--- | :--- | :--- | :--- | :--- |
186+
| project | string | The project ID | Yes | |
187+
| operation | string | The operation ID | Yes | |
188+
189+
190+
---
191+
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env node
2+
3+
// Copyright 2025 Google LLC
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
const { spawn, execSync } = require('child_process');
18+
const path = require('path');
19+
const fs = require('fs');
20+
21+
const toolName = "clone_instance";
22+
const configArgs = ["--prebuilt", "cloud-sql-postgres-admin"];
23+
24+
function getToolboxPath() {
25+
if (process.env.GEMINI_CLI === '1') {
26+
const localPath = path.resolve(__dirname, '../../../toolbox');
27+
if (fs.existsSync(localPath)) {
28+
return localPath;
29+
}
30+
}
31+
try {
32+
const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
33+
const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
34+
if (globalPath) {
35+
return globalPath.split('\n')[0].trim();
36+
}
37+
throw new Error("Toolbox binary not found");
38+
} catch (e) {
39+
throw new Error("Toolbox binary not found");
40+
}
41+
}
42+
43+
let toolboxBinary;
44+
try {
45+
toolboxBinary = getToolboxPath();
46+
} catch (err) {
47+
console.error("Error:", err.message);
48+
process.exit(1);
49+
}
50+
51+
function getEnv() {
52+
const envPath = path.resolve(__dirname, '../../../.env');
53+
const env = { ...process.env };
54+
if (fs.existsSync(envPath)) {
55+
const envContent = fs.readFileSync(envPath, 'utf-8');
56+
envContent.split('\n').forEach(line => {
57+
const trimmed = line.trim();
58+
if (trimmed && !trimmed.startsWith('#')) {
59+
const splitIdx = trimmed.indexOf('=');
60+
if (splitIdx !== -1) {
61+
const key = trimmed.slice(0, splitIdx).trim();
62+
let value = trimmed.slice(splitIdx + 1).trim();
63+
value = value.replace(/(^['"]|['"]$)/g, '');
64+
if (env[key] === undefined) {
65+
env[key] = value;
66+
}
67+
}
68+
}
69+
});
70+
}
71+
return env;
72+
}
73+
74+
let env = process.env;
75+
if (process.env.GEMINI_CLI === '1') {
76+
env = getEnv();
77+
}
78+
79+
const args = process.argv.slice(2);
80+
const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
81+
82+
const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
83+
84+
child.on('close', (code) => {
85+
process.exit(code);
86+
});
87+
88+
child.on('error', (err) => {
89+
console.error("Error executing toolbox:", err);
90+
process.exit(1);
91+
});
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env node
2+
3+
// Copyright 2025 Google LLC
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
const { spawn, execSync } = require('child_process');
18+
const path = require('path');
19+
const fs = require('fs');
20+
21+
const toolName = "create_backup";
22+
const configArgs = ["--prebuilt", "cloud-sql-postgres-admin"];
23+
24+
function getToolboxPath() {
25+
if (process.env.GEMINI_CLI === '1') {
26+
const localPath = path.resolve(__dirname, '../../../toolbox');
27+
if (fs.existsSync(localPath)) {
28+
return localPath;
29+
}
30+
}
31+
try {
32+
const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
33+
const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
34+
if (globalPath) {
35+
return globalPath.split('\n')[0].trim();
36+
}
37+
throw new Error("Toolbox binary not found");
38+
} catch (e) {
39+
throw new Error("Toolbox binary not found");
40+
}
41+
}
42+
43+
let toolboxBinary;
44+
try {
45+
toolboxBinary = getToolboxPath();
46+
} catch (err) {
47+
console.error("Error:", err.message);
48+
process.exit(1);
49+
}
50+
51+
function getEnv() {
52+
const envPath = path.resolve(__dirname, '../../../.env');
53+
const env = { ...process.env };
54+
if (fs.existsSync(envPath)) {
55+
const envContent = fs.readFileSync(envPath, 'utf-8');
56+
envContent.split('\n').forEach(line => {
57+
const trimmed = line.trim();
58+
if (trimmed && !trimmed.startsWith('#')) {
59+
const splitIdx = trimmed.indexOf('=');
60+
if (splitIdx !== -1) {
61+
const key = trimmed.slice(0, splitIdx).trim();
62+
let value = trimmed.slice(splitIdx + 1).trim();
63+
value = value.replace(/(^['"]|['"]$)/g, '');
64+
if (env[key] === undefined) {
65+
env[key] = value;
66+
}
67+
}
68+
}
69+
});
70+
}
71+
return env;
72+
}
73+
74+
let env = process.env;
75+
if (process.env.GEMINI_CLI === '1') {
76+
env = getEnv();
77+
}
78+
79+
const args = process.argv.slice(2);
80+
const toolboxArgs = ["--log-level", "error", ...configArgs, "invoke", toolName, ...args];
81+
82+
const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit', env });
83+
84+
child.on('close', (code) => {
85+
process.exit(code);
86+
});
87+
88+
child.on('error', (err) => {
89+
console.error("Error executing toolbox:", err);
90+
process.exit(1);
91+
});

0 commit comments

Comments
 (0)