mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-10 15:02:56 +00:00
## Problem The regression test on extensions relied on the admin API to set the default endpoint settings, which is not stable and requires admin privileges. Specifically: - The workflow was using `default_endpoint_settings` to configure necessary PostgreSQL settings like `DateStyle`, `TimeZone`, and `neon.allow_unstable_extensions` - This approach was failing because the API endpoint for setting `default_endpoint_settings` was changed (referenced in a comment as issue #27108) - The admin API requires special privileges. ## Summary of changes We get rid of the admin API dependency and use ALTER DATABASE statements instead: **Removed the default_endpoint_settings mechanism:** - Removed the default_endpoint_settings input parameter from the neon-project-create action - Removed the API call that was attempting to set these settings at the project level - Completely removed the default_endpoint_settings configuration from the cloud-extensions workflow **Added database-level settings:** - Created a new `alter_db.sh` script that applies the same settings directly to each test database - Modified all extension test scripts to call this script after database creation
155 lines
6.6 KiB
YAML
155 lines
6.6 KiB
YAML
name: 'Create Neon Project'
|
|
description: 'Create Neon Project using API'
|
|
|
|
inputs:
|
|
api_key:
|
|
description: 'Neon API key'
|
|
required: true
|
|
region_id:
|
|
description: 'Region ID, if not set the project will be created in the default region'
|
|
default: aws-us-east-2
|
|
postgres_version:
|
|
description: 'Postgres version; default is 16'
|
|
default: '16'
|
|
api_host:
|
|
description: 'Neon API host'
|
|
default: console-stage.neon.build
|
|
compute_units:
|
|
description: '[Min, Max] compute units'
|
|
default: '[1, 1]'
|
|
# settings below only needed if you want the project to be sharded from the beginning
|
|
shard_split_project:
|
|
description: 'by default new projects are not shard-split initiailly, but only when shard-split threshold is reached, specify true to explicitly shard-split initially'
|
|
required: false
|
|
default: 'false'
|
|
disable_sharding:
|
|
description: 'by default new projects use storage controller default policy to shard-split when shard-split threshold is reached, specify true to explicitly disable sharding'
|
|
required: false
|
|
default: 'false'
|
|
admin_api_key:
|
|
description: 'Admin API Key needed for shard-splitting. Must be specified if shard_split_project is true'
|
|
required: false
|
|
shard_count:
|
|
description: 'Number of shards to split the project into, only applies if shard_split_project is true'
|
|
required: false
|
|
default: '8'
|
|
stripe_size:
|
|
description: 'Stripe size, optional, in 8kiB pages. e.g. set 2048 for 16MB stripes. Default is 128 MiB, only applies if shard_split_project is true'
|
|
required: false
|
|
default: '32768'
|
|
psql_path:
|
|
description: 'Path to psql binary - it is caller responsibility to provision the psql binary'
|
|
required: false
|
|
default: '/tmp/neon/pg_install/v16/bin/psql'
|
|
libpq_lib_path:
|
|
description: 'Path to directory containing libpq library - it is caller responsibility to provision the libpq library'
|
|
required: false
|
|
default: '/tmp/neon/pg_install/v16/lib'
|
|
project_settings:
|
|
description: 'A JSON object with project settings'
|
|
required: false
|
|
default: '{}'
|
|
|
|
outputs:
|
|
dsn:
|
|
description: 'Created Project DSN (for main database)'
|
|
value: ${{ steps.create-neon-project.outputs.dsn }}
|
|
project_id:
|
|
description: 'Created Project ID'
|
|
value: ${{ steps.create-neon-project.outputs.project_id }}
|
|
|
|
runs:
|
|
using: "composite"
|
|
steps:
|
|
- name: Create Neon Project
|
|
id: create-neon-project
|
|
# A shell without `set -x` to not to expose password/dsn in logs
|
|
shell: bash -euo pipefail {0}
|
|
run: |
|
|
res=$(curl \
|
|
"https://${API_HOST}/api/v2/projects" \
|
|
-w "%{http_code}" \
|
|
--header "Accept: application/json" \
|
|
--header "Content-Type: application/json" \
|
|
--header "Authorization: Bearer ${API_KEY}" \
|
|
--data "{
|
|
\"project\": {
|
|
\"name\": \"Created by actions/neon-project-create; GITHUB_RUN_ID=${GITHUB_RUN_ID}\",
|
|
\"pg_version\": ${POSTGRES_VERSION},
|
|
\"region_id\": \"${REGION_ID}\",
|
|
\"provisioner\": \"k8s-neonvm\",
|
|
\"autoscaling_limit_min_cu\": ${MIN_CU},
|
|
\"autoscaling_limit_max_cu\": ${MAX_CU},
|
|
\"settings\": ${PROJECT_SETTINGS}
|
|
}
|
|
}")
|
|
|
|
code=${res: -3}
|
|
if [[ ${code} -ge 400 ]]; then
|
|
echo Request failed with error code ${code}
|
|
echo ${res::-3}
|
|
exit 1
|
|
else
|
|
project=${res::-3}
|
|
fi
|
|
|
|
# Mask password
|
|
echo "::add-mask::$(echo $project | jq --raw-output '.roles[] | select(.name != "web_access") | .password')"
|
|
|
|
dsn=$(echo $project | jq --raw-output '.connection_uris[0].connection_uri')
|
|
echo "::add-mask::${dsn}"
|
|
echo "dsn=${dsn}" >> $GITHUB_OUTPUT
|
|
|
|
project_id=$(echo $project | jq --raw-output '.project.id')
|
|
echo "project_id=${project_id}" >> $GITHUB_OUTPUT
|
|
|
|
echo "Project ${project_id} has been created"
|
|
|
|
if [ "${SHARD_SPLIT_PROJECT}" = "true" ]; then
|
|
# determine tenant ID
|
|
TENANT_ID=`${PSQL} ${dsn} -t -A -c "SHOW neon.tenant_id"`
|
|
|
|
echo "Splitting project ${project_id} with tenant_id ${TENANT_ID} into $((SHARD_COUNT)) shards with stripe size $((STRIPE_SIZE))"
|
|
|
|
echo "Sending PUT request to https://${API_HOST}/regions/${REGION_ID}/api/v1/admin/storage/proxy/control/v1/tenant/${TENANT_ID}/shard_split"
|
|
echo "with body {\"new_shard_count\": $((SHARD_COUNT)), \"new_stripe_size\": $((STRIPE_SIZE))}"
|
|
|
|
# we need an ADMIN API KEY to invoke storage controller API for shard splitting (bash -u above checks that the variable is set)
|
|
curl -X PUT \
|
|
"https://${API_HOST}/regions/${REGION_ID}/api/v1/admin/storage/proxy/control/v1/tenant/${TENANT_ID}/shard_split" \
|
|
-H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Bearer ${ADMIN_API_KEY}" \
|
|
-d "{\"new_shard_count\": $SHARD_COUNT, \"new_stripe_size\": $STRIPE_SIZE}"
|
|
fi
|
|
if [ "${DISABLE_SHARDING}" = "true" ]; then
|
|
# determine tenant ID
|
|
TENANT_ID=`${PSQL} ${dsn} -t -A -c "SHOW neon.tenant_id"`
|
|
|
|
echo "Explicitly disabling shard-splitting for project ${project_id} with tenant_id ${TENANT_ID}"
|
|
|
|
echo "Sending PUT request to https://${API_HOST}/regions/${REGION_ID}/api/v1/admin/storage/proxy/control/v1/tenant/${TENANT_ID}/policy"
|
|
echo "with body {\"scheduling\": \"Essential\"}"
|
|
|
|
# we need an ADMIN API KEY to invoke storage controller API for shard splitting (bash -u above checks that the variable is set)
|
|
curl -X PUT \
|
|
"https://${API_HOST}/regions/${REGION_ID}/api/v1/admin/storage/proxy/control/v1/tenant/${TENANT_ID}/policy" \
|
|
-H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Bearer ${ADMIN_API_KEY}" \
|
|
-d "{\"scheduling\": \"Essential\"}"
|
|
fi
|
|
|
|
|
|
env:
|
|
API_HOST: ${{ inputs.api_host }}
|
|
API_KEY: ${{ inputs.api_key }}
|
|
REGION_ID: ${{ inputs.region_id }}
|
|
POSTGRES_VERSION: ${{ inputs.postgres_version }}
|
|
MIN_CU: ${{ fromJSON(inputs.compute_units)[0] }}
|
|
MAX_CU: ${{ fromJSON(inputs.compute_units)[1] }}
|
|
SHARD_SPLIT_PROJECT: ${{ inputs.shard_split_project }}
|
|
DISABLE_SHARDING: ${{ inputs.disable_sharding }}
|
|
ADMIN_API_KEY: ${{ inputs.admin_api_key }}
|
|
SHARD_COUNT: ${{ inputs.shard_count }}
|
|
STRIPE_SIZE: ${{ inputs.stripe_size }}
|
|
PSQL: ${{ inputs.psql_path }}
|
|
LD_LIBRARY_PATH: ${{ inputs.libpq_lib_path }}
|
|
PROJECT_SETTINGS: ${{ inputs.project_settings }}
|