Skip to content

Commit

Permalink
Observability related functions (#13)
Browse files Browse the repository at this point in the history
* Initial Observability scripts

Signed-off-by: Jeroen van Erp <[email protected]>

* Added comments and use vars

Signed-off-by: Jeroen van Erp <[email protected]>

* Return instead of global vars

Signed-off-by: Jeroen van Erp <[email protected]>

* Fix return vs echo

Signed-off-by: Jeroen van Erp <[email protected]>

* Try to fix escapes

Signed-off-by: Jeroen van Erp <[email protected]>

* Appease the lords of Bash linting

Signed-off-by: Jeroen van Erp <[email protected]>

* Incorporate review comments

Signed-off-by: Jeroen van Erp <[email protected]>

---------

Signed-off-by: Jeroen van Erp <[email protected]>
  • Loading branch information
hierynomus authored Sep 17, 2024
1 parent 084bb1b commit 8abd214
Show file tree
Hide file tree
Showing 5 changed files with 271 additions and 0 deletions.
103 changes: 103 additions & 0 deletions scripts/authentication/keycloak.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#!/bin/bash

#######################################
# Login to Keycloak and get an access token
# Globals:
# SSO_ACCESS_TOKEN
# Arguments:
# kc_url (Keycloak)
# kc_realm (Keycloak)
# kc_client_id (Keycloak)
# kc_client_secret (Keycloak)
# kc_username (Keycloak)
# kc_password (Keycloak)
# Examples:
# keycloak_login https://sso.suse.com instruqt suse xxxxxx admin password
#######################################
keycloak_login() {
local kc_url=$1
local kc_realm=$2
local kc_client_id=$3
local kc_client_secret=$4
local kc_username=$5
local kc_password=$6

local response
response=$(curl -s -X POST "$kc_url/realms/$kc_realm/protocol/openid-connect/token" \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode "client_id=$kc_client_id" \
--data-urlencode "client_secret=$kc_client_secret" \
--data-urlencode "username=$kc_username" \
--data-urlencode "password=$kc_password" \
--data-urlencode 'grant_type=password')

echo $response | jq -r .access_token
}

#######################################
# Create a user in Keycloak
# Arguments:
# kc_url (Keycloak)
# kc_realm (Keycloak)
# kc_access_token (Keycloak)
# username
# password
# Examples:
# keycloak_create_user https://sso.suse.com instruqt $SSO_ACCESS_TOKEN user password group
#######################################
keycloak_create_user() {
local kc_url=$1
local kc_realm=$2
local kc_access_token=$3
local username=$4
local password=$5
local group=$6

local user_request
user_request=$(cat <<EOF
{
"username": "$username",
"enabled": true,
"emailVerified": true,
"requiredActions": [],
"email": "$username@instruqt.suse.io",
"groups": ["$group"],
"credentials": [
{
"type": "password",
"value": "$password"
}
]
}
EOF
)

curl -s -X POST "$kc_url/admin/realms/$kc_realm/users" \
-H "Authorization: Bearer $kc_access_token" \
-H 'Content-Type: application/json' \
--data-binary "$user_request"
}

#######################################
# Delete a user in Keycloak
# Arguments:
# kc_url (Keycloak)
# kc_realm (Keycloak)
# kc_access_token (Keycloak)
# username
# Examples:
# keycloak_delete_user https://sso.suse.com instruqt $SSO_ACCESS_TOKEN user
#######################################
keycloak_delete_user() {
local kc_url=$1
local kc_realm=$2
local kc_access_token=$3
local username=$4

local user_id
user_id=$(curl -s -X GET "$kc_url/admin/realms/$kc_realm/users?username=$username" \
-H "Authorization: Bearer $kc_access_token" | jq -r .[0].id)

curl -s -X DELETE "$kc_url/admin/realms/$kc_realm/users/$user_id" \
-H "Authorization: Bearer $kc_access_token"
}
49 changes: 49 additions & 0 deletions scripts/observability/api_key.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/bash

#######################################
# Create an Ingestion API key for SUSE Observability
# Output:
# The ingestion API key
# Arguments:
# url (SUSE Observability)
# service_token (SUSE Observability)
# cluster_name
# Examples:
# observability_create_ingestion_api_key https://obs.suse.com/ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx demo
#######################################
observability_create_ingestion_api_key() {
local url=$1
local service_token=$2
local cluster_name=$3

local resp
resp=$(/usr/local/bin/sts ingestion-api-key create --name $cluster_name -o json --url $url --service-token $service_token)

echo $resp | jq -r '."ingestion-api-key".apiKey'
}

#######################################
# Delete an Ingestion API key for SUSE Observability
# Arguments:
# url (SUSE Observability)
# service_token (SUSE Observability)
# cluster_name
# Examples:
# observability_delete_ingestion_api_key https://obs.suse.com/ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx demo
#######################################
observability_delete_ingestion_api_key() {
local url=$1
local service_token=$2
local cluster_name=$3

local keys key_id

keys=$(/usr/local/bin/sts ingestion-api-key list -o json --url $url --service-token $service_token)
key_id=$(echo $keys | jq -r '."ingestion-api-keys"[] | select(.name == "'$cluster_name'") | .id')
if [ -n "$key_id" ]; then
/usr/local/bin/sts ingestion-api-key delete --id $key_id --url $url --service-token $service_token
echo ">>> Ingestion API key for cluster '${cluster_name}' deleted"
else
echo ">>> Ingestion API key for cluster '${cluster_name}' not found"
fi
}
12 changes: 12 additions & 0 deletions scripts/observability/cli.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

#######################################
# Install the SUSE Observability CLI
#######################################
observability_install_cli() {
if [ -x "$(command -v sts)" ]; then
curl -o- https://dl.stackstate.com/stackstate-cli/install.sh | STS_CLI_LOCATION=/usr/local/bin bash
else
echo ">>> sts CLI already installed"
fi
}
46 changes: 46 additions & 0 deletions scripts/observability/stackpack.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash

#######################################
# Delete a StackPack instance from SUSE Observability
# Arguments:
# url (SUSE Observability)
# service_token (SUSE Observability)
# cluster_name
# Examples:
# observability_delete_stackpack https://obs.suse.com/ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx demo
#######################################
observability_delete_stackpack() {
local url=$1
local service_token=$2
local cluster_name=$3

if observability_check_stackpack $url $service_token $cluster_name; then
/usr/local/bin/sts stackpack uninstall --id $stackpack_id --url $url --service-token $service_token --name kubernetes-v2
echo ">>> StackPack for cluster '${cluster_name}' deleted"
else
echo ">>> StackPack for cluster '${cluster_name}' not found"
fi
}

#######################################
# Check if a StackPack instance exists in SUSE Observability
# Arguments:
# url (SUSE Observability)
# service_token (SUSE Observability)
# cluster_name
# Returns:
# `true` if the StackPack instance exists, `false` otherwise
# Examples:
# observability_check_stackpack https://obs.suse.com/ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx demo
#######################################
observability_check_stackpack() {
local url=$1
local service_token=$2
local cluster_name=$3

local stackpacks stackpack_id
stackpacks=$(/usr/local/bin/sts stackpack list-instances --name kubernetes-v2 -o json --url $url --service-token $service_token)
stackpack_id=$(echo $stackpacks | jq -r '.instances[] | select(.config.kubernetes_cluster_name == "'$cluster_name'") | .id')
[[ -n "$stackpack_id" ]]
return
}
61 changes: 61 additions & 0 deletions scripts/observability/stql.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/bin/bash

#######################################
# Get the state of a component in SUSE Observability
# Arguments:
# url (SUSE Observability)
# service_token (SUSE Observability)
# stql
# Output:
# "CRITICAL", "DEVIATING", "UNKNOWN" or "CLEAR"
# Examples:
# observability_get_component_state https://obs.suse.com/ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx "lobel = \"cluster-name:$DOWNSTREAM_CLUSTER_NAME\" AND ..."
#######################################
observability_get_component_state() {
local url=$1
local service_token=$2
local stql=$3

local component
component=$(observability_get_component_snapshot $url $service_token "$stql")
echo $component | jq -r '.viewSnapshotResponse.components[0].state.healthState'
}

#######################################
# Query the snapshot of a component in SUSE Observability
# Arguments:
# url (SUSE Observability)
# service_token (SUSE Observability)
# stql
# Output:
# JSON viewSnapshotResponse
# Examples:
# observability_get_component_snapshot https://obs.suse.com/ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx "lobel = \"cluster-name:$DOWNSTREAM_CLUSTER_NAME\" AND ..."
#######################################
observability_get_component_snapshot() {
local url=$1
local service_token=$2
local stql=$3

local req
req=$(cat <<EOF
{
"queryVersion": "1.0",
"metadata": {
"groupingEnabled": false,
"showIndirectRelations": false,
"minGroupSize": 10,
"groupedByLayer": false,
"groupedByDomain": false,
"groupedByRelation": false,
"autoGrouping": false,
"connectedComponents": false,
"neighboringComponents": false,
"showFullComponent": false
}
}
EOF
)
req=$(echo $req | jq --arg stql "$stql" '.query = "\($stql)"')
curl -s -k -H "Authorization: ApiKey $service_token" -H "Content-Type: application/json" -X POST -d "$req" $url/api/snapshot
}

0 comments on commit 8abd214

Please sign in to comment.