Generate and verify openapi specs in source tree at api/openapi-spec

pull/6/head
mbohlool 2016-09-27 23:55:45 -07:00
parent 15fbbacc33
commit 35b5174bf1
7 changed files with 198 additions and 9 deletions

View File

@ -100,5 +100,6 @@ done
${KUBE_ROOT}/hack/update-munge-docs.sh
${KUBE_ROOT}/hack/update-generated-swagger-docs.sh
${KUBE_ROOT}/hack/update-swagger-spec.sh
${KUBE_ROOT}/hack/update-openapi-spec.sh
${KUBE_ROOT}/hack/update-generated-protobuf.sh
./hack/update-api-reference-docs.sh

View File

@ -590,10 +590,11 @@ out. Put `grep` or `ack` to good use.
If you added functionality, you should consider documenting it and/or writing
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
hack/update-swagger-spec.sh
hack/update-openapi-spec.sh
```
The API spec changes should be in a commit separate from your other changes.

View File

@ -387,6 +387,59 @@ kube::util::fetch-swagger-spec() {
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
# repo, e.g. "upstream" or "origin".

75
hack/update-openapi-spec.sh Executable file
View File

@ -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

51
hack/verify-openapi-spec.sh Executable file
View File

@ -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

View File

@ -158,6 +158,18 @@ else
fi
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
echo "${red}Aborting commit${reset}"
fi

View File

@ -42,16 +42,12 @@ func sortParameters(p []spec.Parameter) {
sort.Sort(byNameIn{p})
}
func groupRoutesByPath(routes []restful.Route) (ret map[string][]restful.Route) {
ret = make(map[string][]restful.Route)
func groupRoutesByPath(routes []restful.Route) map[string][]restful.Route {
pathToRoutes := make(map[string][]restful.Route)
for _, r := range routes {
route, exists := ret[r.Path]
if !exists {
route = make([]restful.Route, 0, 1)
}
ret[r.Path] = append(route, r)
pathToRoutes[r.Path] = append(pathToRoutes[r.Path], r)
}
return ret
return pathToRoutes
}
func mapKeyFromParam(param *restful.Parameter) interface{} {