forked from kubernetes-sigs/aws-efs-csi-driver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
kops.sh
155 lines (130 loc) · 4.85 KB
/
kops.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
#!/bin/bash
set -euo pipefail
OS_ARCH=$(go env GOOS)-amd64
BASE_DIR=$(dirname "$(realpath "${BASH_SOURCE[0]}")")
source "${BASE_DIR}"/util.sh
function kops_install() {
INSTALL_PATH=${1}
KOPS_VERSION=${2}
if [[ -e "${INSTALL_PATH}"/kops ]]; then
INSTALLED_KOPS_VERSION=$("${INSTALL_PATH}"/kops version)
if [[ "$INSTALLED_KOPS_VERSION" == *"$KOPS_VERSION"* ]]; then
echo "KOPS $INSTALLED_KOPS_VERSION already installed!"
return
fi
fi
KOPS_DOWNLOAD_URL=https://github.com/kubernetes/kops/releases/download/v${KOPS_VERSION}/kops-${OS_ARCH}
curl -L -X GET "${KOPS_DOWNLOAD_URL}" -o "${INSTALL_PATH}"/kops
chmod +x "${INSTALL_PATH}"/kops
}
function kops_create_cluster() {
CLUSTER_NAME=${1}
BIN=${2}
ZONES=${3}
NODE_COUNT=${4}
INSTANCE_TYPE=${5}
K8S_VERSION=${6}
CLUSTER_FILE=${7}
KUBECONFIG=${8}
KOPS_PATCH_FILE=${9}
KOPS_PATCH_NODE_FILE=${10}
KOPS_STATE_FILE=${11}
if kops_cluster_exists "${CLUSTER_NAME}" "${BIN}" "${KOPS_STATE_FILE}"; then
loudecho "Replacing cluster $CLUSTER_NAME with $CLUSTER_FILE"
${BIN} replace --state "${KOPS_STATE_FILE}" -f "${CLUSTER_FILE}"
else
loudecho "Creating cluster $CLUSTER_NAME with $CLUSTER_FILE (dry run)"
${BIN} create cluster --state "${KOPS_STATE_FILE}" \
--zones "${ZONES}" \
--node-count="${NODE_COUNT}" \
--node-size="${INSTANCE_TYPE}" \
--kubernetes-version="${K8S_VERSION}" \
--dry-run \
-o yaml \
"${CLUSTER_NAME}" > "${CLUSTER_FILE}"
if test -f "$KOPS_PATCH_FILE"; then
kops_patch_cluster_file "$CLUSTER_FILE" "$KOPS_PATCH_FILE" "Cluster" ""
fi
if test -f "$KOPS_PATCH_NODE_FILE"; then
kops_patch_cluster_file "$CLUSTER_FILE" "$KOPS_PATCH_NODE_FILE" "InstanceGroup" "Node"
fi
loudecho "Creating cluster $CLUSTER_NAME with $CLUSTER_FILE"
${BIN} create --state "${KOPS_STATE_FILE}" -f "${CLUSTER_FILE}"
fi
loudecho "Updating cluster $CLUSTER_NAME with $CLUSTER_FILE"
${BIN} update cluster --state "${KOPS_STATE_FILE}" "${CLUSTER_NAME}" --yes
loudecho "Exporting cluster ${CLUSTER_NAME} kubecfg to ${KUBECONFIG}"
${BIN} export kubecfg --state "${KOPS_STATE_FILE}" "${CLUSTER_NAME}" --admin --kubeconfig "${KUBECONFIG}"
loudecho "Validating cluster ${CLUSTER_NAME}"
${BIN} validate cluster --state "${KOPS_STATE_FILE}" --wait 10m --kubeconfig "${KUBECONFIG}"
return $?
}
function kops_cluster_exists() {
CLUSTER_NAME=${1}
BIN=${2}
KOPS_STATE_FILE=${3}
set +e
if ${BIN} get cluster --state "${KOPS_STATE_FILE}" "${CLUSTER_NAME}"; then
set -e
return 0
else
set -e
return 1
fi
}
function kops_delete_cluster() {
BIN=${1}
CLUSTER_NAME=${2}
KOPS_STATE_FILE=${3}
loudecho "Deleting cluster ${CLUSTER_NAME}"
${BIN} delete cluster --name "${CLUSTER_NAME}" --state "${KOPS_STATE_FILE}" --yes
}
# TODO switch this to python, work exclusively with yaml, use kops toolbox
# template/kops set?, all this hacking with jq stinks!
function kops_patch_cluster_file() {
CLUSTER_FILE=${1} # input must be yaml
KOPS_PATCH_FILE=${2} # input must be yaml
KIND=${3} # must be either Cluster or InstanceGroup
ROLE=${4} # must be either Master or Node
loudecho "Patching cluster $CLUSTER_NAME with $KOPS_PATCH_FILE"
# Temporary intermediate files for patching, don't mutate CLUSTER_FILE until
# the end
CLUSTER_FILE_JSON=$CLUSTER_FILE.json
CLUSTER_FILE_0=$CLUSTER_FILE.0
CLUSTER_FILE_1=$CLUSTER_FILE.1
# HACK convert the multiple yaml documents to an array of json objects
yaml_to_json "$CLUSTER_FILE" "$CLUSTER_FILE_JSON"
# Find the json objects to patch
FILTER=".[] | select(.kind==\"$KIND\")"
if [ -n "$ROLE" ]; then
FILTER="$FILTER | select(.spec.role==\"$ROLE\")"
fi
jq "$FILTER" "$CLUSTER_FILE_JSON" > "$CLUSTER_FILE_0"
# Patch only the json objects
kubectl patch -f "$CLUSTER_FILE_0" --local --type merge --patch "$(cat "$KOPS_PATCH_FILE")" -o json > "$CLUSTER_FILE_1"
mv "$CLUSTER_FILE_1" "$CLUSTER_FILE_0"
# Delete the original json objects, add the patched
# TODO Cluster must always be first?
jq "del($FILTER)" "$CLUSTER_FILE_JSON" | jq ". + \$patched | sort" --slurpfile patched "$CLUSTER_FILE_0" > "$CLUSTER_FILE_1"
mv "$CLUSTER_FILE_1" "$CLUSTER_FILE_0"
# HACK convert the array of json objects to multiple yaml documents
json_to_yaml "$CLUSTER_FILE_0" "$CLUSTER_FILE_1"
mv "$CLUSTER_FILE_1" "$CLUSTER_FILE_0"
# Done patching, overwrite original yaml CLUSTER_FILE
mv "$CLUSTER_FILE_0" "$CLUSTER_FILE" # output is yaml
# Clean up
rm "$CLUSTER_FILE_JSON"
}
function yaml_to_json() {
IN=${1}
OUT=${2}
kubectl patch -f "$IN" --local -p "{}" --type merge -o json | jq '.' -s > "$OUT"
}
function json_to_yaml() {
IN=${1}
OUT=${2}
for ((i = 0; i < $(jq length "$IN"); i++)); do
echo "---" >> "$OUT"
jq ".[$i]" "$IN" | kubectl patch -f - --local -p "{}" --type merge -o yaml >> "$OUT"
done
}