Skip to content

Commit 7c6e3be

Browse files
authored
Merge pull request #302 from kubernetes-sigs/cleanup-ag
hack/cleanup-ag: spurious affinity group cleaner
2 parents 58fad9f + 1fa2dba commit 7c6e3be

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed

hack/cleanup-affinity-groups.sh

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Copyright 2023 The Kubernetes Authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
# Requires: jq, kubectl, cmk (get https://github.com/apache/cloudstack-cloudmonkey/releases/tag/6.4.0-rc1 or later)
18+
#
19+
# About: this tool helps to remove CloudStack affinity groups from CAPC
20+
# management cluster which are not assigned to any instances.
21+
#
22+
# Usage and help:
23+
# chmod +x cleanup-affinity-groups.sh
24+
# ./cleanup-affinity-groups.sh -h
25+
26+
set -o errexit
27+
set -o nounset
28+
set -o pipefail
29+
30+
# script params
31+
DRY_RUN=false
32+
VERBOSE=false
33+
34+
# k8s params
35+
NAMESPACE=default
36+
KUBECONFIG=$HOME/.kube/config
37+
38+
# cmk params
39+
CS_URL=
40+
CS_APIKEY=
41+
CS_SECRETKEY=
42+
43+
debug() {
44+
if [[ "$VERBOSE" == "true" ]]; then
45+
echo -e "[debug] $@"
46+
fi
47+
}
48+
49+
_kubectl() {
50+
KUBECONFIG=$KUBECONFIG kubectl -n $NAMESPACE -o json $@
51+
}
52+
53+
_cmk() {
54+
cmk -u $CS_URL -k $CS_APIKEY -s $CS_SECRETKEY -o json $@
55+
}
56+
57+
get_affinity_groups() {
58+
_kubectl get cloudstackaffinitygroups | jq -r '.items[].metadata.name'
59+
}
60+
61+
get_cluster() {
62+
local affinitygroup=$1
63+
_kubectl get cloudstackaffinitygroup $affinitygroup | jq -r '.metadata.labels."cluster.x-k8s.io/cluster-name"'
64+
}
65+
66+
get_cluster_credentials() {
67+
local cluster=$1
68+
_kubectl get cloudstackcluster $cluster | jq -r '.spec.failureDomains[].acsEndpoint.name' | uniq
69+
}
70+
71+
setup_acs_credentials() {
72+
local credential=$1
73+
CS_URL=$(_kubectl get secret $credential | jq -r '.data."api-url"' | base64 -D)
74+
CS_APIKEY=$(_kubectl get secret $credential | jq -r '.data."api-key"' | base64 -D)
75+
CS_SECRETKEY=$(_kubectl get secret $credential | jq -r '.data."secret-key"' | base64 -D)
76+
debug "Using CloudStack Control Plane URL: $CS_URL and CloudStack Account: $(_cmk list users | jq -r '.user[] | .account + " and User: " + .username')"
77+
}
78+
79+
main() {
80+
local ags=$(get_affinity_groups)
81+
debug "Affinity groups in the namespace $NAMESPACE:\n$ags"
82+
for ag in $ags; do
83+
echo -e "\033[0;32m[info]\033[0m Checking CloudStack Affinity Group: $ag"
84+
local cluster=$(get_cluster $ag)
85+
for credential in $(get_cluster_credentials $cluster); do
86+
setup_acs_credentials $credential
87+
local ag_uuid=$(_kubectl get cloudstackaffinitygroup $ag | jq -r '.spec.id')
88+
local ag_instances=$(_cmk list affinitygroups id=$ag_uuid | jq -r '.affinitygroup[0].virtualmachineIds')
89+
if [[ "$ag_instances" == "null" ]]; then
90+
echo -e "\033[0;35m[info]\033[0m Found Affinity Group ($ag_uuid) with no instances assigned: $ag"
91+
if [[ "$DRY_RUN" == "false" ]]; then
92+
kubectl -n $NAMESPACE delete cloudstackaffinitygroup $ag
93+
echo -e "\033[0;31m[info]\033[0m Affinity Group ($ag_uuid) $ag has been removed"
94+
else
95+
echo -e "\033[0;35m[info]\033[0m [dryrun] Affinity Group ($ag_uuid) $ag has been removed"
96+
fi
97+
fi
98+
done
99+
done
100+
}
101+
102+
help() {
103+
echo "Usage: $0 [-d|k|h|v]"
104+
echo
105+
echo "This cleanup tool helps to remove CloudStack affinity groups from CAPC"
106+
echo "management cluster which are not assigned to any instances, which may"
107+
echo "have been created as a side effect of other operations. This tool checks"
108+
echo "all the cloudstackaffinitygroups using its CloudStack cluster specific"
109+
echo "credential(s) and uses cmk to check if the affinity group have no"
110+
echo "instances assigned. In dry-run, it outputs such affinity groups"
111+
echo "otherwise it deletes them."
112+
echo
113+
echo "Options:"
114+
echo "-d Runs the tools in dry-run mode"
115+
echo "-k Pass custom kube config, default: \$HOME/.kube/config"
116+
echo "-n Kubernetes namespace, default: default"
117+
echo "-h Print this help"
118+
echo "-v Verbose mode"
119+
echo
120+
}
121+
122+
while getopts ":dk:vn:h" option; do
123+
case $option in
124+
d)
125+
DRY_RUN=true;;
126+
k)
127+
KUBECONFIG=$OPTARG;;
128+
v)
129+
VERBOSE=true;;
130+
n)
131+
NAMESPACE=$OPTARG;;
132+
h)
133+
help
134+
exit;;
135+
\?)
136+
echo "Error: Invalid option provided, please see help docs"
137+
help
138+
exit;;
139+
esac
140+
done
141+
142+
if ! command -v jq &> /dev/null
143+
then
144+
echo "[error] jq could not be found, please install first"
145+
exit 1
146+
fi
147+
148+
if ! command -v kubectl &> /dev/null
149+
then
150+
echo "[error] kubectl could not be found, please install first"
151+
exit 1
152+
fi
153+
154+
if ! command -v cmk &> /dev/null
155+
then
156+
echo "[error] cmk could not be found, please install https://github.com/apache/cloudstack-cloudmonkey/releases/tag/6.4.0-rc1 or newer"
157+
exit 1
158+
fi
159+
160+
debug "[options] DRY_RUN=$DRY_RUN"
161+
debug "[options] VERBOSE=$VERBOSE"
162+
debug "[options] NAMESPACE=$NAMESPACE"
163+
debug "[options] KUBECONFIG=$KUBECONFIG"
164+
main

0 commit comments

Comments
 (0)