...
1#!/usr/bin/env bash
2
3# Copyright 2016 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# Script to fetch latest openapi spec.
18# Puts the updated spec at api/openapi-spec/
19
20set -o errexit
21set -o nounset
22set -o pipefail
23
24KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
25DISCOVERY_ROOT_DIR="${KUBE_ROOT}/api/discovery"
26OPENAPI_ROOT_DIR="${KUBE_ROOT}/api/openapi-spec"
27source "${KUBE_ROOT}/hack/lib/init.sh"
28
29kube::util::require-jq
30kube::golang::setup_env
31kube::etcd::install
32
33# We need to call `make` here because that includes all of the compile and link
34# flags that we use for a production build, which we need for this script.
35make -C "${KUBE_ROOT}" WHAT=cmd/kube-apiserver
36
37function cleanup()
38{
39 if [[ -n ${APISERVER_PID-} ]]; then
40 kill "${APISERVER_PID}" 1>&2 2>/dev/null
41 wait "${APISERVER_PID}" || true
42 fi
43 unset APISERVER_PID
44
45 kube::etcd::cleanup
46
47 kube::log::status "Clean up complete"
48}
49
50trap cleanup EXIT SIGINT
51
52TMP_DIR=${TMP_DIR:-$(kube::realpath "$(mktemp -d -t "$(basename "$0").XXXXXX")")}
53ETCD_HOST=${ETCD_HOST:-127.0.0.1}
54ETCD_PORT=${ETCD_PORT:-2379}
55API_PORT=${API_PORT:-8050}
56API_HOST=${API_HOST:-127.0.0.1}
57API_LOGFILE=${API_LOGFILE:-${TMP_DIR}/openapi-api-server.log}
58
59kube::etcd::start
60
61echo "dummy_token,admin,admin" > "${TMP_DIR}/tokenauth.csv"
62
63# setup envs for TokenRequest required flags
64SERVICE_ACCOUNT_LOOKUP=${SERVICE_ACCOUNT_LOOKUP:-true}
65SERVICE_ACCOUNT_KEY=${SERVICE_ACCOUNT_KEY:-${TMP_DIR}/kube-serviceaccount.key}
66# Generate ServiceAccount key if needed
67if [[ ! -f "${SERVICE_ACCOUNT_KEY}" ]]; then
68 mkdir -p "$(dirname "${SERVICE_ACCOUNT_KEY}")"
69 openssl genrsa -out "${SERVICE_ACCOUNT_KEY}" 2048 2>/dev/null
70fi
71
72# Start kube-apiserver
73# omit enums from static openapi snapshots used to generate clients until #109177 is resolved
74# TODO(aojea) remove ConsistentListFromCache after https://issues.k8s.io/123674
75kube::log::status "Starting kube-apiserver"
76kube-apiserver \
77 --bind-address="${API_HOST}" \
78 --secure-port="${API_PORT}" \
79 --etcd-servers="http://${ETCD_HOST}:${ETCD_PORT}" \
80 --advertise-address="10.10.10.10" \
81 --cert-dir="${TMP_DIR}/certs" \
82 --feature-gates=AllAlpha=true,OpenAPIEnums=false,ConsistentListFromCache=false \
83 --runtime-config="api/all=true" \
84 --token-auth-file="${TMP_DIR}/tokenauth.csv" \
85 --authorization-mode=RBAC \
86 --service-account-key-file="${SERVICE_ACCOUNT_KEY}" \
87 --service-account-lookup="${SERVICE_ACCOUNT_LOOKUP}" \
88 --service-account-issuer="https://kubernetes.default.svc" \
89 --service-account-signing-key-file="${SERVICE_ACCOUNT_KEY}" \
90 --v=2 \
91 --service-cluster-ip-range="10.0.0.0/24" >"${API_LOGFILE}" 2>&1 &
92APISERVER_PID=$!
93
94if ! kube::util::wait_for_url "https://${API_HOST}:${API_PORT}/healthz" "apiserver: "; then
95 kube::log::error "Here are the last 10 lines from kube-apiserver (${API_LOGFILE})"
96 kube::log::error "=== BEGIN OF LOG ==="
97 tail -10 "${API_LOGFILE}" >&2 || :
98 kube::log::error "=== END OF LOG ==="
99 exit 1
100fi
101
102kube::log::status "Updating aggregated discovery"
103
104rm -fr "${DISCOVERY_ROOT_DIR}"
105mkdir -p "${DISCOVERY_ROOT_DIR}"
106curl -kfsS -H 'Authorization: Bearer dummy_token' -H 'Accept: application/json;g=apidiscovery.k8s.io;v=v2beta1;as=APIGroupDiscoveryList' "https://${API_HOST}:${API_PORT}/apis" | jq -S . > "${DISCOVERY_ROOT_DIR}/aggregated_v2beta1.json"
107
108kube::log::status "Updating " "${OPENAPI_ROOT_DIR} for OpenAPI v2"
109
110rm -f "${OPENAPI_ROOT_DIR}/swagger.json"
111curl -w "\n" -kfsS -H 'Authorization: Bearer dummy_token' \
112 "https://${API_HOST}:${API_PORT}/openapi/v2" \
113 | jq -S '.info.version="unversioned"' \
114 > "${OPENAPI_ROOT_DIR}/swagger.json"
115
116kube::log::status "Updating " "${OPENAPI_ROOT_DIR}/v3 for OpenAPI v3"
117
118mkdir -p "${OPENAPI_ROOT_DIR}/v3"
119# clean up folder, note that some files start with dot like
120# ".well-known__openid-configuration_openapi.json"
121rm -r "${OPENAPI_ROOT_DIR}"/v3/{*,.*} || true
122
123rm -rf "${OPENAPI_ROOT_DIR}/v3/*"
124curl -w "\n" -kfsS -H 'Authorization: Bearer dummy_token' \
125 "https://${API_HOST}:${API_PORT}/openapi/v3" \
126 | jq -r '.paths | to_entries | .[].key' \
127 | while read -r group; do
128 kube::log::status "Updating OpenAPI spec and discovery for group ${group}"
129 OPENAPI_FILENAME="${group}_openapi.json"
130 OPENAPI_FILENAME_ESCAPED="${OPENAPI_FILENAME//\//__}"
131 OPENAPI_PATH="${OPENAPI_ROOT_DIR}/v3/${OPENAPI_FILENAME_ESCAPED}"
132 curl -w "\n" -kfsS -H 'Authorization: Bearer dummy_token' \
133 "https://${API_HOST}:${API_PORT}/openapi/v3/{$group}" \
134 | jq -S '.info.version="unversioned"' \
135 > "$OPENAPI_PATH"
136
137 if [[ "${group}" == "api"* ]]; then
138 DISCOVERY_FILENAME="${group}.json"
139 DISCOVERY_FILENAME_ESCAPED="${DISCOVERY_FILENAME//\//__}"
140 DISCOVERY_PATH="${DISCOVERY_ROOT_DIR}/${DISCOVERY_FILENAME_ESCAPED}"
141 curl -kfsS -H 'Authorization: Bearer dummy_token' "https://${API_HOST}:${API_PORT}/{$group}" | jq -S . > "$DISCOVERY_PATH"
142 fi
143done
144
145kube::log::status "SUCCESS"
146
147# ex: ts=2 sw=2 et filetype=sh
View as plain text