commit
70bffa33fa
15 changed files with 747 additions and 0 deletions
@ -0,0 +1 @@ |
|||||
|
3scale-admin-cli.sh |
||||
@ -0,0 +1,18 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
set -Eeuo pipefail |
||||
|
|
||||
|
if ! oc whoami &>/dev/null; then |
||||
|
echo "Not connected to OpenShift!" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
export THREESCALE_TOKEN="$(oc get secret system-seed -o go-template --template='{{.data.ADMIN_ACCESS_TOKEN|base64decode}}')" |
||||
|
export ADMIN_PORTAL_HOSTNAME="$(oc get route -l zync.3scale.net/route-to=system-provider -o go-template='{{(index .items 0).spec.host}}')" |
||||
|
export OIDC_ISSUER_ENDPOINT="https://zync:changeme@sso-sso.apps.changeme/auth/realms/3scale" |
||||
|
|
||||
|
for f in src/*.sh; do |
||||
|
. "$f" |
||||
|
done |
||||
|
|
||||
|
# TODO |
||||
@ -0,0 +1,3 @@ |
|||||
|
#!/bin/sh |
||||
|
|
||||
|
cat src/*.sh > 3scale-admin-cli.sh |
||||
@ -0,0 +1,146 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
set -Eeuo pipefail |
||||
|
|
||||
|
. 3scale-admin-cli.sh |
||||
|
|
||||
|
if [ -z "${THREESCALE_TOKEN:-}" ]; then |
||||
|
echo "Please set the THREESCALE_TOKEN environment variable!" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
if [ -z "${ADMIN_PORTAL_HOSTNAME:-}" ]; then |
||||
|
echo "Please set the ADMIN_PORTAL_HOSTNAME environment variable!" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
if [ -z "${SERVICE_NAME:-}" ]; then |
||||
|
echo "Please set the SERVICE_NAME environment variable!" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
## |
||||
|
## Service creation |
||||
|
## |
||||
|
declare -A service_def=( ["system_name"]="$SERVICE_NAME" ["name"]="Echo API" ["description"]="Echo API" ["deployment_option"]="hosted" ["backend_version"]="1" ) |
||||
|
apply service present service_def |
||||
|
service_id=$last_object_id |
||||
|
|
||||
|
## |
||||
|
## Backend creation |
||||
|
## |
||||
|
declare -A backend_def=( ["system_name"]="$SERVICE_NAME" ["name"]="Echo API" ["private_endpoint"]="https://echo-api.3scale.net" ) |
||||
|
apply backend present backend_def |
||||
|
backend_id=$last_object_id |
||||
|
|
||||
|
## |
||||
|
## Backend method creation |
||||
|
## |
||||
|
|
||||
|
# Find the "hits" metric so that we can create the methods under it |
||||
|
breadcrumb=( backend_apis $backend_id ) |
||||
|
hits_metric_id="$(metric_list | id_of_external_id_with_prefix "system_name" "hits")" |
||||
|
|
||||
|
# Create one method |
||||
|
breadcrumb=( backend_apis $backend_id metrics $hits_metric_id ) |
||||
|
declare -A method_def=( ["system_name"]="say_hello" ["friendly_name"]="sayHello" ["unit"]="hits" ) |
||||
|
apply method present method_def |
||||
|
method_id=$last_object_id |
||||
|
|
||||
|
# Create one mapping rule |
||||
|
breadcrumb=( backend_apis $backend_id ) |
||||
|
delete_all "mapping_rule" |
||||
|
declare -A mapping_rule_def=( ["http_method"]="GET" ["pattern"]="/" ["delta"]="1" ["metric_id"]="$method_id" ) |
||||
|
mapping_rule_create mapping_rule_def |
||||
|
|
||||
|
## |
||||
|
## Proxy configuration |
||||
|
## |
||||
|
breadcrumb=( services $service_id ) |
||||
|
declare -A proxy_def=( ["credentials_location"]="headers" ["auth_user_key"]="X-APIKey" ) |
||||
|
proxy_update proxy_def |
||||
|
proxy="$(get_result proxy_update | cleanup_item)" |
||||
|
|
||||
|
# Unless specified in the proxy definition, the endpoints are generated by 3scale |
||||
|
staging_endpoint="$(echo "$proxy" | jq -r .sandbox_endpoint)" |
||||
|
echo "Staging endpoint is: $staging_endpoint" |
||||
|
production_endpoint="$(echo "$proxy" | jq -r .endpoint)" |
||||
|
echo "Production endpoint is: $production_endpoint" |
||||
|
|
||||
|
## |
||||
|
## Link the Backend to the Service |
||||
|
## |
||||
|
breadcrumb=( services $service_id ) |
||||
|
declare -A backend_usage_def=( ["backend_id"]="$backend_id" ["path"]="/" ) |
||||
|
apply backend_usage present backend_usage_def |
||||
|
|
||||
|
## |
||||
|
## Update the policy chain |
||||
|
## |
||||
|
breadcrumb=( services $service_id ) |
||||
|
policies="$(policy_list | remove_policy 'cors' | jq '. += [ {"name": "cors", "version": "builtin", "configuration": {"allow_credentials": true}, "enabled": true} ]')" |
||||
|
policy_update "$policies" |
||||
|
|
||||
|
## |
||||
|
## Create one application plan |
||||
|
## |
||||
|
breadcrumb=( services $service_id ) |
||||
|
declare -A application_plan_def=( ["system_name"]="test" ["name"]="Test plan" ) |
||||
|
apply application_plan present application_plan_def |
||||
|
application_plan_id=$last_object_id |
||||
|
|
||||
|
## |
||||
|
## Create a test application |
||||
|
## |
||||
|
|
||||
|
# The application can be created in the default first account (aka the "Developer" account) |
||||
|
account_id="$(find_first_account | jq '.id')" |
||||
|
|
||||
|
# The user_key is an external identifier for the application. To achieve |
||||
|
# idempotency, we need to generate one by ourself. |
||||
|
# |
||||
|
# The application name, service system_name and admin access token (secret) are |
||||
|
# hashed together to produce a stable but unguessable identifier. |
||||
|
application_name="Test app" |
||||
|
user_key="$(echo -n "${application_name}${SERVICE_NAME}${THREESCALE_TOKEN}" | sha1sum | cut -d " " -f1)" |
||||
|
|
||||
|
breadcrumb=( accounts $account_id ) |
||||
|
declare -A application_def=( ["plan_id"]="$application_plan_id" ["name"]="$application_name" ["description"]="used for internal testing" ["user_key"]="$user_key" ) |
||||
|
apply application_apikey present application_def |
||||
|
application_id=$last_object_id |
||||
|
|
||||
|
## |
||||
|
## Smoke tests |
||||
|
## |
||||
|
|
||||
|
echo "Waiting 5 seconds before running tests on the staging environment..." |
||||
|
sleep 5 |
||||
|
|
||||
|
if ! curl -sfk $staging_endpoint/hello -H "X-APIKey: $user_key" > /dev/null; then |
||||
|
echo "Smoke test failed!" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
## |
||||
|
## Promotion to production |
||||
|
## |
||||
|
breadcrumb=( services $service_id ) |
||||
|
staging_version="$(proxy_version 'sandbox')" |
||||
|
echo "Proxy version in staging: $staging_version" |
||||
|
production_version="$(proxy_version 'production' || echo 'none')" |
||||
|
echo "Proxy version in production: $production_version" |
||||
|
|
||||
|
if [ "$staging_version" != "$production_version" ]; then |
||||
|
proxy_promote sandbox "$staging_version" |
||||
|
fi |
||||
|
|
||||
|
## |
||||
|
## Final tests |
||||
|
## |
||||
|
|
||||
|
while ! curl -sfk $production_endpoint/hello -H "X-APIKey: $user_key" &> /dev/null; do |
||||
|
echo "Production API is not yet ready..." |
||||
|
sleep 5 |
||||
|
done |
||||
|
|
||||
|
curl -sfk $production_endpoint/hello -H "X-APIKey: $user_key" --write-out "Production API - HTTP %{http_code}\n" -o /dev/null |
||||
@ -0,0 +1,35 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
set -Eeuo pipefail |
||||
|
|
||||
|
. 3scale-admin-cli.sh |
||||
|
|
||||
|
if [ -z "${THREESCALE_TOKEN:-}" ]; then |
||||
|
echo "Please set the THREESCALE_TOKEN environment variable!" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
if [ -z "${ADMIN_PORTAL_HOSTNAME:-}" ]; then |
||||
|
echo "Please set the ADMIN_PORTAL_HOSTNAME environment variable!" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
if [ -z "${SERVICE_NAME:-}" ]; then |
||||
|
echo "Please set the SERVICE_NAME environment variable!" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
## |
||||
|
## Service deletion |
||||
|
## |
||||
|
declare -A service_def=( ["system_name"]="${SERVICE_NAME}" ) |
||||
|
apply service absent service_def |
||||
|
|
||||
|
echo "Waiting 5 seconds before deleting the backend..." |
||||
|
sleep 5 |
||||
|
|
||||
|
## |
||||
|
## Backend deletion |
||||
|
## |
||||
|
declare -A backend_def=( ["system_name"]="${SERVICE_NAME}" ) |
||||
|
apply backend absent backend_def |
||||
@ -0,0 +1,165 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
set -Eeuo pipefail |
||||
|
|
||||
|
. 3scale-admin-cli.sh |
||||
|
|
||||
|
if [ -z "${THREESCALE_TOKEN:-}" ]; then |
||||
|
echo "Please set the THREESCALE_TOKEN environment variable!" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
if [ -z "${ADMIN_PORTAL_HOSTNAME:-}" ]; then |
||||
|
echo "Please set the ADMIN_PORTAL_HOSTNAME environment variable!" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
if [ -z "${OIDC_ISSUER_ENDPOINT:-}" ]; then |
||||
|
echo "Please set the OIDC_ISSUER_ENDPOINT environment variable!" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
if [ -z "${SERVICE_NAME:-}" ]; then |
||||
|
echo "Please set the SERVICE_NAME environment variable!" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
## |
||||
|
## Service creation |
||||
|
## |
||||
|
declare -A service_def=( ["system_name"]="$SERVICE_NAME" ["name"]="Echo API" ["description"]="Echo API with OIDC" ["deployment_option"]="hosted" ["backend_version"]="oidc" ) |
||||
|
apply service present service_def |
||||
|
service_id=$last_object_id |
||||
|
|
||||
|
## |
||||
|
## Backend creation |
||||
|
## |
||||
|
declare -A backend_def=( ["system_name"]="$SERVICE_NAME" ["name"]="Echo API" ["private_endpoint"]="https://echo-api.3scale.net" ) |
||||
|
apply backend present backend_def |
||||
|
backend_id=$last_object_id |
||||
|
|
||||
|
## |
||||
|
## Backend method creation |
||||
|
## |
||||
|
|
||||
|
# Find the "hits" metric so that we can create the methods under it |
||||
|
breadcrumb=( backend_apis $backend_id ) |
||||
|
hits_metric_id="$(metric_list | id_of_external_id_with_prefix "system_name" "hits")" |
||||
|
|
||||
|
# Create one method |
||||
|
breadcrumb=( backend_apis $backend_id metrics $hits_metric_id ) |
||||
|
declare -A method_def=( ["system_name"]="say_hello" ["friendly_name"]="sayHello" ["unit"]="hits" ) |
||||
|
apply method present method_def |
||||
|
method_id=$last_object_id |
||||
|
|
||||
|
# Create one mapping rule |
||||
|
breadcrumb=( backend_apis $backend_id ) |
||||
|
delete_all "mapping_rule" |
||||
|
declare -A mapping_rule_def=( ["http_method"]="GET" ["pattern"]="/" ["delta"]="1" ["metric_id"]="$method_id" ) |
||||
|
mapping_rule_create mapping_rule_def |
||||
|
|
||||
|
## |
||||
|
## Proxy configuration |
||||
|
## |
||||
|
breadcrumb=( services $service_id ) |
||||
|
declare -A proxy_def=( ["credentials_location"]="headers" ["oidc_issuer_endpoint"]="$OIDC_ISSUER_ENDPOINT" ) |
||||
|
proxy_update proxy_def |
||||
|
proxy="$(get_result proxy_update | cleanup_item)" |
||||
|
|
||||
|
# Unless specified in the proxy definition, the endpoints are generated by 3scale |
||||
|
staging_endpoint="$(echo "$proxy" | jq -r .sandbox_endpoint)" |
||||
|
echo "Staging endpoint is: $staging_endpoint" |
||||
|
production_endpoint="$(echo "$proxy" | jq -r .endpoint)" |
||||
|
echo "Production endpoint is: $production_endpoint" |
||||
|
|
||||
|
## |
||||
|
## Write the OIDC configuration |
||||
|
## |
||||
|
breadcrumb=( services $service_id ) |
||||
|
declare -A oidc_configuration_def=( ["standard_flow_enabled"]="false" ["implicit_flow_enabled"]="false" ["service_accounts_enabled"]="true" ["direct_access_grants_enabled"]="false" ) |
||||
|
oidc_configuration_update oidc_configuration_def |
||||
|
|
||||
|
## |
||||
|
## Link the Backend to the Service |
||||
|
## |
||||
|
breadcrumb=( services $service_id ) |
||||
|
declare -A backend_usage_def=( ["backend_id"]="$backend_id" ["path"]="/" ) |
||||
|
apply backend_usage present backend_usage_def |
||||
|
|
||||
|
## |
||||
|
## Update the policy chain |
||||
|
## |
||||
|
breadcrumb=( services $service_id ) |
||||
|
policies="$(policy_list | remove_policy 'cors' | jq '. += [ {"name": "cors", "version": "builtin", "configuration": {"allow_credentials": true}, "enabled": true} ]')" |
||||
|
policy_update "$policies" |
||||
|
|
||||
|
## |
||||
|
## Create one application plan |
||||
|
## |
||||
|
breadcrumb=( services $service_id ) |
||||
|
declare -A application_plan_def=( ["system_name"]="test" ["name"]="Test plan" ) |
||||
|
apply application_plan present application_plan_def |
||||
|
application_plan_id=$last_object_id |
||||
|
|
||||
|
## |
||||
|
## Create a test application |
||||
|
## |
||||
|
|
||||
|
# The application can be created in the default first account (aka the "Developer" account) |
||||
|
account_id="$(find_first_account | jq '.id')" |
||||
|
|
||||
|
# The application_id is an external identifier for the application. To achieve |
||||
|
# idempotency, we need to generate one by ourself. |
||||
|
# |
||||
|
# The application name, service system_name and admin access token (secret) are |
||||
|
# hashed together to produce a stable but unguessable identifier. |
||||
|
application_name="Test app" |
||||
|
client_id="$(echo -n "$application_name$SERVICE_NAME$THREESCALE_TOKEN" | sha1sum | cut -d " " -f1)" |
||||
|
client_secret="$(echo -n "secret$application_name$SERVICE_NAME$THREESCALE_TOKEN" | sha1sum | cut -d " " -f1)" |
||||
|
|
||||
|
breadcrumb=( accounts $account_id ) |
||||
|
declare -A application_def=( ["plan_id"]="$application_plan_id" ["name"]="$application_name" ["description"]="used for internal testing" ["application_id"]="$client_id" ["application_key"]="$client_secret" ) |
||||
|
apply application_appid present application_def |
||||
|
application_id=$last_object_id |
||||
|
|
||||
|
## |
||||
|
## Smoke tests |
||||
|
## |
||||
|
|
||||
|
# First, get a token from the Authorization Server |
||||
|
token_endpoint="$(echo "$OIDC_ISSUER_ENDPOINT" |sed -r 's|(https?)://[^:]+:[^@]+@([^/]+)/(.*)$|\1://\2/\3|')/protocol/openid-connect/token" |
||||
|
while ! curl -sfk "$token_endpoint" -X POST -d client_id="$client_id" -d client_secret="$client_secret" -d "grant_type=client_credentials" > "$tmp/token.json"; do |
||||
|
echo "Waiting for the OIDC client to appear in Keycloak..." |
||||
|
sleep 5 |
||||
|
done |
||||
|
token="$(jq -r .access_token "$tmp/token.json")" |
||||
|
|
||||
|
# Then, test the API |
||||
|
if ! curl -sfk $staging_endpoint/hello -H "Authorization: Bearer $token" > /dev/null; then |
||||
|
echo "Smoke test failed!" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
## |
||||
|
## Promotion to production |
||||
|
## |
||||
|
breadcrumb=( services $service_id ) |
||||
|
staging_version="$(proxy_version 'sandbox')" |
||||
|
echo "Proxy version in staging: $staging_version" |
||||
|
production_version="$(proxy_version 'production' || echo 'none')" |
||||
|
echo "Proxy version in production: $production_version" |
||||
|
|
||||
|
if [ "$staging_version" != "$production_version" ]; then |
||||
|
proxy_promote sandbox "$staging_version" |
||||
|
fi |
||||
|
|
||||
|
## |
||||
|
## Final tests |
||||
|
## |
||||
|
|
||||
|
while ! curl -sfk $production_endpoint/hello -H "Authorization: Bearer $token" &> /dev/null; do |
||||
|
echo "Production API is not yet ready..." |
||||
|
sleep 5 |
||||
|
done |
||||
|
|
||||
|
curl -sfk $production_endpoint/hello -H "Authorization: Bearer $token" --write-out "Production API - HTTP %{http_code}\n" -o /dev/null |
||||
@ -0,0 +1,35 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
set -Eeuo pipefail |
||||
|
|
||||
|
. 3scale-admin-cli.sh |
||||
|
|
||||
|
if [ -z "${THREESCALE_TOKEN:-}" ]; then |
||||
|
echo "Please set the THREESCALE_TOKEN environment variable!" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
if [ -z "${ADMIN_PORTAL_HOSTNAME:-}" ]; then |
||||
|
echo "Please set the ADMIN_PORTAL_HOSTNAME environment variable!" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
if [ -z "${SERVICE_NAME:-}" ]; then |
||||
|
echo "Please set the SERVICE_NAME environment variable!" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
## |
||||
|
## Service deletion |
||||
|
## |
||||
|
declare -A service_def=( ["system_name"]="${SERVICE_NAME}" ) |
||||
|
apply service absent service_def |
||||
|
|
||||
|
echo "Waiting 5 seconds before deleting the backend..." |
||||
|
sleep 5 |
||||
|
|
||||
|
## |
||||
|
## Backend deletion |
||||
|
## |
||||
|
declare -A backend_def=( ["system_name"]="${SERVICE_NAME}" ) |
||||
|
apply backend absent backend_def |
||||
@ -0,0 +1,43 @@ |
|||||
|
declare -A threescale_object_types=( ["backend"]="backend_apis" ["service"]="services" ["metric"]="metrics" ["method"]="methods" ["mapping_rule"]="mapping_rules" ["backend_usage"]="backend_usages" ["application_plan"]="application_plans" ["application_apikey"]="applications" ["application_appid"]="applications" ) |
||||
|
declare -A threescale_contains_external_id=( ["metric"]="contains_external_id_with_prefix" ["method"]="contains_external_id_with_prefix" ["backend_usage"]="contains_numerical_external_id") |
||||
|
declare -A threescale_id_of_external_id=( ["metric"]="id_of_external_id_with_prefix" ["method"]="id_of_external_id_with_prefix" ["backend_usage"]="id_of_numerical_external_id") |
||||
|
declare -A threescale_external_id=( ["backend_usage"]="backend_id" ["application_apikey"]="user_key" ["application_appid"]="application_id" ) |
||||
|
|
||||
|
template=$(cat <<"EOF" |
||||
|
function OBJECT_TYPE_list () { |
||||
|
echo "Finding all OBJECT_TYPE..." >&2 |
||||
|
threescale_call OBJECT_TYPE_list GET "$(breadcrumb_to_path breadcrumb)/URL_PART.json" "200" |
||||
|
if [ $? -gt 0 ]; then |
||||
|
return $? |
||||
|
fi |
||||
|
|
||||
|
get_result OBJECT_TYPE_list | cleanup_list |
||||
|
} |
||||
|
|
||||
|
function OBJECT_TYPE_create () { |
||||
|
local -n OBJECT_TYPE=$1 |
||||
|
local stable_id="$(external_id_factory OBJECT_TYPE)" |
||||
|
echo "Creating OBJECT_TYPE with $stable_id ${OBJECT_TYPE[$stable_id]:-}..." >&2 |
||||
|
threescale_call OBJECT_TYPE_create POST "$(breadcrumb_to_path breadcrumb)/URL_PART.json" "201" $(map_to_curl OBJECT_TYPE) |
||||
|
} |
||||
|
|
||||
|
function OBJECT_TYPE_update () { |
||||
|
local id=$1 |
||||
|
local -n OBJECT_TYPE=$2 |
||||
|
local stable_id="$(external_id_factory OBJECT_TYPE)" |
||||
|
echo "Updating OBJECT_TYPE with $stable_id ${OBJECT_TYPE[$stable_id]:-} and id $id..." >&2 |
||||
|
threescale_call OBJECT_TYPE_update PUT "$(breadcrumb_to_path breadcrumb)/URL_PART/$id.json" "200" $(map_to_curl OBJECT_TYPE) |
||||
|
} |
||||
|
|
||||
|
function OBJECT_TYPE_delete () { |
||||
|
local id=$1 |
||||
|
echo "Deleting OBJECT_TYPE with id $id..." >&2 |
||||
|
threescale_call OBJECT_TYPE_delete DELETE "$(breadcrumb_to_path breadcrumb)/URL_PART/$id.json" "200" |
||||
|
} |
||||
|
EOF |
||||
|
) |
||||
|
|
||||
|
for object_type in "${!threescale_object_types[@]}"; do |
||||
|
url_part="${threescale_object_types[$object_type]}" |
||||
|
eval "$(echo "$template" | sed "s/OBJECT_TYPE/$object_type/g; s/URL_PART/$url_part/g")" |
||||
|
done |
||||
@ -0,0 +1,183 @@ |
|||||
|
declare tmp=$(mktemp -d -t threescale-XXXXXXXXXX) |
||||
|
|
||||
|
function threescale_call () { |
||||
|
request_name="$1" |
||||
|
method="$2" |
||||
|
service="$3" |
||||
|
expected_http_codes="$4" |
||||
|
shift 4 |
||||
|
|
||||
|
# Make HTTP methods uppercase |
||||
|
method="${method^^}" |
||||
|
|
||||
|
local -a curl_args=( -sk --write-out "%{http_code}" -o "$tmp/$request_name.json" -X "$method" "$@") |
||||
|
local url="https://$ADMIN_PORTAL_HOSTNAME/admin/api$service" |
||||
|
|
||||
|
if [[ "$method" == "GET" || "$method" == "DELETE" ]]; then |
||||
|
if [[ "$url" =~ .*\?.* ]]; then |
||||
|
url="$url&access_token=$THREESCALE_TOKEN" |
||||
|
else |
||||
|
url="$url?access_token=$THREESCALE_TOKEN" |
||||
|
fi |
||||
|
else |
||||
|
curl_args+=( "-d" "access_token=$THREESCALE_TOKEN" ) |
||||
|
fi |
||||
|
|
||||
|
curl_args+=( "$url" ) |
||||
|
|
||||
|
if [ "${CURL_DEBUG:-}" != "" ]; then |
||||
|
echo curl "${curl_args[@]}" ">" "$tmp/$request_name.code" >&2 |
||||
|
fi |
||||
|
|
||||
|
curl "${curl_args[@]}" > "$tmp/$request_name.code" |
||||
|
ret=$? |
||||
|
if [ $ret -gt 0 ]; then |
||||
|
echo "curl exited with rc = $ret" >&2 |
||||
|
return $ret |
||||
|
fi |
||||
|
|
||||
|
if [ "${CURL_DEBUG:-}" != "" ]; then |
||||
|
echo "=> HTTP $(cat "$tmp/$request_name.code")" >&2 |
||||
|
fi |
||||
|
|
||||
|
if ! egrep -q "^$expected_http_codes\$" "$tmp/$request_name.code"; then |
||||
|
echo "Unexpected HTTP code: $(cat "$tmp/$request_name.code")" >&2 |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
return 0 |
||||
|
} |
||||
|
|
||||
|
function get_result_file () { |
||||
|
request_name="$1" |
||||
|
echo -n "$tmp/$request_name.json" |
||||
|
} |
||||
|
|
||||
|
function get_result () { |
||||
|
request_name="$1" |
||||
|
cat "$tmp/$request_name.json" |
||||
|
} |
||||
|
|
||||
|
function cleanup_list () { |
||||
|
jq 'to_entries | .[0].value | map(to_entries | .[0].value)' |
||||
|
} |
||||
|
|
||||
|
function cleanup_item () { |
||||
|
jq 'to_entries | .[0].value' |
||||
|
} |
||||
|
|
||||
|
function map_to_curl () { |
||||
|
local -n map=$1 |
||||
|
for k in "${!map[@]}"; do |
||||
|
v="$(urlencode "${map[$k]}")" |
||||
|
echo -d "$k=$v" |
||||
|
done |
||||
|
} |
||||
|
|
||||
|
declare -a breadcrumb |
||||
|
|
||||
|
function breadcrumb_to_path () { |
||||
|
join_by "/" "" ${breadcrumb[@]} |
||||
|
} |
||||
|
|
||||
|
declare last_object_id |
||||
|
|
||||
|
function apply () { |
||||
|
local object_type="$1" |
||||
|
local state="$2" |
||||
|
local -n object=$3 |
||||
|
|
||||
|
${object_type}_list > "$tmp/apply_list.json" |
||||
|
ret=$? |
||||
|
if [ $ret -gt 0 ]; then |
||||
|
echo "${object_type}_list exited with rc = $ret" >&2 |
||||
|
return $ret |
||||
|
fi |
||||
|
local list="$(cat $tmp/apply_list.json)" |
||||
|
|
||||
|
external_id="$(external_id_factory $object_type)" |
||||
|
|
||||
|
last_object_id= |
||||
|
case "$state" in |
||||
|
"present") |
||||
|
if echo "$list" | "$(contains_external_id_factory "$object_type")" "$external_id" "${object[$external_id]}"; then |
||||
|
local id="$(echo "$list" | "$(id_of_external_id_factory "$object_type")" "$external_id" "${object[$external_id]}")" |
||||
|
"${object_type}_update" "$id" object |
||||
|
ret=$? |
||||
|
if [ $ret -gt 0 ]; then |
||||
|
echo "${object_type}_update exited with rc = $ret" >&2 |
||||
|
return $ret |
||||
|
fi |
||||
|
last_object_id="$id" |
||||
|
else |
||||
|
"${object_type}_create" object |
||||
|
ret=$? |
||||
|
if [ $ret -gt 0 ]; then |
||||
|
echo "${object_type}_create exited with rc = $ret" >&2 |
||||
|
return $ret |
||||
|
fi |
||||
|
last_object_id="$(get_result "${object_type}_create" | cleanup_item | jq -r .id)" |
||||
|
fi |
||||
|
;; |
||||
|
"absent") |
||||
|
if echo "$list" | "$(contains_external_id_factory "$object_type")" "$external_id" "${object[$external_id]}"; then |
||||
|
local id="$(echo "$list" | "$(id_of_external_id_factory "$object_type")" "$external_id" "${object[$external_id]}" )" |
||||
|
"${object_type}_delete" "$id" |
||||
|
ret=$? |
||||
|
if [ $ret -gt 0 ]; then |
||||
|
echo "${object_type}_delete exited with rc = $ret" >&2 |
||||
|
return $ret |
||||
|
fi |
||||
|
fi |
||||
|
;; |
||||
|
esac |
||||
|
} |
||||
|
|
||||
|
function delete_all () { |
||||
|
local object_type="$1" |
||||
|
"${object_type}_list" | jq -r '.[] | .id' | while read id; do |
||||
|
"${object_type}_delete" "$id" |
||||
|
done |
||||
|
} |
||||
|
|
||||
|
function external_id_factory () { |
||||
|
local object_type="$1" |
||||
|
id="${threescale_external_id[$object_type]:-}" |
||||
|
echo "${id:-system_name}" |
||||
|
} |
||||
|
|
||||
|
function contains_external_id_factory () { |
||||
|
local object_type="$1" |
||||
|
fn="${threescale_contains_external_id[$object_type]:-}" |
||||
|
echo "${fn:-contains_external_id}" |
||||
|
} |
||||
|
|
||||
|
function id_of_external_id_factory () { |
||||
|
local object_type="$1" |
||||
|
fn="${threescale_id_of_external_id[$object_type]:-}" |
||||
|
echo "${fn:-id_of_external_id}" |
||||
|
} |
||||
|
|
||||
|
function contains_external_id_with_prefix () { |
||||
|
jq --arg k "$1" --arg v "$2" -e '[ .[] | select(.[$k] | startswith($v + ".")) ] | length != 0' > /dev/null |
||||
|
} |
||||
|
|
||||
|
function id_of_external_id_with_prefix () { |
||||
|
jq --arg k "$1" --arg v "$2" -r '.[] | select(.[$k] | startswith($v + ".")) | .id ' |
||||
|
} |
||||
|
|
||||
|
function contains_external_id () { |
||||
|
jq --arg k "$1" --arg v "$2" -e '[ .[] | select(.[$k] == $v) ] | length != 0' > /dev/null |
||||
|
} |
||||
|
|
||||
|
function id_of_external_id () { |
||||
|
jq --arg k "$1" --arg v "$2" -r '.[] | select(.[$k] == $v) | .id ' |
||||
|
} |
||||
|
|
||||
|
function contains_numerical_external_id () { |
||||
|
jq --arg k "$1" --arg v "$2" -e '[ .[] | select(.[$k] == ($v|tonumber)) ] | length != 0' > /dev/null |
||||
|
} |
||||
|
|
||||
|
function id_of_numerical_external_id () { |
||||
|
jq --arg k "$1" --arg v "$2" -r '.[] | select(.[$k] == ($v|tonumber)) | .id ' |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
# https://gist.github.com/cdown/1163649 |
||||
|
|
||||
|
export LC_COLLATE=C |
||||
|
|
||||
|
urlencode() { |
||||
|
# urlencode <string> |
||||
|
|
||||
|
local length="${#1}" |
||||
|
for (( i = 0; i < length; i++ )); do |
||||
|
local c="${1:$i:1}" |
||||
|
case $c in |
||||
|
[a-zA-Z0-9.~_-]) printf '%s' "$c" ;; |
||||
|
*) printf '%%%02X' "'$c" ;; |
||||
|
esac |
||||
|
done |
||||
|
} |
||||
|
|
||||
|
urldecode() { |
||||
|
# urldecode <string> |
||||
|
|
||||
|
local url_encoded="${1//+/ }" |
||||
|
printf '%b' "${url_encoded//%/\\x}" |
||||
|
} |
||||
|
|
||||
|
# https://stackoverflow.com/questions/1527049/how-can-i-join-elements-of-an-array-in-bash |
||||
|
function join_by { local IFS="$1"; shift; echo "$*"; } |
||||
|
|
||||
@ -0,0 +1,9 @@ |
|||||
|
function find_first_account () { |
||||
|
echo "Finding the default first account..." >&2 |
||||
|
threescale_call find_first_account GET "/accounts.json?state=approved&page=1&per_page=1" "200" |
||||
|
if [ $? -gt 0 ]; then |
||||
|
return $? |
||||
|
fi |
||||
|
|
||||
|
get_result find_first_account | cleanup_list | jq '.[0]' |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
function backend_usage_list () { |
||||
|
echo "Finding all backend_usage..." >&2 |
||||
|
threescale_call backend_usage_list GET "$(breadcrumb_to_path breadcrumb)/backend_usages.json" "200" |
||||
|
if [ $? -gt 0 ]; then |
||||
|
return $? |
||||
|
fi |
||||
|
|
||||
|
get_result backend_usage_list | jq 'map(to_entries |.[0].value)' |
||||
|
} |
||||
|
|
||||
|
function backend_usage_create () { |
||||
|
local -n backend_usage=$1 |
||||
|
|
||||
|
local -A api_call_payload |
||||
|
for key in "${!backend_usage[@]}"; do |
||||
|
if [ "$key" == "backend_id" ]; then |
||||
|
api_call_payload[backend_api_id]="${backend_usage[backend_id]}" |
||||
|
else |
||||
|
api_call_payload[$key]="${backend_usage[$key]}" |
||||
|
fi |
||||
|
done |
||||
|
|
||||
|
echo "Creating backend_usage with backend_id = ${api_call_payload[backend_api_id]:-}..." >&2 |
||||
|
threescale_call backend_usage_create POST "$(breadcrumb_to_path breadcrumb)/backend_usages.json" "201" $(map_to_curl api_call_payload) |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
function policy_list () { |
||||
|
echo "Finding all policies..." >&2 |
||||
|
threescale_call policies_list GET "$(breadcrumb_to_path breadcrumb)/proxy/policies.json" "200" |
||||
|
if [ $? -gt 0 ]; then |
||||
|
return $? |
||||
|
fi |
||||
|
|
||||
|
get_result policies_list | cleanup_item |
||||
|
} |
||||
|
|
||||
|
function policy_update () { |
||||
|
local policy_chain="$1" |
||||
|
|
||||
|
echo "Updating policies..." >&2 |
||||
|
threescale_call policy_update PUT "$(breadcrumb_to_path breadcrumb)/proxy/policies.json" "200" --data-urlencode "policies_config=$1" |
||||
|
} |
||||
|
|
||||
|
function contains_policy () { |
||||
|
policy_name="$1" |
||||
|
jq --arg policy_name "$policy_name" -e '[ .[] | select(.name == $policy_name) ] | length != 0' > /dev/null |
||||
|
} |
||||
|
|
||||
|
function remove_policy () { |
||||
|
policy_name="$1" |
||||
|
jq --arg policy_name "$policy_name" -r '[ .[] | select(.name != $policy_name) ]' |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
function proxy_update () { |
||||
|
local -n proxy=$1 |
||||
|
echo "Updating proxy..." >&2 |
||||
|
threescale_call proxy_update PUT "$(breadcrumb_to_path breadcrumb)/proxy.json" "200" $(map_to_curl proxy) |
||||
|
} |
||||
|
|
||||
|
function proxy_version () { |
||||
|
local environment=$1 |
||||
|
|
||||
|
echo "Getting proxy version of env $environment..." >&2 |
||||
|
threescale_call proxy_version GET "$(breadcrumb_to_path breadcrumb)/proxy/configs/${environment}/latest.json" "200" |
||||
|
if [ $? -gt 0 ]; then |
||||
|
return $? |
||||
|
fi |
||||
|
|
||||
|
get_result proxy_version | cleanup_item | jq '.version' |
||||
|
} |
||||
|
|
||||
|
function proxy_promote () { |
||||
|
local environment="$1" |
||||
|
local version="$2" |
||||
|
echo "Promoting proxy version $version of env $environment..." >&2 |
||||
|
threescale_call proxy_promote POST "$(breadcrumb_to_path breadcrumb)/proxy/configs/${environment}/${version}/promote.json" "201" -d to=production |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,6 @@ |
|||||
|
function oidc_configuration_update () { |
||||
|
local -n oidc_configuration=$1 |
||||
|
|
||||
|
echo "Updating OIDC configuration..." >&2 |
||||
|
threescale_call policy_update PATCH "$(breadcrumb_to_path breadcrumb)/proxy/oidc_configuration.json" "200" $(map_to_curl oidc_configuration) |
||||
|
} |
||||
Loading…
Reference in new issue