Skip to content

Instantly share code, notes, and snippets.

@fsultan
Created July 12, 2024 21:03
Show Gist options
  • Save fsultan/5388c611ac7c22eb64358b6f5706b2c0 to your computer and use it in GitHub Desktop.
Save fsultan/5388c611ac7c22eb64358b6f5706b2c0 to your computer and use it in GitHub Desktop.
solace config map
apiVersion: v1
items:
- apiVersion: v1
data:
ca.crt: |
-----BEGIN CERTIFICATE-----
MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwptaW5p
a3ViZUNBMB4XDTIzMDMwOTE1Mzk0NVoXDTMzMDMwNzE1Mzk0NVowFTETMBEGA1UE
AxMKbWluaWt1YmVDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALBK
GGy3kyK4qAl1bMM0OHBMPYuFOFk7hQgVCxVnzj8ZENy+pTjUUtbyrT7d2lFL9WS4
6i1PvKW78vzf+fm3evv2jhQDxb/hB883kMscv39nawK71Z/SHp0CMNTz8DX2YaLE
cynuKl/3f8IhohjW/GjLB3+LtmkQcusgMmcZp1yDpfdJzHRWEr/okFA6BV7Xoaib
tLwgYxRYstF6QMbBx8zT2wHPz8koL2bzVBzDXbRdFvBGoYhCrhnAspiXpF3kEwaT
qUymHfB+joDrLqxxeEgumFgHYreg5OSSy44aSmZkU+M+we6ABPHZZFSyY3zcjQr2
evL8VFFu/gegEb1odI0CAwEAAaNhMF8wDgYDVR0PAQH/BAQDAgKkMB0GA1UdJQQW
MBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
BBTOlyvjrF7JOiNqj2M8iLfdgd8CNjANBgkqhkiG9w0BAQsFAAOCAQEAMPIwbNfb
t41+6WFsQ63jWSDl8dnvHM2S7eIk4sZ/25xQVba4NwTywTbiUDHYO4mWEj0vPz94
RWCf9gJ/MkpqU1VoSvgIDquYp+uXJHXieH1bf2XOpVvKGKZtdvUqD8Z1xegR+YQK
s9fA5rO/zIi/EgsIWyMQib4748fI+WnIQE/6kI2nm02rTMJbgFfjjGS5JQODHA5Z
3EZCY2x6yRUAoSd0awqIn7Y8oK9shgfEs1Rtw7Dy5yOpBkhO7smbhAyWJNoFMZmc
osmTEQ5lFjRDyykj71K8ha9YuIZV9XzfIHYBNmiqn/EiRwl3qRKHZyEbZc+6LtB+
cHWBGxRkcxS1ag==
-----END CERTIFICATE-----
kind: ConfigMap
metadata:
annotations:
kubernetes.io/description: Contains a CA bundle that can be used to verify the
kube-apiserver when using internal endpoints such as the internal service
IP or kubernetes.default.svc. No other usage is guaranteed across distributions
of Kubernetes clusters.
creationTimestamp: "2024-07-12T19:30:14Z"
name: kube-root-ca.crt
namespace: default
resourceVersion: "334"
uid: edf934f6-2b9c-438c-9f77-e5158d6bced9
- apiVersion: v1
data:
init.sh: |-
export username_admin_passwordfilepath="/mnt/disks/secrets/username_admin_password"
export username_admin_globalaccesslevel=admin
export service_ssh_port='2222'
export service_webtransport_port='8008'
export service_webtransport_tlsport='1443'
export service_semp_tlsport='1943'
export logging_debug_output=all
export system_scaling_maxconnectioncount="100"
# Deal with the fact we cannot accept "-" in router names
export routername=$(echo $(hostname) | sed 's/-//g')
readiness_check.sh: |-
#!/bin/bash
APP=`basename "$0"`
LOG_FILE=/usr/sw/var/k8s_readiness_check.log # STDOUT/STDERR goes to k8s event logs but gets cleaned out eventually. This will also persist it.
if [ -f ${LOG_FILE} ] ; then
tail -n 1000 ${LOG_FILE} > ${LOG_FILE}.tmp; mv -f ${LOG_FILE}.tmp ${LOG_FILE} || : # Limit logs size
fi
exec > >(tee -a ${LOG_FILE}) 2>&1 # Setup logging
FINAL_ACTIVITY_LOGGED_TRACKING_FILE=/tmp/final_activity_state_logged
# Function to read Kubernetes metadata labels
get_label () {
# Params: $1 label name
echo $(cat /etc/podinfo/labels | awk -F= '$1=="'${1}'"{print $2}' | xargs);
}
# Function to set Kubernetes metadata labels
set_label () {
# Params: $1 label name, $2 label set value
#Prevent overdriving Kubernetes infra, don't set activity state to same as previous state
previous_state=$(get_label "active")
if [ "${2}" = "${previous_state}" ]; then
#echo "`date` INFO: ${APP}-Current and Previous state match (${2}), not updating pod label"
:
else
echo "`date` INFO: ${APP}-Updating pod label using K8s API from ${previous_state} to ${2}"
echo "[{\"op\": \"add\", \"path\": \"/metadata/labels/${1}\", \"value\": \"${2}\" }]" > /tmp/patch_label.json
K8S=https://kubernetes.default.svc.cluster.local:$KUBERNETES_SERVICE_PORT
KUBE_TOKEN=$(</var/run/secrets/kubernetes.io/serviceaccount/token)
CACERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
NAMESPACE=$(</var/run/secrets/kubernetes.io/serviceaccount/namespace)
if ! curl -sS --output /dev/null --cacert $CACERT --connect-timeout 5 \
--request PATCH --data "$(cat /tmp/patch_label.json)" \
-H "Authorization: Bearer $KUBE_TOKEN" -H "Content-Type:application/json-patch+json" \
$K8S/api/v1/namespaces/$NAMESPACE/pods/$HOSTNAME ; then
# Label update didn't work this way, fall back to alternative legacy method to update label
if ! curl -sSk --output /dev/null -H "Authorization: Bearer $KUBE_TOKEN" --request PATCH --data "$(cat /tmp/patch_label.json)" \
-H "Content-Type:application/json-patch+json" \
https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_PORT_443_TCP_PORT/api/v1/namespaces/$STATEFULSET_NAMESPACE/pods/$HOSTNAME ; then
echo "`date` ERROR: ${APP}-Unable to update pod label, check access from pod to K8s API or RBAC authorization" >&2
rm -f ${FINAL_ACTIVITY_LOGGED_TRACKING_FILE}; exit 1
fi
fi
fi
}
# Function to get remote sync state
get_router_remote_config_state() {
# Params: $1 is property of config to return for router
routerresults=`/mnt/disks/solace/semp_query.sh -n admin -p ${password} -u http://localhost:8080 \
-q "<rpc><show><config-sync><database/><router/><remote/></config-sync></show></rpc>" \
-v "/rpc-reply/rpc/show/config-sync/database/remote/tables/table[1]/source-router/${1}"`
routerremotesync_result=`echo ${routerresults} | xmllint -xpath "string(returnInfo/valueSearchResult)" -`
echo $routerremotesync_result
}
# Main logic: note that there are no re-tries here, if check fails then return not ready.
# nonHA config
health_result=`curl -s -o /dev/null -w "%{http_code}" http://localhost:5550/health-check/guaranteed-active`
case "${health_result}" in
"200")
if [ ! -f ${FINAL_ACTIVITY_LOGGED_TRACKING_FILE} ]; then
echo "`date` INFO: ${APP}-nonHA Event Broker health check reported 200, message spool is up"
touch ${FINAL_ACTIVITY_LOGGED_TRACKING_FILE}
echo "`date` INFO: ${APP}-Server status check complete for this broker node"
echo "`date` INFO: ${APP}-Changing pod label to active"
exit 1
fi
set_label "active" "true"
exit 0
;;
"503")
if [[ $(get_label "active") = "true" ]]; then echo "`date` INFO: ${APP}-nonHA Event Broker health check reported 503, message spool is down"; fi
set_label "active" "false"
echo "`date` INFO: ${APP}-Changing pod label to inactive"
# Fail readiness check
rm -f ${FINAL_ACTIVITY_LOGGED_TRACKING_FILE}; exit 1
;;
*)
echo "`date` WARN: ${APP}-nonHA Event Broker health check reported ${health_result}"
set_label "active" "false"
echo "`date` INFO: ${APP}-Changing pod label to inactive"
# Fail readiness check
rm -f ${FINAL_ACTIVITY_LOGGED_TRACKING_FILE}; exit 1
esac
semp_query.sh: |-
#!/bin/bash
APP=`basename "$0"`
OPTIND=1 # Reset in case getopts has been used previously in the shell.
# Initialize our own variables:
count_search=""
name=""
password=""
query=""
url=""
value_search=""
test_connection_only=false
script_name=$0
verbose=0
while getopts "c:n:p:q:u:v:t" opt; do
case "$opt" in
c) count_search=$OPTARG
;;
n) username=$OPTARG
;;
p) password=$OPTARG
;;
q) query=$OPTARG
;;
u) url=$OPTARG
;;
v) value_search=$OPTARG
;;
t) test_connection_only=true
;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
verbose=1
#echo "`date` INFO: ${APP}-${script_name}: count_search=${count_search} ,username=${username} ,password=xxx query=${query} \
# ,url=${url} ,value_search=${value_search} ,Leftovers: $@" >&2
if [[ ${url} = "" || ${username} = "" || ${password} = "" ]]; then
echo "`date` ERROR: ${APP}-${script_name}: url, username, password are madatory fields" >&2
echo '<returnInfo><errorInfo>missing parameter</errorInfo></returnInfo>'
exit 1
fi
if [ "`curl --write-out '%{http_code}' --silent --output /dev/null -u ${username}:${password} ${url}/SEMP -d '<rpc><show><version/></show></rpc>'`" != "200" ] ; then
echo "<returnInfo><errorInfo>management host is not responding</errorInfo></returnInfo>"
exit 1
fi
if [ "$test_connection_only" = true ] ; then
exit 0 # done here, connection is up
fi
query_response=`curl -sS -u ${username}:${password} ${url}/SEMP -d "${query}"`
# Validate first char of response is "<", otherwise no hope of being valid xml
if [[ ${query_response:0:1} != "<" ]] ; then
echo "<returnInfo><errorInfo>no valid xml returned</errorInfo></returnInfo>"
exit 1
fi
query_response_code=`echo $query_response | xmllint -xpath 'string(/rpc-reply/execute-result/@code)' -`
if [[ -z ${query_response_code} && ${query_response_code} != "ok" ]]; then
echo "<returnInfo><errorInfo>query failed -${query_response_code}-</errorInfo></returnInfo>"
exit 1
fi
#echo "`date` INFO: ${APP}-${script_name}: query passed ${query_response_code}" >&2
if [[ ! -z $value_search ]]; then
value_result=`echo $query_response | xmllint -xpath "string($value_search)" -`
echo "<returnInfo><errorInfo></errorInfo><valueSearchResult>${value_result}</valueSearchResult></returnInfo>"
exit 0
fi
if [[ ! -z $count_search ]]; then
count_line=`echo $query_response | xmllint -xpath "$count_search" -`
count_string=`echo $count_search | cut -d '"' -f 2`
count_result=`echo ${count_line} | tr "><" "\n" | grep -c ${count_string}`
echo "<returnInfo><errorInfo></errorInfo><countSearchResult>${count_result}</countSearchResult></returnInfo>"
exit 0
fi
startup-broker.sh: "#!/bin/bash\nAPP=`basename \"$0\"`\nIFS='-' read -ra host_array
<<< $(hostname)\nnode_ordinal=${host_array[-1]}\necho \"`date` INFO: ${APP}-Node
ordinal: ${node_ordinal}\"\necho \"`date` INFO: ${APP}-Waiting for management
API to become available\"\npassword=`cat /mnt/disks/secrets/username_admin_password`\nINITIAL_STARTUP_FILE=/var/lib/solace/var/k8s_initial_startup_marker\nloop_guard=60\npause=10\ncount=0\n#
Wait for Solace Management API\nwhile [ ${count} -lt ${loop_guard} ]; do \n
\ if /mnt/disks/solace/semp_query.sh -n admin -p ${password} -u http://localhost:8080
-t ; then\n break\n fi\n run_time=$((${count} * ${pause}))\n ((count++))\n
\ echo \"`date` INFO: ${APP}-Waited ${run_time} seconds, Management API not
yet accessible\"\n sleep ${pause}\ndone\nif [ ${count} -eq ${loop_guard} ];
then\n echo \"`date` ERROR: ${APP}-Solace Management API never came up\" >&2\n
\ exit 1 \nfi\necho \"`date` INFO: ${APP}-PubSub+ Event Broker bringup is complete
for this node.\"\n# create startup file after PubSub+ Event Broker is up and
running. Create only if it does not exist\nif [[ ! -e ${INITIAL_STARTUP_FILE}
]]; then\n echo \"PubSub+ Event Broker initial startup completed on `date`\"
> ${INITIAL_STARTUP_FILE}\nfi\nexit 0"
kind: ConfigMap
metadata:
annotations:
meta.helm.sh/release-name: my-release
meta.helm.sh/release-namespace: default
creationTimestamp: "2024-07-12T19:32:43Z"
labels:
app.kubernetes.io/instance: my-release
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: pubsubplus
helm.sh/chart: pubsubplus-3.3.3
name: my-release-pubsubplus
namespace: default
resourceVersion: "644"
uid: d959cc36-34fd-4df7-8c79-409c4cc24f8d
kind: List
metadata:
resourceVersion: ""
fsultan@Fahds-iMac ~ % kubectl get configmap my-release-pubsubplus -o yaml
apiVersion: v1
data:
init.sh: |-
export username_admin_passwordfilepath="/mnt/disks/secrets/username_admin_password"
export username_admin_globalaccesslevel=admin
export service_ssh_port='2222'
export service_webtransport_port='8008'
export service_webtransport_tlsport='1443'
export service_semp_tlsport='1943'
export logging_debug_output=all
export system_scaling_maxconnectioncount="100"
# Deal with the fact we cannot accept "-" in router names
export routername=$(echo $(hostname) | sed 's/-//g')
readiness_check.sh: |-
#!/bin/bash
APP=`basename "$0"`
LOG_FILE=/usr/sw/var/k8s_readiness_check.log # STDOUT/STDERR goes to k8s event logs but gets cleaned out eventually. This will also persist it.
if [ -f ${LOG_FILE} ] ; then
tail -n 1000 ${LOG_FILE} > ${LOG_FILE}.tmp; mv -f ${LOG_FILE}.tmp ${LOG_FILE} || : # Limit logs size
fi
exec > >(tee -a ${LOG_FILE}) 2>&1 # Setup logging
FINAL_ACTIVITY_LOGGED_TRACKING_FILE=/tmp/final_activity_state_logged
# Function to read Kubernetes metadata labels
get_label () {
# Params: $1 label name
echo $(cat /etc/podinfo/labels | awk -F= '$1=="'${1}'"{print $2}' | xargs);
}
# Function to set Kubernetes metadata labels
set_label () {
# Params: $1 label name, $2 label set value
#Prevent overdriving Kubernetes infra, don't set activity state to same as previous state
previous_state=$(get_label "active")
if [ "${2}" = "${previous_state}" ]; then
#echo "`date` INFO: ${APP}-Current and Previous state match (${2}), not updating pod label"
:
else
echo "`date` INFO: ${APP}-Updating pod label using K8s API from ${previous_state} to ${2}"
echo "[{\"op\": \"add\", \"path\": \"/metadata/labels/${1}\", \"value\": \"${2}\" }]" > /tmp/patch_label.json
K8S=https://kubernetes.default.svc.cluster.local:$KUBERNETES_SERVICE_PORT
KUBE_TOKEN=$(</var/run/secrets/kubernetes.io/serviceaccount/token)
CACERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
NAMESPACE=$(</var/run/secrets/kubernetes.io/serviceaccount/namespace)
if ! curl -sS --output /dev/null --cacert $CACERT --connect-timeout 5 \
--request PATCH --data "$(cat /tmp/patch_label.json)" \
-H "Authorization: Bearer $KUBE_TOKEN" -H "Content-Type:application/json-patch+json" \
$K8S/api/v1/namespaces/$NAMESPACE/pods/$HOSTNAME ; then
# Label update didn't work this way, fall back to alternative legacy method to update label
if ! curl -sSk --output /dev/null -H "Authorization: Bearer $KUBE_TOKEN" --request PATCH --data "$(cat /tmp/patch_label.json)" \
-H "Content-Type:application/json-patch+json" \
https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_PORT_443_TCP_PORT/api/v1/namespaces/$STATEFULSET_NAMESPACE/pods/$HOSTNAME ; then
echo "`date` ERROR: ${APP}-Unable to update pod label, check access from pod to K8s API or RBAC authorization" >&2
rm -f ${FINAL_ACTIVITY_LOGGED_TRACKING_FILE}; exit 1
fi
fi
fi
}
# Function to get remote sync state
get_router_remote_config_state() {
# Params: $1 is property of config to return for router
routerresults=`/mnt/disks/solace/semp_query.sh -n admin -p ${password} -u http://localhost:8080 \
-q "<rpc><show><config-sync><database/><router/><remote/></config-sync></show></rpc>" \
-v "/rpc-reply/rpc/show/config-sync/database/remote/tables/table[1]/source-router/${1}"`
routerremotesync_result=`echo ${routerresults} | xmllint -xpath "string(returnInfo/valueSearchResult)" -`
echo $routerremotesync_result
}
# Main logic: note that there are no re-tries here, if check fails then return not ready.
# nonHA config
health_result=`curl -s -o /dev/null -w "%{http_code}" http://localhost:5550/health-check/guaranteed-active`
case "${health_result}" in
"200")
if [ ! -f ${FINAL_ACTIVITY_LOGGED_TRACKING_FILE} ]; then
echo "`date` INFO: ${APP}-nonHA Event Broker health check reported 200, message spool is up"
touch ${FINAL_ACTIVITY_LOGGED_TRACKING_FILE}
echo "`date` INFO: ${APP}-Server status check complete for this broker node"
echo "`date` INFO: ${APP}-Changing pod label to active"
exit 1
fi
set_label "active" "true"
exit 0
;;
"503")
if [[ $(get_label "active") = "true" ]]; then echo "`date` INFO: ${APP}-nonHA Event Broker health check reported 503, message spool is down"; fi
set_label "active" "false"
echo "`date` INFO: ${APP}-Changing pod label to inactive"
# Fail readiness check
rm -f ${FINAL_ACTIVITY_LOGGED_TRACKING_FILE}; exit 1
;;
*)
echo "`date` WARN: ${APP}-nonHA Event Broker health check reported ${health_result}"
set_label "active" "false"
echo "`date` INFO: ${APP}-Changing pod label to inactive"
# Fail readiness check
rm -f ${FINAL_ACTIVITY_LOGGED_TRACKING_FILE}; exit 1
esac
semp_query.sh: |-
#!/bin/bash
APP=`basename "$0"`
OPTIND=1 # Reset in case getopts has been used previously in the shell.
# Initialize our own variables:
count_search=""
name=""
password=""
query=""
url=""
value_search=""
test_connection_only=false
script_name=$0
verbose=0
while getopts "c:n:p:q:u:v:t" opt; do
case "$opt" in
c) count_search=$OPTARG
;;
n) username=$OPTARG
;;
p) password=$OPTARG
;;
q) query=$OPTARG
;;
u) url=$OPTARG
;;
v) value_search=$OPTARG
;;
t) test_connection_only=true
;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
verbose=1
#echo "`date` INFO: ${APP}-${script_name}: count_search=${count_search} ,username=${username} ,password=xxx query=${query} \
# ,url=${url} ,value_search=${value_search} ,Leftovers: $@" >&2
if [[ ${url} = "" || ${username} = "" || ${password} = "" ]]; then
echo "`date` ERROR: ${APP}-${script_name}: url, username, password are madatory fields" >&2
echo '<returnInfo><errorInfo>missing parameter</errorInfo></returnInfo>'
exit 1
fi
if [ "`curl --write-out '%{http_code}' --silent --output /dev/null -u ${username}:${password} ${url}/SEMP -d '<rpc><show><version/></show></rpc>'`" != "200" ] ; then
echo "<returnInfo><errorInfo>management host is not responding</errorInfo></returnInfo>"
exit 1
fi
if [ "$test_connection_only" = true ] ; then
exit 0 # done here, connection is up
fi
query_response=`curl -sS -u ${username}:${password} ${url}/SEMP -d "${query}"`
# Validate first char of response is "<", otherwise no hope of being valid xml
if [[ ${query_response:0:1} != "<" ]] ; then
echo "<returnInfo><errorInfo>no valid xml returned</errorInfo></returnInfo>"
exit 1
fi
query_response_code=`echo $query_response | xmllint -xpath 'string(/rpc-reply/execute-result/@code)' -`
if [[ -z ${query_response_code} && ${query_response_code} != "ok" ]]; then
echo "<returnInfo><errorInfo>query failed -${query_response_code}-</errorInfo></returnInfo>"
exit 1
fi
#echo "`date` INFO: ${APP}-${script_name}: query passed ${query_response_code}" >&2
if [[ ! -z $value_search ]]; then
value_result=`echo $query_response | xmllint -xpath "string($value_search)" -`
echo "<returnInfo><errorInfo></errorInfo><valueSearchResult>${value_result}</valueSearchResult></returnInfo>"
exit 0
fi
if [[ ! -z $count_search ]]; then
count_line=`echo $query_response | xmllint -xpath "$count_search" -`
count_string=`echo $count_search | cut -d '"' -f 2`
count_result=`echo ${count_line} | tr "><" "\n" | grep -c ${count_string}`
echo "<returnInfo><errorInfo></errorInfo><countSearchResult>${count_result}</countSearchResult></returnInfo>"
exit 0
fi
startup-broker.sh: "#!/bin/bash\nAPP=`basename \"$0\"`\nIFS='-' read -ra host_array
<<< $(hostname)\nnode_ordinal=${host_array[-1]}\necho \"`date` INFO: ${APP}-Node
ordinal: ${node_ordinal}\"\necho \"`date` INFO: ${APP}-Waiting for management
API to become available\"\npassword=`cat /mnt/disks/secrets/username_admin_password`\nINITIAL_STARTUP_FILE=/var/lib/solace/var/k8s_initial_startup_marker\nloop_guard=60\npause=10\ncount=0\n#
Wait for Solace Management API\nwhile [ ${count} -lt ${loop_guard} ]; do \n if
/mnt/disks/solace/semp_query.sh -n admin -p ${password} -u http://localhost:8080
-t ; then\n break\n fi\n run_time=$((${count} * ${pause}))\n ((count++))\n
\ echo \"`date` INFO: ${APP}-Waited ${run_time} seconds, Management API not yet
accessible\"\n sleep ${pause}\ndone\nif [ ${count} -eq ${loop_guard} ]; then\n
\ echo \"`date` ERROR: ${APP}-Solace Management API never came up\" >&2\n exit
1 \nfi\necho \"`date` INFO: ${APP}-PubSub+ Event Broker bringup is complete for
this node.\"\n# create startup file after PubSub+ Event Broker is up and running.
\ Create only if it does not exist\nif [[ ! -e ${INITIAL_STARTUP_FILE} ]]; then\n
\ echo \"PubSub+ Event Broker initial startup completed on `date`\" > ${INITIAL_STARTUP_FILE}\nfi\nexit
0"
kind: ConfigMap
metadata:
annotations:
meta.helm.sh/release-name: my-release
meta.helm.sh/release-namespace: default
creationTimestamp: "2024-07-12T19:32:43Z"
labels:
app.kubernetes.io/instance: my-release
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: pubsubplus
helm.sh/chart: pubsubplus-3.3.3
name: my-release-pubsubplus
namespace: default
resourceVersion: "644"
uid: d959cc36-34fd-4df7-8c79-409c4cc24f8d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment