mirror of https://github.com/k3s-io/k3s
Generate and verify openapi specs in source tree at api/openapi-spec
parent
15fbbacc33
commit
35b5174bf1
|
@ -100,5 +100,6 @@ done
|
||||||
${KUBE_ROOT}/hack/update-munge-docs.sh
|
${KUBE_ROOT}/hack/update-munge-docs.sh
|
||||||
${KUBE_ROOT}/hack/update-generated-swagger-docs.sh
|
${KUBE_ROOT}/hack/update-generated-swagger-docs.sh
|
||||||
${KUBE_ROOT}/hack/update-swagger-spec.sh
|
${KUBE_ROOT}/hack/update-swagger-spec.sh
|
||||||
|
${KUBE_ROOT}/hack/update-openapi-spec.sh
|
||||||
${KUBE_ROOT}/hack/update-generated-protobuf.sh
|
${KUBE_ROOT}/hack/update-generated-protobuf.sh
|
||||||
./hack/update-api-reference-docs.sh
|
./hack/update-api-reference-docs.sh
|
||||||
|
|
|
@ -590,10 +590,11 @@ out. Put `grep` or `ack` to good use.
|
||||||
If you added functionality, you should consider documenting it and/or writing
|
If you added functionality, you should consider documenting it and/or writing
|
||||||
an example to illustrate your change.
|
an example to illustrate your change.
|
||||||
|
|
||||||
Make sure you update the swagger API spec by running:
|
Make sure you update the swagger and OpenAPI spec by running:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
hack/update-swagger-spec.sh
|
hack/update-swagger-spec.sh
|
||||||
|
hack/update-openapi-spec.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
The API spec changes should be in a commit separate from your other changes.
|
The API spec changes should be in a commit separate from your other changes.
|
||||||
|
|
|
@ -387,6 +387,59 @@ kube::util::fetch-swagger-spec() {
|
||||||
curl -w "\n" -fs "${SWAGGER_API_PATH}logs" > "${SWAGGER_ROOT_DIR}/logs.json"
|
curl -w "\n" -fs "${SWAGGER_API_PATH}logs" > "${SWAGGER_ROOT_DIR}/logs.json"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Takes a group/version and returns the openapi-spec file name.
|
||||||
|
# default behavior: extensions/v1beta1 -> v1beta1.extensions
|
||||||
|
# special case for v1: v1 -> v1
|
||||||
|
kube::util::gv-to-openapi-name() {
|
||||||
|
local group_version="$1"
|
||||||
|
case "${group_version}" in
|
||||||
|
v1)
|
||||||
|
echo "v1"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "${group_version#*/}.${group_version%/*}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Fetches openapi spec from apiserver.
|
||||||
|
# Assumed vars:
|
||||||
|
# OPENAPI_API_PATH: Base path for openapi on apiserver. normally APIServer root. i.e., http://localhost:8080/
|
||||||
|
# OPENAPI_ROOT_DIR: Root dir where we want to to save the fetched spec.
|
||||||
|
# VERSIONS: Array of group versions to include in swagger spec.
|
||||||
|
kube::util::fetch-openapi-spec() {
|
||||||
|
for ver in ${VERSIONS}; do
|
||||||
|
if [[ " ${KUBE_NONSERVER_GROUP_VERSIONS} " == *" ${ver} "* ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
# fetch the openapi spec for each group version.
|
||||||
|
if [[ ${ver} == "v1" ]]; then
|
||||||
|
SUBPATH="api"
|
||||||
|
else
|
||||||
|
SUBPATH="apis"
|
||||||
|
fi
|
||||||
|
SUBPATH="${SUBPATH}/${ver}"
|
||||||
|
OPENAPI_JSON_NAME="$(kube::util::gv-to-openapi-name ${ver}).json"
|
||||||
|
curl -w "\n" -fs "${OPENAPI_PATH}${SUBPATH}/swagger.json" > "${OPENAPI_ROOT_DIR}/${OPENAPI_JSON_NAME}"
|
||||||
|
|
||||||
|
# fetch the openapi spec for the discovery mechanism at group level.
|
||||||
|
if [[ ${ver} == "v1" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
SUBPATH="apis/"${ver%/*}
|
||||||
|
OPEAN_JSON_NAME="${ver%/*}.json"
|
||||||
|
curl -w "\n" -fs "${OPENAPI_PATH}${SUBPATH}/swagger.json" > "${OPENAPI_ROOT_DIR}/${OPENAPI_JSON_NAME}"
|
||||||
|
done
|
||||||
|
|
||||||
|
# fetch openapi specs for other discovery mechanism.
|
||||||
|
curl -w "\n" -fs "${OPENAPI_PATH}swagger.json" > "${OPENAPI_ROOT_DIR}/root_swagger.json"
|
||||||
|
curl -w "\n" -fs "${OPENAPI_PATH}version/swagger.json" > "${OPENAPI_ROOT_DIR}/version.json"
|
||||||
|
curl -w "\n" -fs "${OPENAPI_PATH}api/swagger.json" > "${OPENAPI_ROOT_DIR}/api.json"
|
||||||
|
curl -w "\n" -fs "${OPENAPI_PATH}apis/swagger.json" > "${OPENAPI_ROOT_DIR}/apis.json"
|
||||||
|
curl -w "\n" -fs "${OPENAPI_PATH}logs/swagger.json" > "${OPENAPI_ROOT_DIR}/logs.json"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# Returns the name of the upstream remote repository name for the local git
|
# Returns the name of the upstream remote repository name for the local git
|
||||||
# repo, e.g. "upstream" or "origin".
|
# repo, e.g. "upstream" or "origin".
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copyright 2016 The Kubernetes Authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
# Script to fetch latest openapi spec.
|
||||||
|
# Puts the updated spec at api/openapi-spec/
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
|
||||||
|
OPENAPI_ROOT_DIR="${KUBE_ROOT}/api/openapi-spec"
|
||||||
|
source "${KUBE_ROOT}/hack/lib/init.sh"
|
||||||
|
|
||||||
|
kube::golang::setup_env
|
||||||
|
|
||||||
|
make -C "${KUBE_ROOT}" WHAT=cmd/kube-apiserver
|
||||||
|
|
||||||
|
function cleanup()
|
||||||
|
{
|
||||||
|
[[ -n ${APISERVER_PID-} ]] && kill ${APISERVER_PID} 1>&2 2>/dev/null
|
||||||
|
|
||||||
|
kube::etcd::cleanup
|
||||||
|
|
||||||
|
kube::log::status "Clean up complete"
|
||||||
|
}
|
||||||
|
|
||||||
|
trap cleanup EXIT SIGINT
|
||||||
|
|
||||||
|
kube::golang::setup_env
|
||||||
|
|
||||||
|
apiserver=$(kube::util::find-binary "kube-apiserver")
|
||||||
|
|
||||||
|
TMP_DIR=$(mktemp -d /tmp/update-openapi-spec.XXXX)
|
||||||
|
ETCD_HOST=${ETCD_HOST:-127.0.0.1}
|
||||||
|
ETCD_PORT=${ETCD_PORT:-2379}
|
||||||
|
API_PORT=${API_PORT:-8050}
|
||||||
|
API_HOST=${API_HOST:-127.0.0.1}
|
||||||
|
|
||||||
|
kube::etcd::start
|
||||||
|
|
||||||
|
# Start kube-apiserver
|
||||||
|
kube::log::status "Starting kube-apiserver"
|
||||||
|
"${KUBE_OUTPUT_HOSTBIN}/kube-apiserver" \
|
||||||
|
--insecure-bind-address="${API_HOST}" \
|
||||||
|
--bind-address="${API_HOST}" \
|
||||||
|
--insecure-port="${API_PORT}" \
|
||||||
|
--etcd-servers="http://${ETCD_HOST}:${ETCD_PORT}" \
|
||||||
|
--advertise-address="10.10.10.10" \
|
||||||
|
--cert-dir="${TMP_DIR}/certs" \
|
||||||
|
--service-cluster-ip-range="10.0.0.0/24" >/tmp/openapi-api-server.log 2>&1 &
|
||||||
|
APISERVER_PID=$!
|
||||||
|
|
||||||
|
kube::util::wait_for_url "${API_HOST}:${API_PORT}/healthz" "apiserver: "
|
||||||
|
|
||||||
|
kube::log::status "Updating " ${OPENAPI_ROOT_DIR}
|
||||||
|
|
||||||
|
OPENAPI_PATH="${API_HOST}:${API_PORT}/" OPENAPI_ROOT_DIR="${OPENAPI_ROOT_DIR}" VERSIONS="${KUBE_AVAILABLE_GROUP_VERSIONS}" KUBE_NONSERVER_GROUP_VERSIONS="${KUBE_NONSERVER_GROUP_VERSIONS}" kube::util::fetch-openapi-spec
|
||||||
|
|
||||||
|
kube::log::status "SUCCESS"
|
||||||
|
|
||||||
|
# ex: ts=2 sw=2 et filetype=sh
|
|
@ -0,0 +1,51 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copyright 2016 The Kubernetes Authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
|
||||||
|
source "${KUBE_ROOT}/hack/lib/init.sh"
|
||||||
|
|
||||||
|
kube::golang::setup_env
|
||||||
|
|
||||||
|
make -C "${KUBE_ROOT}" WHAT=cmd/kube-apiserver
|
||||||
|
|
||||||
|
apiserver=$(kube::util::find-binary "kube-apiserver")
|
||||||
|
|
||||||
|
SPECROOT="${KUBE_ROOT}/api/openapi-spec"
|
||||||
|
TMP_SPECROOT="${KUBE_ROOT}/_tmp/openapi-spec"
|
||||||
|
_tmp="${KUBE_ROOT}/_tmp"
|
||||||
|
|
||||||
|
mkdir -p "${_tmp}"
|
||||||
|
trap "rm -rf ${_tmp}" EXIT SIGINT
|
||||||
|
cp -a "${SPECROOT}" "${TMP_SPECROOT}"
|
||||||
|
|
||||||
|
"${KUBE_ROOT}/hack/update-openapi-spec.sh"
|
||||||
|
echo "diffing ${SPECROOT} against freshly generated openapi spec"
|
||||||
|
ret=0
|
||||||
|
diff -Naupr -I 'Auto generated by' "${SPECROOT}" "${TMP_SPECROOT}" || ret=$?
|
||||||
|
cp -a ${TMP_SPECROOT} "${KUBE_ROOT}/api"
|
||||||
|
if [[ $ret -eq 0 ]]
|
||||||
|
then
|
||||||
|
echo "${SPECROOT} up to date."
|
||||||
|
else
|
||||||
|
echo "${SPECROOT} is out of date. Please run hack/update-openapi-spec.sh"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ex: ts=2 sw=2 et filetype=sh
|
|
@ -158,6 +158,18 @@ else
|
||||||
fi
|
fi
|
||||||
echo "${reset}"
|
echo "${reset}"
|
||||||
|
|
||||||
|
echo -ne "Checking for openapi spec that need updating... "
|
||||||
|
if ! hack/verify-openapi-spec.sh > /dev/null; then
|
||||||
|
echo "${red}ERROR!"
|
||||||
|
echo "Openapi spec needs to be updated."
|
||||||
|
echo "To regenerate the spec, run:"
|
||||||
|
echo " hack/update-openapi-spec.sh"
|
||||||
|
exit_code=1
|
||||||
|
else
|
||||||
|
echo "${green}OK"
|
||||||
|
fi
|
||||||
|
echo "${reset}"
|
||||||
|
|
||||||
if [[ "${exit_code}" != 0 ]]; then
|
if [[ "${exit_code}" != 0 ]]; then
|
||||||
echo "${red}Aborting commit${reset}"
|
echo "${red}Aborting commit${reset}"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -42,16 +42,12 @@ func sortParameters(p []spec.Parameter) {
|
||||||
sort.Sort(byNameIn{p})
|
sort.Sort(byNameIn{p})
|
||||||
}
|
}
|
||||||
|
|
||||||
func groupRoutesByPath(routes []restful.Route) (ret map[string][]restful.Route) {
|
func groupRoutesByPath(routes []restful.Route) map[string][]restful.Route {
|
||||||
ret = make(map[string][]restful.Route)
|
pathToRoutes := make(map[string][]restful.Route)
|
||||||
for _, r := range routes {
|
for _, r := range routes {
|
||||||
route, exists := ret[r.Path]
|
pathToRoutes[r.Path] = append(pathToRoutes[r.Path], r)
|
||||||
if !exists {
|
|
||||||
route = make([]restful.Route, 0, 1)
|
|
||||||
}
|
|
||||||
ret[r.Path] = append(route, r)
|
|
||||||
}
|
}
|
||||||
return ret
|
return pathToRoutes
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapKeyFromParam(param *restful.Parameter) interface{} {
|
func mapKeyFromParam(param *restful.Parameter) interface{} {
|
||||||
|
|
Loading…
Reference in New Issue