-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathsupport.sh
executable file
·169 lines (148 loc) · 8.17 KB
/
support.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/bin/bash
# Script intended to capture any relevant logs and support information for on-premise deployment.
OUTPUT_DIR=${OUTPUT_DIR:-$(mktemp -d)}
TAR_NAME=${TAR_NAME:-/tmp/calyptia-support-$HOSTNAME-$(date -u +"%Y-%m-%dT%H-%M-%SZ").tgz}
# Set this to a token to use for working with the Calyptia configuration
CALYPTIA_CLOUD_TOKEN=${CALYPTIA_CLOUD_TOKEN:-}
# Set this to the location of the cloud-api endpoint to use
CALYPTIA_CLOUD_URL=${CALYPTIA_CLOUD_URL:-}
# Finds a random, unused port on the system and echos it.
# Returns 1 and echos -1 if it can't find one.
function find_unused_port() {
local portnum
while true; do
portnum=$(shuf -i 1025-65535 -n 1)
if ! lsof -Pi ":$portnum" -sTCP:LISTEN; then
echo "$portnum"
return 0
fi
done
echo -1
return 1
}
echo "Running support script: $(date -u +"%Y-%m-%dT%H:%M:%SZ") $*"
if ! command -v kubectl &> /dev/null; then
echo "ERROR: Missing kubectl"
exit 1
fi
echo "Output stored here (add extra information beforehand to be tarred up): $OUTPUT_DIR"
# Ensure we have the directory
mkdir -p "$OUTPUT_DIR"
\kubectl get nodes -o yaml > "$OUTPUT_DIR"/kubectl-nodes.yaml
\kubectl get pods --all-namespaces -o yaml > "$OUTPUT_DIR"/kubectl-all-pods.yaml
\kubectl describe all --all-namespaces > "$OUTPUT_DIR"/kubectl-all.log
\kubectl get -o yaml crd > "$OUTPUT_DIR"/kubectl-crds.yaml
mkdir -p "$OUTPUT_DIR"/cluster
\kubectl cluster-info dump --all-namespaces -o yaml --output-directory="$OUTPUT_DIR"/cluster
# Grab stuff not returned by `get all`
for namespace in $(\kubectl get namespaces --output=jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')
do
# Get YAML for everything in the namespace
for resource_type in $(\kubectl api-resources --namespaced --verbs=list -o name | tr "\n" " ");
do
mkdir -p "${OUTPUT_DIR}/namespaces/${namespace}"
\kubectl get -n "$namespace" "$resource_type" --show-kind --ignore-not-found -o yaml > "${OUTPUT_DIR}/namespaces/${namespace}"/"$resource_type".yaml
done
# Attempt to discover token and url for cloud-api in cluster
if [[ -z "$CALYPTIA_CLOUD_TOKEN" ]]; then
if \kubectl get --namespace "$namespace" secret auth-secret &>/dev/null; then
CALYPTIA_CLOUD_TOKEN=$(kubectl get --namespace "$namespace" secret auth-secret -o jsonpath='{.data.token}'| base64 --decode)
export CALYPTIA_CLOUD_TOKEN
if [[ -z "$CALYPTIA_CLOUD_TOKEN" ]]; then
# Use the old approach
CALYPTIA_CLOUD_TOKEN=$(kubectl get --namespace "$namespace" secret auth-secret -o jsonpath='{.data.ONPREM_CLOUD_API_PROJECT_TOKEN}'| base64 --decode)
export CALYPTIA_CLOUD_TOKEN
fi
# Detain the token for comparison in the pod specs
echo -n "$CALYPTIA_CLOUD_TOKEN" > "${OUTPUT_DIR}"/token.txt
fi
fi
if [[ -z "$CALYPTIA_CLOUD_URL" ]]; then
if \kubectl get --namespace "$namespace" svc -l 'app.kubernetes.io/component=cloud-api' | grep -qv "No resources found"; then
if [[ $(\kubectl get --namespace "$namespace" svc -l 'app.kubernetes.io/component=cloud-api' -o=jsonpath='{.items..spec.type}') == 'LoadBalancer' ]]; then
service_lb_ip=$(kubectl get -n "$namespace" svc -l 'app.kubernetes.io/component=cloud-api' -o=jsonpath='{.items..status.loadBalancer.ingress[0].ip}')
if [[ -z "$service_lb_ip" ]]; then
service_lb_ip=$(kubectl get -n "$namespace" svc -l 'app.kubernetes.io/component=cloud-api' -o=jsonpath='{.items..status.loadBalancer.ingress[0].hostname}')
fi
service_lb_port=$(kubectl get -n "$namespace" svc -l 'app.kubernetes.io/component=cloud-api' -o=jsonpath='{.items..spec.ports[0].port}')
CALYPTIA_CLOUD_URL="http://${service_lb_ip}:${service_lb_port}"
export CALYPTIA_CLOUD_URL
else
# port-forwarding required
local_port=$(find_unused_port)
if [[ "$local_port" != '-1' ]]; then
\kubectl port-forward --namespace "$namespace" \
svc/"$(\kubectl get --namespace "$namespace" svc -l 'app.kubernetes.io/component=cloud-api' -o=jsonpath='{.items..metadata.name}')" \
"$local_port:5000" &
export PF_PID=$!
export CALYPTIA_CLOUD_URL="http://127.0.0.1:$local_port"
fi
fi
fi
fi
done
# Grab all images used in the cluster: https://kubernetes.io/docs/tasks/access-application-cluster/list-all-running-container-images/
\kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" |\
tr -s '[:space:]' '\n' |\
sort |\
uniq -c &> "$OUTPUT_DIR"/kubectl-all-images.log
for namespace in $(\kubectl get namespaces --output=jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')
do
# Finally grab extra logs for failing pods
for pod in $(\kubectl get pods --field-selector=status.phase!=Running,status.phase!=Succeeded --namespace "$namespace" --output=jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')
do
pod_output_dir="${OUTPUT_DIR}/failing/${namespace}"/"${pod}"
mkdir -p "$pod_output_dir"
# Dump pod spec
\kubectl describe --namespace "$namespace" pod "$pod" > "$pod_output_dir"/spec.yaml
# Get previous logs
\kubectl logs --namespace "$namespace" --previous "$pod" &> "$pod_output_dir"/previous.log
# Get current logs just in case there is a race
\kubectl logs --namespace "$namespace" "$pod" &> "$pod_output_dir"/current.log
done
done
# Attempt to dump some Calyptia configuration details using the URL and token provided
if command -v calyptia &> /dev/null && [[ -n "$CALYPTIA_CLOUD_URL" ]] && [[ -n "$CALYPTIA_CLOUD_TOKEN" ]]; then
for core in $(calyptia --token "$CALYPTIA_CLOUD_TOKEN" --cloud-url "$CALYPTIA_CLOUD_URL" get core_instances -o json | jq -r '.[].id')
do
for pipeline in $(calyptia get pipelines "$CALYPTIA_CLOUD_TOKEN" --cloud-url "$CALYPTIA_CLOUD_URL" --core-instance "$core" -o json | jq -r '.[].id')
do
mkdir -p "$OUTPUT_DIR/instances/${core}/${pipeline}"
\curl -H "Authorization: Bearer ${CALYPTIA_CLOUD_TOKEN}" -sSfL "${CALYPTIA_CLOUD_URL}/v1/pipelines/${pipeline}/metadata" &> "$OUTPUT_DIR/instances/${core}/${pipeline}"/metadata.json
done
done
else
echo "Unable to extract any Calyptia instance configuration details, ensure Calyptia CLI is installed and CALYPTIA_CLOUD_URL/CALYPTIA_CLOUD_TOKEN are set."
fi
# Kill any port-forwarding without output
[[ -n "${PF_PID:-}" ]] && kill -9 "$PF_PID" && wait "$PF_PID" 2>/dev/null
# Grab any helm values directly
if command -v jq && command -v gunzip && command -v base64; then
for helm_json in $(kubectl get secrets -A -l owner=helm -o json | jq -c .items[])
do
helm_name=$(echo "$helm_json" | jq '.metadata.name')
mkdir -p "$OUTPUT_DIR/helm/$helm_name"
# Extract the template and values used
echo "$helm_json" | jq -r '.data.release' | base64 -d | base64 -d | gunzip -c - | jq -c '.' &> "$OUTPUT_DIR/helm/$helm_name"/all.json
jq '.config' "$OUTPUT_DIR/helm/$helm_name"/all.json &> "$OUTPUT_DIR/helm/$helm_name"/values.json
jq -r '.chart.templates[].data' "$OUTPUT_DIR/helm/$helm_name"/all.json | base64 -d &> "$OUTPUT_DIR/helm/$helm_name"/template.yaml
done
else
echo "Unable to extract helm values as missing jq, gunzip or base64 commands"
fi
# Grab any K3S logs for on-prem deployment
journalctl -q -u k3s &> "$OUTPUT_DIR"/k3s-service.log
# Check for systemctl and scrape systemctl units if available
if command -v systemctl &> /dev/null; then
echo "Scraping systemctl units..."
systemctl list-units --all --type=service --no-pager &> "$OUTPUT_DIR/systemctl-all-units.log"
echo "Systemctl units scraped."
else
echo "Systemctl not found, skipping systemctl units scrape."
fi
# Create a tarball for simple upload
echo "Creating tarball: $TAR_NAME"
tar -czf "$TAR_NAME" -C "$OUTPUT_DIR" .
chmod a+r "$TAR_NAME"
echo "Support script complete: $TAR_NAME"
echo "Please verify all content is acceptable to share - including secrets - and remove anything sensitive."