Skip to content

Commit

Permalink
feat: add database and roles to project creation, and minor updates (#…
Browse files Browse the repository at this point in the history
…191)

- Update the api version
- Add database and roles to project creation
  • Loading branch information
duskpoet committed Mar 29, 2024
1 parent 43e8f6f commit 7b5f8f6
Show file tree
Hide file tree
Showing 12 changed files with 98 additions and 39 deletions.
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"typescript": "^4.7.4"
},
"dependencies": {
"@neondatabase/api-client": "1.4.1",
"@neondatabase/api-client": "1.5.0",
"@segment/analytics-node": "^1.0.0-beta.26",
"axios": "^1.4.0",
"axios-debug-log": "^1.0.0",
Expand Down
10 changes: 10 additions & 0 deletions snapshots/commands/projects.test.snap
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ connection_uris:
"
`;

exports[`projects create with database and role test 1`] = `
"project:
id: new-project-123456
name: test_project
created_at: 2021-01-01T00:00:00.000Z
connection_uris:
- connection_uri: postgres://localhost:5432/test_project
"
`;

exports[`projects delete test 1`] = `
"id: test
name: test
Expand Down
34 changes: 14 additions & 20 deletions src/commands/branches.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,19 +372,17 @@ const reset = async (
}
const branchId = await branchIdFromProps(props);
const {
data: { branch },
data: {
branch: { parent_id },
},
} = await props.apiClient.getProjectBranch(props.projectId, branchId);
if (!branch.parent_id) {
if (!parent_id) {
throw new Error('Branch has no parent');
}
const { data } = await retryOnLock(() =>
props.apiClient.request({
method: 'POST',
path: `/projects/${props.projectId}/branches/${branch.id}/reset`,
body: {
source_branch_id: branch.parent_id,
preserve_under_name: props.preserveUnderName || undefined,
},
props.apiClient.restoreProjectBranch(props.projectId, branchId, {
source_branch_id: parent_id,
preserve_under_name: props.preserveUnderName || undefined,
}),
);

Expand Down Expand Up @@ -423,17 +421,13 @@ const restore = async (
);

const { data } = await retryOnLock(() =>
props.apiClient.request({
method: 'POST',
path: `/projects/${props.projectId}/branches/${targetBranchId}/reset`,
body: {
source_branch_id: pointInTime.branchId,
preserve_under_name: props.preserveUnderName || undefined,
...(pointInTime.tag === 'lsn' && { source_lsn: pointInTime.lsn }),
...(pointInTime.tag === 'timestamp' && {
source_timestamp: pointInTime.timestamp,
}),
},
props.apiClient.restoreProjectBranch(props.projectId, targetBranchId, {
source_branch_id: pointInTime.branchId,
preserve_under_name: props.preserveUnderName || undefined,
...(pointInTime.tag === 'lsn' && { source_lsn: pointInTime.lsn }),
...(pointInTime.tag === 'timestamp' && {
source_timestamp: pointInTime.timestamp,
}),
}),
);

Expand Down
2 changes: 1 addition & 1 deletion src/commands/ip_allow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ const remove = async (props: ProjectScopeProps & { ips: string[] }) => {
project.settings = {
allowed_ips: {
ips:
existingAllowedIps?.ips.filter((ip) => !props.ips.includes(ip)) ?? [],
existingAllowedIps?.ips?.filter((ip) => !props.ips.includes(ip)) ?? [],
primary_branch_only: existingAllowedIps?.primary_branch_only ?? false,
},
};
Expand Down
17 changes: 17 additions & 0 deletions src/commands/projects.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,23 @@ describe('projects', () => {
},
});

testCliCommand({
name: 'create with database and role',
args: [
'projects',
'create',
'--name',
'test_project',
'--database',
'test_db',
'--role',
'test_role',
],
expected: {
snapshot: true,
},
});

testCliCommand({
name: 'create and connect with psql',
args: ['projects', 'create', '--name', 'test_project', '--psql'],
Expand Down
20 changes: 19 additions & 1 deletion src/commands/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ const REGIONS = [
'aws-eu-central-1',
'aws-us-east-2',
'aws-us-east-1',
'aws-il-central-1',
];

const PROJECTS_LIST_LIMIT = 100;
Expand Down Expand Up @@ -60,6 +59,16 @@ export const builder = (argv: yargs.Argv) => {
describe: 'Connect to a new project via psql',
default: false,
},
database: {
describe:
projectCreateRequest['project.branch.database_name'].description,
type: 'string',
},
role: {
describe:
projectCreateRequest['project.branch.role_name'].description,
type: 'string',
},
'set-context': {
type: 'boolean',
describe: 'Set the current context to the new project',
Expand Down Expand Up @@ -144,6 +153,8 @@ const create = async (
props: CommonProps & {
name?: string;
regionId?: string;
database?: string;
role?: string;
psql: boolean;
setContext: boolean;
'--'?: string[];
Expand All @@ -156,6 +167,13 @@ const create = async (
if (props.regionId) {
project.region_id = props.regionId;
}
project.branch = {};
if (props.database) {
project.branch.database_name = props.database;
}
if (props.role) {
project.branch.role_name = props.role;
}
const { data } = await props.apiClient.createProject({
project,
});
Expand Down
38 changes: 29 additions & 9 deletions src/parameters.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,18 @@ export const projectCreateRequest = {
'project.settings.allowed_ips.ips': {
type: "array",
description: "A list of IP addresses that are allowed to connect to the endpoint.",
demandOption: true,
demandOption: false,
},
'project.settings.allowed_ips.primary_branch_only': {
type: "boolean",
description: "If true, the list will be applied only to the primary branch.",
demandOption: true,
},
'project.settings.enable_logical_replication': {
type: "boolean",
description: "Sets wal_level=logical for all compute endpoints in this project.\nAll active endpoints will be suspended.\nOnce enabled, logical replication cannot be disabled.\n",
demandOption: false,
},
'project.name': {
type: "string",
description: "The project name",
Expand Down Expand Up @@ -69,12 +74,12 @@ export const projectCreateRequest = {
},
'project.default_endpoint_settings.suspend_timeout_seconds': {
type: "number",
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
demandOption: false,
},
'project.pg_version': {
type: "number",
description: "The major PostgreSQL version number. Currently supported versions are `14`, `15` and `16`.",
description: "The major Postgres version number. Currently supported versions are `14`, `15`, and `16`.",
demandOption: false,
},
'project.store_passwords': {
Expand Down Expand Up @@ -118,21 +123,26 @@ export const projectUpdateRequest = {
'project.settings.allowed_ips.ips': {
type: "array",
description: "A list of IP addresses that are allowed to connect to the endpoint.",
demandOption: true,
demandOption: false,
},
'project.settings.allowed_ips.primary_branch_only': {
type: "boolean",
description: "If true, the list will be applied only to the primary branch.",
demandOption: true,
},
'project.settings.enable_logical_replication': {
type: "boolean",
description: "Sets wal_level=logical for all compute endpoints in this project.\nAll active endpoints will be suspended.\nOnce enabled, logical replication cannot be disabled.\n",
demandOption: false,
},
'project.name': {
type: "string",
description: "The project name",
demandOption: false,
},
'project.default_endpoint_settings.suspend_timeout_seconds': {
type: "number",
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
demandOption: false,
},
'project.history_retention_seconds': {
Expand Down Expand Up @@ -165,7 +175,12 @@ export const branchCreateRequest = {
},
'branch.parent_timestamp': {
type: "string",
description: "A timestamp identifying a point in time on the parent branch. The branch will be created with data starting from this point in time.\n",
description: "A timestamp identifying a point in time on the parent branch. The branch will be created with data starting from this point in time.\nThe timestamp must be provided in ISO 8601 format; for example: `2024-02-26T12:00:00Z`.\n",
demandOption: false,
},
'branch.protected': {
type: "boolean",
description: "Whether the branch is protected\n",
demandOption: false,
},
} as const;
Expand All @@ -185,7 +200,7 @@ export const branchCreateRequestEndpointOptions = {
},
'suspend_timeout_seconds': {
type: "number",
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
demandOption: false,
},
} as const;
Expand All @@ -196,6 +211,11 @@ export const branchUpdateRequest = {
description: undefined,
demandOption: false,
},
'branch.protected': {
type: "boolean",
description: undefined,
demandOption: false,
},
} as const;

export const endpointCreateRequest = {
Expand Down Expand Up @@ -244,7 +264,7 @@ export const endpointCreateRequest = {
},
'endpoint.suspend_timeout_seconds': {
type: "number",
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
demandOption: false,
},
} as const;
Expand Down Expand Up @@ -284,7 +304,7 @@ export const endpointUpdateRequest = {
},
'endpoint.suspend_timeout_seconds': {
type: "number",
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
description: "Duration of inactivity in seconds after which the compute endpoint is\nautomatically suspended. The value `0` means use the global default.\nThe value `-1` means never suspend. The default value is `300` seconds (5 minutes).\nThe minimum value is `60` seconds (1 minute).\nThe maximum value is `604800` seconds (1 week). For more information, see\n[Auto-suspend configuration](https://neon.tech/docs/manage/endpoints#auto-suspend-configuration).\n",
demandOption: false,
},
} as const;
Expand Down

0 comments on commit 7b5f8f6

Please sign in to comment.