Add swagger (OpenAPI 2.0) support (#1245)
* Add swagger (OpenAPI 2.0) support * Gererate swagger_doc before building bundle image
This commit is contained in:
@@ -17,6 +17,7 @@ require (
|
||||
github.com/dsnet/compress v0.0.0-20171208185109-cc9eb1d7ad76 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/elazarl/goproxy v0.0.0-20181111060418-2ce16c963a8a // indirect
|
||||
github.com/emicklei/go-restful-openapi v1.2.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.7
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/go-sql-driver/mysql v1.4.1 // indirect
|
||||
@@ -64,7 +65,7 @@ require (
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/sirupsen/logrus v1.2.0
|
||||
github.com/spf13/pflag v1.0.1 // indirect
|
||||
github.com/stretchr/testify v1.2.2
|
||||
github.com/stretchr/testify v1.3.0
|
||||
github.com/ulikunitz/xz v0.0.0-20180703112113-636d36a76670 // indirect
|
||||
github.com/urfave/cli v1.20.0
|
||||
github.com/wcharczuk/go-chart v2.0.1+incompatible
|
||||
@@ -86,4 +87,5 @@ require (
|
||||
k8s.io/apiextensions-apiserver v0.0.0-20190116211702-f0729a5940c5
|
||||
k8s.io/apimachinery v0.0.0-20190116203031-d49e237a2683
|
||||
k8s.io/client-go v7.0.0+incompatible
|
||||
k8s.io/klog v0.3.3 // indirect
|
||||
)
|
||||
|
||||
@@ -11,6 +11,10 @@ github.com/Azure/go-autorest v9.9.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWA
|
||||
github.com/DataDog/datadog-go v0.0.0-20180822151419-281ae9f2d895/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/DataDog/zstd v1.3.5 h1:DtpNbljikUepEPD16hD4LvIcmhnhdLTiW/5pHgbmp14=
|
||||
github.com/DataDog/zstd v1.3.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||
github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
|
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/Shopify/sarama v1.21.0 h1:0GKs+e8mn1RRUzfg9oUXv3v7ZieQLmOZF/bfnmmGhM8=
|
||||
github.com/Shopify/sarama v1.21.0/go.mod h1:yuqtN/pe8cXRWG5zPaO7hCfNJp5MwmkoJEoLjkm5tCQ=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc=
|
||||
@@ -27,6 +31,7 @@ github.com/bsm/sarama-cluster v2.1.15+incompatible/go.mod h1:r7ao+4tTNXvWm+VRpRJ
|
||||
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927 h1:SKI1/fuSdodxmNNyVBR8d7X/HuLnRpvvFO0AgyQk764=
|
||||
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9 h1:74lLNRzvsdIlkTgfDSMuaPjBr4cf6k7pwQQANm/yLKU=
|
||||
@@ -51,10 +56,22 @@ github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/elazarl/goproxy v0.0.0-20181111060418-2ce16c963a8a h1:A4wNiqeKqU56ZhtnzJCTyPZ1+cyu8jKtIchQ3TtxHgw=
|
||||
github.com/elazarl/goproxy v0.0.0-20181111060418-2ce16c963a8a/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/emicklei/go-restful v2.9.6+incompatible h1:tfrHha8zJ01ywiOEC1miGY8st1/igzWB8OmvPgoYX7w=
|
||||
github.com/emicklei/go-restful v2.9.6+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/emicklei/go-restful-openapi v1.2.0 h1:ohRZ1yEZERGzqaozBgxa3A0lt6c6KF14xhs3IL9ECwg=
|
||||
github.com/emicklei/go-restful-openapi v1.2.0/go.mod h1:cy7o3Ge8ZWZ5E90mpEY81sJZZFs2pkuYcLvfngYy1l0=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20180322222829-3a0015ad55fa h1:hr8WVDjg4JKtQptZpzyb196TmruCs7PIsdJz8KAOZp8=
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20180322222829-3a0015ad55fa/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||
github.com/go-openapi/jsonreference v0.0.0-20180322222742-3fb327e6747d h1:k3UQ7Z8yFYq0BNkYykKIheY0HlZBl1Hku+pO9HE9FNU=
|
||||
github.com/go-openapi/jsonreference v0.0.0-20180322222742-3fb327e6747d/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
||||
github.com/go-openapi/spec v0.0.0-20180415031709-bcff419492ee h1:eo0HQoNFtbiEc7+1gRF9pgW6azx8a1cO2fXcqq1MuD0=
|
||||
github.com/go-openapi/spec v0.0.0-20180415031709-bcff419492ee/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
||||
github.com/go-openapi/swag v0.0.0-20180405201759-811b1089cde9 h1:+vsw187FKvA2QUGAcE+vQSfyxqLbUXixPYRRMAzwu04=
|
||||
github.com/go-openapi/swag v0.0.0-20180405201759-811b1089cde9/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
|
||||
@@ -124,6 +141,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mailru/easyjson v0.0.0-20180323154445-8b799c424f57 h1:qhv1ir3dIyOFmFU+5KqG4dF3zSQTA4nn1DFhu2NQC44=
|
||||
github.com/mailru/easyjson v0.0.0-20180323154445-8b799c424f57/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c h1:N7uWGS2fTwH/4BwxbHiJZNAFTSJ5yPU0emHsQWvkxEY=
|
||||
github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
@@ -181,10 +200,12 @@ github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/ulikunitz/xz v0.0.0-20180703112113-636d36a76670 h1:HQWT4ta3wW5GZ790GaqLCS+w1dvuA3rMfEQxLi+UOYU=
|
||||
github.com/ulikunitz/xz v0.0.0-20180703112113-636d36a76670/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
||||
@@ -207,6 +228,7 @@ golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f h1:FO4MZ3N56GnxbqxGKqh+YTz
|
||||
golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -265,3 +287,5 @@ k8s.io/apimachinery v0.0.0-20190116203031-d49e237a2683 h1:BmOSGJ1vwLhZKgDhTQlLF6
|
||||
k8s.io/apimachinery v0.0.0-20190116203031-d49e237a2683/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
|
||||
k8s.io/client-go v7.0.0+incompatible h1:kiH+Y6hn+pc78QS/mtBfMJAMIIaWevHi++JvOGEEQp4=
|
||||
k8s.io/client-go v7.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
|
||||
k8s.io/klog v0.3.3 h1:niceAagH1tzskmaie/icWd7ci1wbG7Bf2c6YGcQv+3c=
|
||||
k8s.io/klog v0.3.3/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
|
||||
+16
-1
@@ -266,12 +266,27 @@ build_all() {
|
||||
fi
|
||||
|
||||
mkdir -p $BUILDDIR
|
||||
|
||||
|
||||
# generate swagger (OpenApi 2.0) doc before building bundle image
|
||||
generate_swagger_doc
|
||||
|
||||
build_fission_bundle_image $version $date $gitcommit
|
||||
build_fetcher_image $version $date $gitcommit
|
||||
build_builder_image $version $date $gitcommit
|
||||
build_all_cli $version $date $gitcommit
|
||||
build_pre_upgrade_checks_image $version $date $gitcommit
|
||||
|
||||
remove_generated_swagger_doc
|
||||
}
|
||||
|
||||
generate_swagger_doc() {
|
||||
pushd $DIR/pkg/apis/fission.io/v1/tool
|
||||
./update-generated-swagger-docs.sh
|
||||
popd
|
||||
}
|
||||
|
||||
remove_generated_swagger_doc() {
|
||||
rm $DIR/pkg/apis/fission.io/v1/types_swagger_doc_generated.go
|
||||
}
|
||||
|
||||
version=${VERSION}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# How to update swagger (OpenAPI) struct description
|
||||
|
||||
Run `update-generated-swagger-docs.sh` and it will parse all comments in `types.go`.
|
||||
|
||||
```bash
|
||||
./update-generated-swagger-docs.sh
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
Copyright 2019 The Fission 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.
|
||||
*/
|
||||
Executable
+67
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env 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.
|
||||
|
||||
#
|
||||
# Please refer https://github.com/kubernetes/kubernetes/tree/master/hack for original file
|
||||
#
|
||||
|
||||
# Contains swagger related util functions.
|
||||
#
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
# Generates types_swagger_doc_generated file for the given group version.
|
||||
# $1: Name of the group version
|
||||
# $2: Path to the directory where types.go for that group version exists. This
|
||||
# is the directory where the file will be generated.
|
||||
kube::swagger::gen_types_swagger_doc() {
|
||||
local group_version=$1
|
||||
local gv_dir=$2
|
||||
local TMPFILE
|
||||
TMPFILE="${TMPDIR:-/tmp}/types_swagger_doc_generated.$(date +%s).go"
|
||||
|
||||
echo "Generating swagger type docs for ${group_version} at ${gv_dir}"
|
||||
|
||||
{
|
||||
echo -e "$(cat boilerplate.generatego.txt)\n"
|
||||
echo "package ${group_version##*/}"
|
||||
cat <<EOF
|
||||
|
||||
// This file contains a collection of methods that can be used from go-restful to
|
||||
// generate Swagger API documentation for its models. Please read this PR for more
|
||||
// information on the implementation: https://github.com/emicklei/go-restful/pull/215
|
||||
//
|
||||
// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if
|
||||
// they are on one line! For multiple line or blocks that you want to ignore use ---.
|
||||
// Any context after a --- is ignored.
|
||||
//
|
||||
// Those methods can be generated by using hack/update-generated-swagger-docs.sh
|
||||
|
||||
// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT.
|
||||
EOF
|
||||
} > "${TMPFILE}"
|
||||
|
||||
go run ./swagger_type_docs.go -s \
|
||||
"${gv_dir}/types.go" \
|
||||
-f - \
|
||||
>> "${TMPFILE}"
|
||||
|
||||
echo "// AUTO-GENERATED FUNCTIONS END HERE" >> "${TMPFILE}"
|
||||
|
||||
gofmt -w -s "${TMPFILE}"
|
||||
mv "${TMPFILE}" "${gv_dir}/types_swagger_doc_generated.go"
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright 2015 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.
|
||||
*/
|
||||
|
||||
//
|
||||
// Please refer https://github.com/kubernetes/kubernetes/blob/master/cmd/genswaggertypedocs/swagger_type_docs.go for original file
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
kruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
flag "github.com/spf13/pflag"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
var (
|
||||
functionDest = flag.StringP("func-dest", "f", "-", "Output for swagger functions; '-' means stdout (default)")
|
||||
typeSrc = flag.StringP("type-src", "s", "", "From where we are going to read the types")
|
||||
verify = flag.BoolP("verify", "v", false, "Verifies if the given type-src file has documentation for every type")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
if *typeSrc == "" {
|
||||
klog.Fatalf("Please define -s flag as it is the source file")
|
||||
}
|
||||
|
||||
var funcOut io.Writer
|
||||
if *functionDest == "-" {
|
||||
funcOut = os.Stdout
|
||||
} else {
|
||||
file, err := os.Create(*functionDest)
|
||||
if err != nil {
|
||||
klog.Fatalf("Couldn't open %v: %v", *functionDest, err)
|
||||
}
|
||||
defer file.Close()
|
||||
funcOut = file
|
||||
}
|
||||
|
||||
docsForTypes := kruntime.ParseDocumentationFrom(*typeSrc)
|
||||
|
||||
if *verify {
|
||||
rc, err := kruntime.VerifySwaggerDocsExist(docsForTypes, funcOut)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error in verification process: %s\n", err)
|
||||
}
|
||||
os.Exit(rc)
|
||||
}
|
||||
|
||||
if len(docsForTypes) > 0 {
|
||||
if err := kruntime.WriteSwaggerDocFunc(docsForTypes, funcOut); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error when writing swagger documentation functions: %s\n", err)
|
||||
os.Exit(-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2015 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.
|
||||
|
||||
# Generates `types_swagger_doc_generated.go` files for API group
|
||||
# versions. That file contains functions on API structs that return
|
||||
# the comments that should be surfaced for the corresponding API type
|
||||
# in our API docs.
|
||||
|
||||
|
||||
#
|
||||
# Please refer https://github.com/kubernetes/kubernetes/tree/master/hack for original file
|
||||
#
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
FISSION_CRD_VERSION=v1
|
||||
|
||||
source "swagger.sh"
|
||||
|
||||
# To avoid compile errors, remove the currently existing files.
|
||||
|
||||
for group_version in "${FISSION_CRD_VERSION}"; do
|
||||
kube::swagger::gen_types_swagger_doc "${group_version}" ../../${FISSION_CRD_VERSION}
|
||||
done
|
||||
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
Copyright 2019 The Fission 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.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/go-multierror"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// Each CRD type needs:
|
||||
// GetObjectKind (to satisfy the Object interface)
|
||||
//
|
||||
// In addition, each singular CRD type needs:
|
||||
// GetObjectMeta (to satisfy the ObjectMetaAccessor interface)
|
||||
//
|
||||
// And each list CRD type needs:
|
||||
// GetListMeta (to satisfy the ListMetaAccessor interface)
|
||||
|
||||
func (f *Function) GetObjectKind() schema.ObjectKind {
|
||||
return &f.TypeMeta
|
||||
}
|
||||
func (e *Environment) GetObjectKind() schema.ObjectKind {
|
||||
return &e.TypeMeta
|
||||
}
|
||||
func (ht *HTTPTrigger) GetObjectKind() schema.ObjectKind {
|
||||
return &ht.TypeMeta
|
||||
}
|
||||
func (w *KubernetesWatchTrigger) GetObjectKind() schema.ObjectKind {
|
||||
return &w.TypeMeta
|
||||
}
|
||||
func (t *TimeTrigger) GetObjectKind() schema.ObjectKind {
|
||||
return &t.TypeMeta
|
||||
}
|
||||
func (m *MessageQueueTrigger) GetObjectKind() schema.ObjectKind {
|
||||
return &m.TypeMeta
|
||||
}
|
||||
func (p *Package) GetObjectKind() schema.ObjectKind {
|
||||
return &p.TypeMeta
|
||||
}
|
||||
func (c *CanaryConfig) GetObjectKind() schema.ObjectKind {
|
||||
return &c.TypeMeta
|
||||
}
|
||||
|
||||
func (r *Recorder) GetObjectKind() schema.ObjectKind {
|
||||
return &r.TypeMeta
|
||||
}
|
||||
|
||||
func (f *Function) GetObjectMeta() metav1.Object {
|
||||
return &f.Metadata
|
||||
}
|
||||
func (e *Environment) GetObjectMeta() metav1.Object {
|
||||
return &e.Metadata
|
||||
}
|
||||
func (ht *HTTPTrigger) GetObjectMeta() metav1.Object {
|
||||
return &ht.Metadata
|
||||
}
|
||||
func (w *KubernetesWatchTrigger) GetObjectMeta() metav1.Object {
|
||||
return &w.Metadata
|
||||
}
|
||||
func (t *TimeTrigger) GetObjectMeta() metav1.Object {
|
||||
return &t.Metadata
|
||||
}
|
||||
func (m *MessageQueueTrigger) GetObjectMeta() metav1.Object {
|
||||
return &m.Metadata
|
||||
}
|
||||
func (p *Package) GetObjectMeta() metav1.Object {
|
||||
return &p.Metadata
|
||||
}
|
||||
func (c *CanaryConfig) GetObjectMeta() metav1.Object {
|
||||
return &c.Metadata
|
||||
}
|
||||
|
||||
func (r *Recorder) GetObjectMeta() metav1.Object {
|
||||
return &r.Metadata
|
||||
}
|
||||
|
||||
func (fl *FunctionList) GetObjectKind() schema.ObjectKind {
|
||||
return &fl.TypeMeta
|
||||
}
|
||||
func (el *EnvironmentList) GetObjectKind() schema.ObjectKind {
|
||||
return &el.TypeMeta
|
||||
}
|
||||
func (hl *HTTPTriggerList) GetObjectKind() schema.ObjectKind {
|
||||
return &hl.TypeMeta
|
||||
}
|
||||
func (wl *KubernetesWatchTriggerList) GetObjectKind() schema.ObjectKind {
|
||||
return &wl.TypeMeta
|
||||
}
|
||||
func (wl *TimeTriggerList) GetObjectKind() schema.ObjectKind {
|
||||
return &wl.TypeMeta
|
||||
}
|
||||
func (ml *MessageQueueTriggerList) GetObjectKind() schema.ObjectKind {
|
||||
return &ml.TypeMeta
|
||||
}
|
||||
func (pl *PackageList) GetObjectKind() schema.ObjectKind {
|
||||
return &pl.TypeMeta
|
||||
}
|
||||
func (rl *RecorderList) GetObjectKind() schema.ObjectKind {
|
||||
return &rl.TypeMeta
|
||||
}
|
||||
|
||||
func (cl *CanaryConfigList) GetObjectKind() schema.ObjectKind {
|
||||
return &cl.TypeMeta
|
||||
}
|
||||
|
||||
func (fl *FunctionList) GetListMeta() metav1.ListInterface {
|
||||
return &fl.Metadata
|
||||
}
|
||||
func (el *EnvironmentList) GetListMeta() metav1.ListInterface {
|
||||
return &el.Metadata
|
||||
}
|
||||
func (hl *HTTPTriggerList) GetListMeta() metav1.ListInterface {
|
||||
return &hl.Metadata
|
||||
}
|
||||
func (wl *KubernetesWatchTriggerList) GetListMeta() metav1.ListInterface {
|
||||
return &wl.Metadata
|
||||
}
|
||||
func (wl *TimeTriggerList) GetListMeta() metav1.ListInterface {
|
||||
return &wl.Metadata
|
||||
}
|
||||
func (ml *MessageQueueTriggerList) GetListMeta() metav1.ListInterface {
|
||||
return &ml.Metadata
|
||||
}
|
||||
func (pl *PackageList) GetListMeta() metav1.ListInterface {
|
||||
return &pl.Metadata
|
||||
}
|
||||
|
||||
func (rl *RecorderList) GetListMeta() metav1.ListInterface {
|
||||
return &rl.Metadata
|
||||
}
|
||||
|
||||
func (cl *CanaryConfigList) GetListMeta() metav1.ListInterface {
|
||||
return &cl.Metadata
|
||||
}
|
||||
|
||||
func validateMetadata(field string, m metav1.ObjectMeta) error {
|
||||
return ValidateKubeReference(field, m.Name, m.Namespace)
|
||||
}
|
||||
|
||||
func (p *Package) Validate() error {
|
||||
var result *multierror.Error
|
||||
|
||||
result = multierror.Append(result,
|
||||
validateMetadata("Package", p.Metadata),
|
||||
p.Spec.Validate(),
|
||||
p.Status.Validate())
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (pl *PackageList) Validate() error {
|
||||
var result *multierror.Error
|
||||
// not validate ListMeta
|
||||
for _, p := range pl.Items {
|
||||
result = multierror.Append(result, p.Validate())
|
||||
}
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (f *Function) Validate() error {
|
||||
var result *multierror.Error
|
||||
|
||||
result = multierror.Append(result,
|
||||
validateMetadata("Function", f.Metadata),
|
||||
f.Spec.Validate())
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (fl *FunctionList) Validate() error {
|
||||
var result *multierror.Error
|
||||
for _, f := range fl.Items {
|
||||
result = multierror.Append(result, f.Validate())
|
||||
}
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (e *Environment) Validate() error {
|
||||
var result *multierror.Error
|
||||
|
||||
result = multierror.Append(result,
|
||||
validateMetadata("Environment", e.Metadata),
|
||||
e.Spec.Validate())
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (el *EnvironmentList) Validate() error {
|
||||
var result *multierror.Error
|
||||
for _, e := range el.Items {
|
||||
result = multierror.Append(result, e.Validate())
|
||||
}
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (h *HTTPTrigger) Validate() error {
|
||||
var result *multierror.Error
|
||||
|
||||
result = multierror.Append(result,
|
||||
validateMetadata("HTTPTrigger", h.Metadata),
|
||||
h.Spec.Validate())
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (hl *HTTPTriggerList) Validate() error {
|
||||
var result *multierror.Error
|
||||
for _, h := range hl.Items {
|
||||
result = multierror.Append(result, h.Validate())
|
||||
}
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (k *KubernetesWatchTrigger) Validate() error {
|
||||
var result *multierror.Error
|
||||
|
||||
result = multierror.Append(result,
|
||||
validateMetadata("KubernetesWatchTrigger", k.Metadata),
|
||||
k.Spec.Validate())
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (kl *KubernetesWatchTriggerList) Validate() error {
|
||||
var result *multierror.Error
|
||||
for _, k := range kl.Items {
|
||||
result = multierror.Append(result, k.Validate())
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (t *TimeTrigger) Validate() error {
|
||||
var result *multierror.Error
|
||||
|
||||
result = multierror.Append(result,
|
||||
validateMetadata("TimeTrigger", t.Metadata),
|
||||
t.Spec.Validate())
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (tl *TimeTriggerList) Validate() error {
|
||||
var result *multierror.Error
|
||||
for _, t := range tl.Items {
|
||||
result = multierror.Append(result, t.Validate())
|
||||
}
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (m *MessageQueueTrigger) Validate() error {
|
||||
var result *multierror.Error
|
||||
|
||||
result = multierror.Append(result,
|
||||
validateMetadata("MessageQueueTrigger", m.Metadata),
|
||||
m.Spec.Validate())
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (ml *MessageQueueTriggerList) Validate() error {
|
||||
var result *multierror.Error
|
||||
for _, m := range ml.Items {
|
||||
result = multierror.Append(result, m.Validate())
|
||||
}
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (r *Recorder) Validate() error {
|
||||
var result *multierror.Error
|
||||
|
||||
result = multierror.Append(result,
|
||||
validateMetadata("Recorder", r.Metadata),
|
||||
r.Spec.Validate())
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
@@ -1,364 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 The Fission 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.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
type (
|
||||
//
|
||||
// Functions and packages
|
||||
//
|
||||
|
||||
// ChecksumType specifies the checksum algorithm, such as
|
||||
// sha256, used for a checksum.
|
||||
ChecksumType string
|
||||
|
||||
// Checksum of package contents when the contents are stored
|
||||
// outside the Package struct. Type is the checksum algorithm;
|
||||
// "sha256" is the only currently supported one. Sum is hex
|
||||
// encoded.
|
||||
Checksum struct {
|
||||
Type ChecksumType `json:"type,omitempty"`
|
||||
Sum string `json:"sum,omitempty"`
|
||||
}
|
||||
|
||||
// ArchiveType is either literal or URL, indicating whether
|
||||
// the package is specified in the Archive struct or
|
||||
// externally.
|
||||
ArchiveType string
|
||||
|
||||
// Package contains or references a collection of source or
|
||||
// binary files.
|
||||
Archive struct {
|
||||
// Type defines how the package is specified: literal or URL.
|
||||
Type ArchiveType `json:"type,omitempty"`
|
||||
|
||||
// Literal contents of the package. Can be used for
|
||||
// encoding packages below TODO (256KB?) size.
|
||||
Literal []byte `json:"literal,omitempty"`
|
||||
|
||||
// URL references a package.
|
||||
URL string `json:"url,omitempty"`
|
||||
|
||||
// Checksum ensures the integrity of packages
|
||||
// refereced by URL. Ignored for literals.
|
||||
Checksum Checksum `json:"checksum,omitempty"`
|
||||
}
|
||||
|
||||
EnvironmentReference struct {
|
||||
Namespace string `json:"namespace"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
SecretReference struct {
|
||||
Namespace string `json:"namespace"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
ConfigMapReference struct {
|
||||
Namespace string `json:"namespace"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
BuildStatus string
|
||||
|
||||
PackageSpec struct {
|
||||
Environment EnvironmentReference `json:"environment"`
|
||||
Source Archive `json:"source,omitempty"`
|
||||
Deployment Archive `json:"deployment,omitempty"`
|
||||
BuildCommand string `json:"buildcmd,omitempty"`
|
||||
// In the future, we can have a debug build here too
|
||||
}
|
||||
|
||||
PackageStatus struct {
|
||||
BuildStatus BuildStatus `json:"buildstatus,omitempty"`
|
||||
BuildLog string `json:"buildlog,omitempty"` // output of the build (errors etc)
|
||||
}
|
||||
|
||||
PackageRef struct {
|
||||
Namespace string `json:"namespace"`
|
||||
Name string `json:"name"`
|
||||
|
||||
// Including resource version in the reference forces the function to be updated on
|
||||
// package update, making it possible to cache the function based on its metadata.
|
||||
ResourceVersion string `json:"resourceversion,omitempty"`
|
||||
}
|
||||
|
||||
FunctionPackageRef struct {
|
||||
PackageRef PackageRef `json:"packageref"`
|
||||
|
||||
// FunctionName specifies a specific function within the package. This allows
|
||||
// functions to share packages, by having different functions within the same
|
||||
// package.
|
||||
//
|
||||
// Fission itself does not interpret this path. It is passed verbatim to
|
||||
// build and runtime environments.
|
||||
//
|
||||
// This is optional: if unspecified, the environment has a default name.
|
||||
FunctionName string `json:"functionName,omitempty"`
|
||||
}
|
||||
|
||||
//ExecutorType is the primary executor for an environment
|
||||
ExecutorType string
|
||||
|
||||
//StrategyType is the strategy to be used for function execution
|
||||
StrategyType string
|
||||
|
||||
// FunctionSpec describes the contents of the function.
|
||||
FunctionSpec struct {
|
||||
// Environment is the build and runtime environment that this function is
|
||||
// associated with. An Environment with this name should exist, otherwise the
|
||||
// function cannot be invoked.
|
||||
Environment EnvironmentReference `json:"environment"`
|
||||
|
||||
// Reference to a package containing deployment and optionally the source
|
||||
Package FunctionPackageRef `json:"package"`
|
||||
|
||||
Secrets []SecretReference `json:"secrets"`
|
||||
ConfigMaps []ConfigMapReference `json:"configmaps"`
|
||||
|
||||
// cpu and memory resources as per K8S standards
|
||||
Resources apiv1.ResourceRequirements `json:"resources"`
|
||||
|
||||
// InvokeStrategy is a set of controls which affect how function executes
|
||||
InvokeStrategy InvokeStrategy
|
||||
}
|
||||
|
||||
/*InvokeStrategy is a set of controls over how the function executes.
|
||||
It affects the performance and resource usage of the function.
|
||||
|
||||
An InvokeStategy is of one of two types: ExecutionStrategy, which controls low-level
|
||||
parameters such as which ExecutorType to use, when to autoscale, minimum and maximum
|
||||
number of running instances, etc. A higher-level AbstractInvokeStrategy will also be
|
||||
supported; this strategy would specify the target request rate of the function,
|
||||
the target latency statistics, and the target cost (in terms of compute resources).
|
||||
*/
|
||||
InvokeStrategy struct {
|
||||
ExecutionStrategy ExecutionStrategy
|
||||
StrategyType StrategyType
|
||||
}
|
||||
|
||||
/*ExecutionStrategy specifies low-level parameters for function execution,
|
||||
such as the number of instances.
|
||||
|
||||
MinScale affects the cold start behaviour for a function. If MinScale is 0 then the
|
||||
deployment is created on first invocation of function and is good for requests of
|
||||
asynchronous nature. If MinScale is greater than 0 then MinScale number of pods are
|
||||
created at the time of creation of function. This ensures faster response during first
|
||||
invocation at the cost of consuming resources.
|
||||
|
||||
MaxScale is the maximum number of pods that function will scale to based on TargetCPUPercent
|
||||
and resources allocated to the function pod.
|
||||
*/
|
||||
ExecutionStrategy struct {
|
||||
ExecutorType ExecutorType
|
||||
MinScale int
|
||||
MaxScale int
|
||||
TargetCPUPercent int
|
||||
SpecializationTimeout int
|
||||
}
|
||||
|
||||
FunctionReferenceType string
|
||||
|
||||
FunctionReference struct {
|
||||
// Type indicates whether this function reference is by name or selector. For now,
|
||||
// the only supported reference type is by name. Future reference types:
|
||||
// * Function by label or annotation
|
||||
// * Branch or tag of a versioned function
|
||||
// * A "rolling upgrade" from one version of a function to another
|
||||
Type FunctionReferenceType `json:"type"`
|
||||
|
||||
// Name of the function.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Function Reference by weight. this map contains function name as key and its weight
|
||||
// as the value.
|
||||
FunctionWeights map[string]int `json:"functionweights"`
|
||||
}
|
||||
|
||||
//
|
||||
// Environments
|
||||
//
|
||||
|
||||
Runtime struct {
|
||||
// Image for containing the language runtime.
|
||||
Image string `json:"image"`
|
||||
|
||||
// LoadEndpointPort defines the port on which the
|
||||
// server listens for function load
|
||||
// requests. Optional; default 8888.
|
||||
LoadEndpointPort int32 `json:"loadendpointport"`
|
||||
|
||||
// LoadEndpointPath defines the relative URL on which
|
||||
// the server listens for function load
|
||||
// requests. Optional; default "/specialize".
|
||||
LoadEndpointPath string `json:"loadendpointpath"`
|
||||
|
||||
// FunctionEndpointPort defines the port on which the
|
||||
// server listens for function requests. Optional;
|
||||
// default 8888.
|
||||
FunctionEndpointPort int32 `json:"functionendpointport"`
|
||||
|
||||
// Container allows the modification of the deployed runtime
|
||||
// container using the Kubernetes Container spec. Fission overrides
|
||||
// the following fields:
|
||||
// - Name
|
||||
// - Image; set to the Runtime.Image
|
||||
// - TerminationMessagePath
|
||||
// - ImagePullPolicy
|
||||
// (optional)
|
||||
Container *apiv1.Container `json:"container,omitempty"`
|
||||
|
||||
// Podspec allows modification of deployed runtime pod with Kubernetes PodSpec
|
||||
// The merging logic is briefly described below and detailed MergePodSpec function
|
||||
// - Volumes mounts and env variables for function and fetcher container are appended
|
||||
// - All additional containers and init containers are appended
|
||||
// - Volume definitions are appended
|
||||
// - Lists such as tolerations, ImagePullSecrets, HostAliases are appended
|
||||
// - Structs are merged and variables from pod spec take precedence
|
||||
// (optional)
|
||||
PodSpec *apiv1.PodSpec `json:"podspec,omitempty"`
|
||||
}
|
||||
|
||||
Builder struct {
|
||||
// Image for containing the language runtime.
|
||||
Image string `json:"image,omitempty"`
|
||||
|
||||
// (Optional) Default build command to run for this build environment.
|
||||
Command string `json:"command,omitempty"`
|
||||
|
||||
// Container allows the modification of the deployed builder
|
||||
// container using the Kubernetes Container spec. Fission overrides
|
||||
// the following fields:
|
||||
// - Name
|
||||
// - Image; set to the Builder.Image
|
||||
// - Command; set to the Builder.Command
|
||||
// - TerminationMessagePath
|
||||
// - ImagePullPolicy
|
||||
// - ReadinessProbe
|
||||
// (optional)
|
||||
Container *apiv1.Container `json:"container,omitempty"`
|
||||
}
|
||||
|
||||
EnvironmentSpec struct {
|
||||
// Environment API version
|
||||
Version int `json:"version"`
|
||||
|
||||
// Runtime container image etc.; required
|
||||
Runtime Runtime `json:"runtime"`
|
||||
|
||||
// Optional
|
||||
Builder Builder `json:"builder"`
|
||||
|
||||
// Optional, but strongly encouraged. Used to populate
|
||||
// links from UI, CLI, etc.
|
||||
DocumentationURL string `json:"documentationurl,omitempty"`
|
||||
|
||||
// Optional, defaults to 'AllowedFunctionsPerContainerSingle'
|
||||
AllowedFunctionsPerContainer AllowedFunctionsPerContainer `json:"allowedFunctionsPerContainer,omitempty"`
|
||||
|
||||
// Optional, defaults to 'false'
|
||||
AllowAccessToExternalNetwork bool `json:"allowAccessToExternalNetwork,omitempty"`
|
||||
|
||||
// Request and limit resources for the environment
|
||||
Resources apiv1.ResourceRequirements `json:"resources"`
|
||||
|
||||
// The initial pool size for environment
|
||||
Poolsize int `json:"poolsize,omitempty"`
|
||||
|
||||
// The grace time for pod to perform connection draining before termination. The unit is in seconds.
|
||||
// Optional, defaults to 360 seconds
|
||||
TerminationGracePeriod int64
|
||||
|
||||
// KeepArchive is used by fetcher to determine if the extracted archive
|
||||
// or unarchived file should be placed, which is then used by specialize handler
|
||||
KeepArchive bool `json:"keeparchive"`
|
||||
}
|
||||
|
||||
AllowedFunctionsPerContainer string
|
||||
|
||||
//
|
||||
// Triggers
|
||||
//
|
||||
|
||||
HTTPTriggerSpec struct {
|
||||
Host string `json:"host"`
|
||||
RelativeURL string `json:"relativeurl"`
|
||||
CreateIngress bool `json:"createingress"`
|
||||
Method string `json:"method"`
|
||||
FunctionReference FunctionReference `json:"functionref"`
|
||||
}
|
||||
|
||||
KubernetesWatchTriggerSpec struct {
|
||||
Namespace string `json:"namespace"`
|
||||
Type string `json:"type"`
|
||||
LabelSelector map[string]string `json:"labelselector"`
|
||||
FunctionReference FunctionReference `json:"functionref"`
|
||||
}
|
||||
|
||||
MessageQueueType string
|
||||
|
||||
// MessageQueueTriggerSpec defines a binding from a topic in a
|
||||
// message queue to a function.
|
||||
MessageQueueTriggerSpec struct {
|
||||
FunctionReference FunctionReference `json:"functionref"`
|
||||
MessageQueueType MessageQueueType `json:"messageQueueType"`
|
||||
Topic string `json:"topic"`
|
||||
ResponseTopic string `json:"respTopic,omitempty"`
|
||||
ErrorTopic string `json:"errorTopic"`
|
||||
MaxRetries int `json:"maxRetries"`
|
||||
ContentType string `json:"contentType"`
|
||||
}
|
||||
|
||||
// RecorderSpec defines a policy for recording requests and responses
|
||||
// to a function, that can be later inspected or replayed.
|
||||
RecorderSpec struct {
|
||||
Name string `json:"name"`
|
||||
Function string `json:"function"`
|
||||
Triggers []string `json:"triggers"`
|
||||
RetentionPolicy string `json:"retentionPolicy"`
|
||||
EvictionPolicy string `json:"evictionPolicy"`
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
// TimeTrigger invokes the specific function at a time or
|
||||
// times specified by a cron string.
|
||||
TimeTriggerSpec struct {
|
||||
Cron string `json:"cron"`
|
||||
FunctionReference `json:"functionref"`
|
||||
}
|
||||
|
||||
FailureType string
|
||||
|
||||
// Canary Config Spec
|
||||
CanaryConfigSpec struct {
|
||||
Trigger string `json:"trigger"`
|
||||
NewFunction string `json:"newfunction"`
|
||||
OldFunction string `json:"oldfunction"`
|
||||
WeightIncrement int `json:"weightincrement"`
|
||||
WeightIncrementDuration string `json:"duration"`
|
||||
FailureThreshold int `json:"failurethreshold"`
|
||||
FailureType FailureType `json:"failureType"`
|
||||
}
|
||||
|
||||
// CanaryConfig Status
|
||||
CanaryConfigStatus struct {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
)
|
||||
+495
-289
@@ -17,9 +17,8 @@ limitations under the License.
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/go-multierror"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
@@ -47,18 +46,19 @@ type (
|
||||
Metadata metav1.ObjectMeta `json:"metadata"`
|
||||
Spec PackageSpec `json:"spec"`
|
||||
|
||||
// Status indicates the build status of package.
|
||||
Status PackageStatus `json:"status"`
|
||||
}
|
||||
|
||||
// PackageList is a list of Packages.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
PackageList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ListMeta `json:"metadata"`
|
||||
|
||||
Items []Package `json:"items"`
|
||||
Items []Package `json:"items"`
|
||||
}
|
||||
|
||||
// Functions.
|
||||
// Function is function runs within environment runtime with given package and secrets/configmaps.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
Function struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
@@ -66,15 +66,15 @@ type (
|
||||
Spec FunctionSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// FunctionList is a list of Functions.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
FunctionList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ListMeta `json:"metadata"`
|
||||
|
||||
Items []Function `json:"items"`
|
||||
Items []Function `json:"items"`
|
||||
}
|
||||
|
||||
// Environments.
|
||||
// Environment is environment for building and running user functions.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
Environment struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
@@ -82,14 +82,15 @@ type (
|
||||
Spec EnvironmentSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// EnvironmentList is a list of Environments.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
EnvironmentList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ListMeta `json:"metadata"`
|
||||
|
||||
Items []Environment `json:"items"`
|
||||
Items []Environment `json:"items"`
|
||||
}
|
||||
|
||||
// HTTPTrigger is the trigger invokes user functions when receiving HTTP requests.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
HTTPTrigger struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
@@ -97,15 +98,15 @@ type (
|
||||
Spec HTTPTriggerSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// HTTPTriggerList is a list of HTTPTriggers
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
HTTPTriggerList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ListMeta `json:"metadata"`
|
||||
|
||||
Items []HTTPTrigger `json:"items"`
|
||||
Items []HTTPTrigger `json:"items"`
|
||||
}
|
||||
|
||||
// Kubernetes Watches as triggers
|
||||
// KubernetesWatchTrigger watches kubernetes resource events and invokes functions.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
KubernetesWatchTrigger struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
@@ -113,15 +114,15 @@ type (
|
||||
Spec KubernetesWatchTriggerSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// KubernetesWatchTriggerList is a list of KubernetesWatchTriggers
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
KubernetesWatchTriggerList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ListMeta `json:"metadata"`
|
||||
|
||||
Items []KubernetesWatchTrigger `json:"items"`
|
||||
Metadata metav1.ListMeta `json:"metadata"`
|
||||
Items []KubernetesWatchTrigger `json:"items"`
|
||||
}
|
||||
|
||||
// Time triggers
|
||||
// TimeTrigger invokes functions based on given cron schedule.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
TimeTrigger struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
@@ -129,6 +130,7 @@ type (
|
||||
Spec TimeTriggerSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// TimeTriggerList is a list of TimeTriggers.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
TimeTriggerList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
@@ -137,7 +139,7 @@ type (
|
||||
Items []TimeTrigger `json:"items"`
|
||||
}
|
||||
|
||||
// Message Queue triggers
|
||||
// MessageQueueTrigger invokes functions when messages arrive to certain topic that trigger subscribes to.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
MessageQueueTrigger struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
@@ -145,14 +147,15 @@ type (
|
||||
Spec MessageQueueTriggerSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// MessageQueueTriggerList is a list of MessageQueueTriggers.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
MessageQueueTriggerList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ListMeta `json:"metadata"`
|
||||
|
||||
Items []MessageQueueTrigger `json:"items"`
|
||||
Metadata metav1.ListMeta `json:"metadata"`
|
||||
Items []MessageQueueTrigger `json:"items"`
|
||||
}
|
||||
|
||||
// Recorder allows user to record all traffic payload to a certain function.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
Recorder struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
@@ -160,6 +163,7 @@ type (
|
||||
Spec RecorderSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// RecorderList is a list of Recorders.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
RecorderList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
@@ -168,6 +172,7 @@ type (
|
||||
Items []Recorder `json:"items"`
|
||||
}
|
||||
|
||||
// CanaryConfig is for canary deployment of two functions.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
CanaryConfig struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
@@ -176,6 +181,7 @@ type (
|
||||
Status CanaryConfigStatus `json:"status"`
|
||||
}
|
||||
|
||||
// CanaryConfigList is a list of CanaryConfigs.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
CanaryConfigList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
@@ -183,272 +189,472 @@ type (
|
||||
|
||||
Items []CanaryConfig `json:"items"`
|
||||
}
|
||||
|
||||
//
|
||||
// Functions and packages
|
||||
//
|
||||
|
||||
// ChecksumType specifies the checksum algorithm, such as
|
||||
// sha256, used for a checksum.
|
||||
ChecksumType string
|
||||
|
||||
// Checksum of package contents when the contents are stored
|
||||
// outside the Package struct. Type is the checksum algorithm;
|
||||
// "sha256" is the only currently supported one. Sum is hex
|
||||
// encoded.
|
||||
Checksum struct {
|
||||
Type ChecksumType `json:"type,omitempty"`
|
||||
Sum string `json:"sum,omitempty"`
|
||||
}
|
||||
|
||||
// ArchiveType is either literal or URL, indicating whether
|
||||
// the package is specified in the Archive struct or
|
||||
// externally.
|
||||
ArchiveType string
|
||||
|
||||
// Package contains or references a collection of source or
|
||||
// binary files.
|
||||
Archive struct {
|
||||
// Type defines how the package is specified: literal or URL.
|
||||
// Available value:
|
||||
// - literal
|
||||
// - url
|
||||
Type ArchiveType `json:"type,omitempty"`
|
||||
|
||||
// Literal contents of the package. Can be used for
|
||||
// encoding packages below TODO (256KB?) size.
|
||||
Literal []byte `json:"literal,omitempty"`
|
||||
|
||||
// URL references a package.
|
||||
URL string `json:"url,omitempty"`
|
||||
|
||||
// Checksum ensures the integrity of packages
|
||||
// refereced by URL. Ignored for literals.
|
||||
Checksum Checksum `json:"checksum,omitempty"`
|
||||
}
|
||||
|
||||
// EnvironmentReference is a reference to a environment.
|
||||
EnvironmentReference struct {
|
||||
Namespace string `json:"namespace"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// SecretReference is a reference to a kubernetes secret.
|
||||
SecretReference struct {
|
||||
Namespace string `json:"namespace"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// ConfigMapReference is a reference to a kubernetes configmap.
|
||||
ConfigMapReference struct {
|
||||
Namespace string `json:"namespace"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// BuildStatus indicates the current build status of a package.
|
||||
BuildStatus string
|
||||
|
||||
// PackageSpec includes source/deploy archives and the reference of environment to build the package.
|
||||
PackageSpec struct {
|
||||
// Environment is a reference to the environment for building source archive.
|
||||
Environment EnvironmentReference `json:"environment"`
|
||||
|
||||
// Source is the archive contains source code and dependencies file.
|
||||
// If the package status is in PENDING state, builder manager will then
|
||||
// notify builder to compile source and save the result as deployable archive.
|
||||
Source Archive `json:"source,omitempty"`
|
||||
|
||||
// Deployment is the deployable archive that environment runtime used to run user function.
|
||||
Deployment Archive `json:"deployment,omitempty"`
|
||||
|
||||
// BuildCommand is a custom build command that builder used to build the source archive.
|
||||
BuildCommand string `json:"buildcmd,omitempty"`
|
||||
|
||||
// In the future, we can have a debug build here too
|
||||
}
|
||||
|
||||
// PackageStatus contains the build status of a package also the build log for examination.
|
||||
PackageStatus struct {
|
||||
// BuildStatus is the package build status.
|
||||
BuildStatus BuildStatus `json:"buildstatus,omitempty"`
|
||||
|
||||
// BuildLog stores build log during the compilation.
|
||||
BuildLog string `json:"buildlog,omitempty"` // output of the build (errors etc)
|
||||
}
|
||||
|
||||
// PackageRef is a reference to the package.
|
||||
PackageRef struct {
|
||||
Namespace string `json:"namespace"`
|
||||
Name string `json:"name"`
|
||||
|
||||
// Including resource version in the reference forces the function to be updated on
|
||||
// package update, making it possible to cache the function based on its metadata.
|
||||
ResourceVersion string `json:"resourceversion,omitempty"`
|
||||
}
|
||||
|
||||
// FunctionPackageRef includes the reference to the package also the entrypoint of package.
|
||||
FunctionPackageRef struct {
|
||||
// Package reference
|
||||
PackageRef PackageRef `json:"packageref"`
|
||||
|
||||
// FunctionName specifies a specific function within the package. This allows
|
||||
// functions to share packages, by having different functions within the same
|
||||
// package.
|
||||
//
|
||||
// Fission itself does not interpret this path. It is passed verbatim to
|
||||
// build and runtime environments.
|
||||
//
|
||||
// This is optional: if unspecified, the environment has a default name.
|
||||
FunctionName string `json:"functionName,omitempty"`
|
||||
}
|
||||
|
||||
// ExecutorType is the primary executor for an environment
|
||||
ExecutorType string
|
||||
|
||||
// StrategyType is the strategy to be used for function execution
|
||||
StrategyType string
|
||||
|
||||
// FunctionSpec describes the contents of the function.
|
||||
FunctionSpec struct {
|
||||
// Environment is the build and runtime environment that this function is
|
||||
// associated with. An Environment with this name should exist, otherwise the
|
||||
// function cannot be invoked.
|
||||
Environment EnvironmentReference `json:"environment"`
|
||||
|
||||
// Reference to a package containing deployment and optionally the source.
|
||||
Package FunctionPackageRef `json:"package"`
|
||||
|
||||
// Reference to a list of secrets.
|
||||
Secrets []SecretReference `json:"secrets"`
|
||||
|
||||
// Reference to a list of configmaps.
|
||||
ConfigMaps []ConfigMapReference `json:"configmaps"`
|
||||
|
||||
// cpu and memory resources as per K8S standards
|
||||
// This is only for newdeploy to set up resource limitation
|
||||
// when creating deployment for a function.
|
||||
Resources apiv1.ResourceRequirements `json:"resources"`
|
||||
|
||||
// InvokeStrategy is a set of controls which affect how function executes
|
||||
InvokeStrategy InvokeStrategy
|
||||
}
|
||||
|
||||
// InvokeStrategy is a set of controls over how the function executes.
|
||||
// It affects the performance and resource usage of the function.
|
||||
//
|
||||
// An InvokeStrategy is of one of two types: ExecutionStrategy, which controls low-level
|
||||
// parameters such as which ExecutorType to use, when to autoscale, minimum and maximum
|
||||
// number of running instances, etc. A higher-level AbstractInvokeStrategy will also be
|
||||
// supported; this strategy would specify the target request rate of the function,
|
||||
// the target latency statistics, and the target cost (in terms of compute resources).
|
||||
InvokeStrategy struct {
|
||||
|
||||
// ExecutionStrategy specifies low-level parameters for function execution,
|
||||
// such as the number of instances.
|
||||
ExecutionStrategy ExecutionStrategy
|
||||
|
||||
// StrategyType is the strategy type of a function.
|
||||
// Now it only supports 'execution'.
|
||||
StrategyType StrategyType
|
||||
}
|
||||
|
||||
// ExecutionStrategy specifies low-level parameters for function execution,
|
||||
// such as the number of instances.
|
||||
//
|
||||
// MinScale affects the cold start behaviour for a function. If MinScale is 0 then the
|
||||
// deployment is created on first invocation of function and is good for requests of
|
||||
// asynchronous nature. If MinScale is greater than 0 then MinScale number of pods are
|
||||
// created at the time of creation of function. This ensures faster response during first
|
||||
// invocation at the cost of consuming resources.
|
||||
//
|
||||
// MaxScale is the maximum number of pods that function will scale to based on TargetCPUPercent
|
||||
// and resources allocated to the function pod.
|
||||
ExecutionStrategy struct {
|
||||
|
||||
// ExecutorType is the executor type of a function used. Defaults to "poolmgr".
|
||||
//
|
||||
// Available value:
|
||||
// - poolmgr
|
||||
// - newdeploy
|
||||
ExecutorType ExecutorType
|
||||
|
||||
// This is only for newdeploy to set up minimum replicas of deployment.
|
||||
MinScale int
|
||||
|
||||
// This is only for newdeploy to set up maximum replicas of deployment.
|
||||
MaxScale int
|
||||
|
||||
// This is only for newdeploy to set up target CPU utilization of HPA.
|
||||
TargetCPUPercent int
|
||||
|
||||
// This is the timeout setting for executor to wait for pod specialization.
|
||||
// Currently, only newdeploy utilizes this value.
|
||||
SpecializationTimeout int
|
||||
}
|
||||
|
||||
FunctionReferenceType string
|
||||
|
||||
FunctionReference struct {
|
||||
// Type indicates whether this function reference is by name or selector. For now,
|
||||
// the only supported reference type is by "name". Future reference types:
|
||||
// * Function by label or annotation
|
||||
// * Branch or tag of a versioned function
|
||||
// * A "rolling upgrade" from one version of a function to another
|
||||
// Available value:
|
||||
// - name
|
||||
// - function-weights
|
||||
Type FunctionReferenceType `json:"type"`
|
||||
|
||||
// Name of the function.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Function Reference by weight. this map contains function name as key and its weight
|
||||
// as the value. This is for canary upgrade purpose.
|
||||
FunctionWeights map[string]int `json:"functionweights"`
|
||||
}
|
||||
|
||||
//
|
||||
// Environments
|
||||
//
|
||||
|
||||
// Runtime is the setting for environment runtime.
|
||||
Runtime struct {
|
||||
// Image for containing the language runtime.
|
||||
Image string `json:"image"`
|
||||
|
||||
// NOT USED NOW
|
||||
// LoadEndpointPort defines the port on which the
|
||||
// server listens for function load
|
||||
// requests. Optional; default 8888.
|
||||
LoadEndpointPort int32 `json:"-"` // `json:"loadendpointport"`
|
||||
|
||||
// NOT USED NOW
|
||||
// LoadEndpointPath defines the relative URL on which
|
||||
// the server listens for function load
|
||||
// requests. Optional; default "/specialize".
|
||||
LoadEndpointPath string `json:"-"` // `json:"loadendpointpath"`
|
||||
|
||||
// NOT USED NOW
|
||||
// FunctionEndpointPort defines the port on which the
|
||||
// server listens for function requests. Optional;
|
||||
// default 8888.
|
||||
FunctionEndpointPort int32 `json:"-"` // `json:"functionendpointport"`
|
||||
|
||||
// (Optional) Container allows the modification of the deployed runtime
|
||||
// container using the Kubernetes Container spec. Fission overrides
|
||||
// the following fields:
|
||||
// - Name
|
||||
// - Image; set to the Runtime.Image
|
||||
// - TerminationMessagePath
|
||||
// - ImagePullPolicy
|
||||
//
|
||||
// You can set either PodSpec or Container, but not both.
|
||||
Container *apiv1.Container `json:"container,omitempty"`
|
||||
|
||||
// (Optional) Podspec allows modification of deployed runtime pod with Kubernetes PodSpec
|
||||
// The merging logic is briefly described below and detailed MergePodSpec function
|
||||
// - Volumes mounts and env variables for function and fetcher container are appended
|
||||
// - All additional containers and init containers are appended
|
||||
// - Volume definitions are appended
|
||||
// - Lists such as tolerations, ImagePullSecrets, HostAliases are appended
|
||||
// - Structs are merged and variables from pod spec take precedence
|
||||
//
|
||||
// You can set either PodSpec or Container, but not both.
|
||||
PodSpec *apiv1.PodSpec `json:"podspec,omitempty"`
|
||||
}
|
||||
|
||||
// Builder is the setting for environment builder.
|
||||
Builder struct {
|
||||
// Image for containing the language compilation environment.
|
||||
Image string `json:"image,omitempty"`
|
||||
|
||||
// (Optional) Default build command to run for this build environment.
|
||||
Command string `json:"command,omitempty"`
|
||||
|
||||
// (Optional) Container allows the modification of the deployed builder
|
||||
// container using the Kubernetes Container spec. Fission overrides
|
||||
// the following fields:
|
||||
// - Name
|
||||
// - Image; set to the Builder.Image
|
||||
// - Command; set to the Builder.Command
|
||||
// - TerminationMessagePath
|
||||
// - ImagePullPolicy
|
||||
// - ReadinessProbe
|
||||
Container *apiv1.Container `json:"container,omitempty"`
|
||||
}
|
||||
|
||||
// EnvironmentSpec contains with builder, runtime and some other related environment settings.
|
||||
EnvironmentSpec struct {
|
||||
// Version is the Environment API version
|
||||
//
|
||||
// Version "1" allows user to run code snippet in a file and
|
||||
// it's supported by most of environments except tensorflow-serving.
|
||||
//
|
||||
// Version "2" supports downloading and compiling user function if source archive is not empty.
|
||||
//
|
||||
// Version "3" is almost the same with v2, but you're able to control the size of pre-warm pool of the environment.
|
||||
Version int `json:"version"`
|
||||
|
||||
// Runtime is configuration for running function, like container image etc.
|
||||
Runtime Runtime `json:"runtime"`
|
||||
|
||||
// (Optional) Builder is configuration for builder manager to launch environment builder to build source code into
|
||||
// deployable binary.
|
||||
Builder Builder `json:"builder"`
|
||||
|
||||
// NOT USED NOW.
|
||||
// (Optional) Strongly encouraged. Used to populate links from UI, CLI, etc.
|
||||
DocumentationURL string `json:"-"` // `json:"documentationurl,omitempty"`
|
||||
|
||||
// (Optional) defaults to 'single'. Fission workflow uses
|
||||
// 'infinite' to load multiple functions in one function pod.
|
||||
// Available value:
|
||||
// - single
|
||||
// - infinite
|
||||
AllowedFunctionsPerContainer AllowedFunctionsPerContainer `json:"allowedFunctionsPerContainer,omitempty"`
|
||||
|
||||
// Istio default blocks all egress traffic for safety.
|
||||
// To enable accessibility of external network for builder/function pod, set to 'true'.
|
||||
// (Optional) defaults to 'false'
|
||||
AllowAccessToExternalNetwork bool `json:"allowAccessToExternalNetwork,omitempty"`
|
||||
|
||||
// The request and limit CPU/MEM resource setting for poolmanager to set up pods in the pre-warm pool.
|
||||
// (Optional) defaults to no limitation.
|
||||
Resources apiv1.ResourceRequirements `json:"resources"`
|
||||
|
||||
// The initial pool size for environment
|
||||
Poolsize int `json:"poolsize,omitempty"`
|
||||
|
||||
// The grace time for pod to perform connection draining before termination. The unit is in seconds.
|
||||
// (Optional) defaults to 360 seconds
|
||||
TerminationGracePeriod int64 `json:"terminationGracePeriod,omitempty"`
|
||||
|
||||
// KeepArchive is used by fetcher to determine if the extracted archive
|
||||
// or unarchived file should be placed, which is then used by specialize handler.
|
||||
// (This is mainly for the JVM environment because .jar is one kind of zip archive.)
|
||||
KeepArchive bool `json:"keeparchive"`
|
||||
}
|
||||
|
||||
AllowedFunctionsPerContainer string
|
||||
|
||||
//
|
||||
// Triggers
|
||||
//
|
||||
|
||||
// HTTPTriggerSpec is for router to expose user functions at the given URL path.
|
||||
HTTPTriggerSpec struct {
|
||||
// NOT USED NOW
|
||||
Host string `json:"-"` //`json:"host"`
|
||||
|
||||
// RelativeURL is the exposed URL for external client to access a function with.
|
||||
RelativeURL string `json:"relativeurl"`
|
||||
|
||||
// If CreateIngress is true, router will create a ingress definition.
|
||||
CreateIngress bool `json:"createingress"`
|
||||
|
||||
// HTTP method to access a function.
|
||||
Method string `json:"method"`
|
||||
|
||||
// FunctionReference is a reference to the target function.
|
||||
FunctionReference FunctionReference `json:"functionref"`
|
||||
}
|
||||
|
||||
// KubernetesWatchTriggerSpec
|
||||
KubernetesWatchTriggerSpec struct {
|
||||
Namespace string `json:"namespace"`
|
||||
|
||||
// Type of resource to watch (Pod, Service, etc.)
|
||||
Type string `json:"type"`
|
||||
|
||||
// Resource labels
|
||||
LabelSelector map[string]string `json:"labelselector"`
|
||||
|
||||
// The reference to a function for kubewatcher to invoke with
|
||||
// when receiving events.
|
||||
FunctionReference FunctionReference `json:"functionref"`
|
||||
}
|
||||
|
||||
// Type of message queue
|
||||
MessageQueueType string
|
||||
|
||||
// MessageQueueTriggerSpec defines a binding from a topic in a
|
||||
// message queue to a function.
|
||||
MessageQueueTriggerSpec struct {
|
||||
// The reference to a function for message queue trigger to invoke with
|
||||
// when receiving messages from subscribed topic.
|
||||
FunctionReference FunctionReference `json:"functionref"`
|
||||
|
||||
// Type of message queue (NATS, Kafka, AzureQueue)
|
||||
MessageQueueType MessageQueueType `json:"messageQueueType"`
|
||||
|
||||
// Subscribed topic
|
||||
Topic string `json:"topic"`
|
||||
|
||||
// Topic for message queue trigger to sent response from function.
|
||||
ResponseTopic string `json:"respTopic,omitempty"`
|
||||
|
||||
// Topic to collect error response sent from function
|
||||
ErrorTopic string `json:"errorTopic"`
|
||||
|
||||
// Maximum times for message queue trigger to retry
|
||||
MaxRetries int `json:"maxRetries"`
|
||||
|
||||
// Content type of payload
|
||||
ContentType string `json:"contentType"`
|
||||
}
|
||||
|
||||
// RecorderSpec defines a policy for recording requests and responses
|
||||
// to a function, that can be later inspected or replayed.
|
||||
RecorderSpec struct {
|
||||
// Name of recorder resource
|
||||
Name string `json:"name"`
|
||||
|
||||
// Function to collect requests/responses
|
||||
Function string `json:"function"`
|
||||
|
||||
// HTTP trigger to record the requests and responses.
|
||||
Triggers []string `json:"triggers"`
|
||||
RetentionPolicy string `json:"-"` // `json:"retentionPolicy"`
|
||||
EvictionPolicy string `json:"-"` // `json:"evictionPolicy"`
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
// TimeTrigger invokes the specific function at a time or
|
||||
// times specified by a cron string.
|
||||
TimeTriggerSpec struct {
|
||||
// Cron schedule
|
||||
Cron string `json:"cron"`
|
||||
|
||||
// The reference to function
|
||||
FunctionReference `json:"functionref"`
|
||||
}
|
||||
|
||||
FailureType string
|
||||
|
||||
// Canary Config Spec
|
||||
CanaryConfigSpec struct {
|
||||
// HTTP trigger that this config references
|
||||
Trigger string `json:"trigger"`
|
||||
|
||||
// New version of the function
|
||||
NewFunction string `json:"newfunction"`
|
||||
|
||||
// Old stable version of the function
|
||||
OldFunction string `json:"oldfunction"`
|
||||
|
||||
// Weight increment step for function
|
||||
WeightIncrement int `json:"weightincrement"`
|
||||
|
||||
// Weight increment interval, string representation of time.Duration, ex : 1m, 2h, 2d (default: "2m")
|
||||
WeightIncrementDuration string `json:"duration"`
|
||||
|
||||
// Threshold in percentage beyond which the new version of the function is considered unstable
|
||||
FailureThreshold int `json:"failurethreshold"`
|
||||
FailureType FailureType `json:"failureType"`
|
||||
}
|
||||
|
||||
// CanaryConfig Status
|
||||
CanaryConfigStatus struct {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
)
|
||||
|
||||
// Each CRD type needs:
|
||||
// GetObjectKind (to satisfy the Object interface)
|
||||
//
|
||||
// In addition, each singular CRD type needs:
|
||||
// GetObjectMeta (to satisfy the ObjectMetaAccessor interface)
|
||||
//
|
||||
// And each list CRD type needs:
|
||||
// GetListMeta (to satisfy the ListMetaAccessor interface)
|
||||
|
||||
func (f *Function) GetObjectKind() schema.ObjectKind {
|
||||
return &f.TypeMeta
|
||||
}
|
||||
func (e *Environment) GetObjectKind() schema.ObjectKind {
|
||||
return &e.TypeMeta
|
||||
}
|
||||
func (ht *HTTPTrigger) GetObjectKind() schema.ObjectKind {
|
||||
return &ht.TypeMeta
|
||||
}
|
||||
func (w *KubernetesWatchTrigger) GetObjectKind() schema.ObjectKind {
|
||||
return &w.TypeMeta
|
||||
}
|
||||
func (t *TimeTrigger) GetObjectKind() schema.ObjectKind {
|
||||
return &t.TypeMeta
|
||||
}
|
||||
func (m *MessageQueueTrigger) GetObjectKind() schema.ObjectKind {
|
||||
return &m.TypeMeta
|
||||
}
|
||||
func (p *Package) GetObjectKind() schema.ObjectKind {
|
||||
return &p.TypeMeta
|
||||
}
|
||||
func (c *CanaryConfig) GetObjectKind() schema.ObjectKind {
|
||||
return &c.TypeMeta
|
||||
}
|
||||
|
||||
func (r *Recorder) GetObjectKind() schema.ObjectKind {
|
||||
return &r.TypeMeta
|
||||
}
|
||||
|
||||
func (f *Function) GetObjectMeta() metav1.Object {
|
||||
return &f.Metadata
|
||||
}
|
||||
func (e *Environment) GetObjectMeta() metav1.Object {
|
||||
return &e.Metadata
|
||||
}
|
||||
func (ht *HTTPTrigger) GetObjectMeta() metav1.Object {
|
||||
return &ht.Metadata
|
||||
}
|
||||
func (w *KubernetesWatchTrigger) GetObjectMeta() metav1.Object {
|
||||
return &w.Metadata
|
||||
}
|
||||
func (t *TimeTrigger) GetObjectMeta() metav1.Object {
|
||||
return &t.Metadata
|
||||
}
|
||||
func (m *MessageQueueTrigger) GetObjectMeta() metav1.Object {
|
||||
return &m.Metadata
|
||||
}
|
||||
func (p *Package) GetObjectMeta() metav1.Object {
|
||||
return &p.Metadata
|
||||
}
|
||||
func (c *CanaryConfig) GetObjectMeta() metav1.Object {
|
||||
return &c.Metadata
|
||||
}
|
||||
|
||||
func (r *Recorder) GetObjectMeta() metav1.Object {
|
||||
return &r.Metadata
|
||||
}
|
||||
|
||||
func (fl *FunctionList) GetObjectKind() schema.ObjectKind {
|
||||
return &fl.TypeMeta
|
||||
}
|
||||
func (el *EnvironmentList) GetObjectKind() schema.ObjectKind {
|
||||
return &el.TypeMeta
|
||||
}
|
||||
func (hl *HTTPTriggerList) GetObjectKind() schema.ObjectKind {
|
||||
return &hl.TypeMeta
|
||||
}
|
||||
func (wl *KubernetesWatchTriggerList) GetObjectKind() schema.ObjectKind {
|
||||
return &wl.TypeMeta
|
||||
}
|
||||
func (wl *TimeTriggerList) GetObjectKind() schema.ObjectKind {
|
||||
return &wl.TypeMeta
|
||||
}
|
||||
func (ml *MessageQueueTriggerList) GetObjectKind() schema.ObjectKind {
|
||||
return &ml.TypeMeta
|
||||
}
|
||||
func (pl *PackageList) GetObjectKind() schema.ObjectKind {
|
||||
return &pl.TypeMeta
|
||||
}
|
||||
func (rl *RecorderList) GetObjectKind() schema.ObjectKind {
|
||||
return &rl.TypeMeta
|
||||
}
|
||||
|
||||
func (cl *CanaryConfigList) GetObjectKind() schema.ObjectKind {
|
||||
return &cl.TypeMeta
|
||||
}
|
||||
|
||||
func (fl *FunctionList) GetListMeta() metav1.ListInterface {
|
||||
return &fl.Metadata
|
||||
}
|
||||
func (el *EnvironmentList) GetListMeta() metav1.ListInterface {
|
||||
return &el.Metadata
|
||||
}
|
||||
func (hl *HTTPTriggerList) GetListMeta() metav1.ListInterface {
|
||||
return &hl.Metadata
|
||||
}
|
||||
func (wl *KubernetesWatchTriggerList) GetListMeta() metav1.ListInterface {
|
||||
return &wl.Metadata
|
||||
}
|
||||
func (wl *TimeTriggerList) GetListMeta() metav1.ListInterface {
|
||||
return &wl.Metadata
|
||||
}
|
||||
func (ml *MessageQueueTriggerList) GetListMeta() metav1.ListInterface {
|
||||
return &ml.Metadata
|
||||
}
|
||||
func (pl *PackageList) GetListMeta() metav1.ListInterface {
|
||||
return &pl.Metadata
|
||||
}
|
||||
|
||||
func (rl *RecorderList) GetListMeta() metav1.ListInterface {
|
||||
return &rl.Metadata
|
||||
}
|
||||
|
||||
func (cl *CanaryConfigList) GetListMeta() metav1.ListInterface {
|
||||
return &cl.Metadata
|
||||
}
|
||||
|
||||
func validateMetadata(field string, m metav1.ObjectMeta) error {
|
||||
return ValidateKubeReference(field, m.Name, m.Namespace)
|
||||
}
|
||||
|
||||
func (p *Package) Validate() error {
|
||||
var result *multierror.Error
|
||||
|
||||
result = multierror.Append(result,
|
||||
validateMetadata("Package", p.Metadata),
|
||||
p.Spec.Validate(),
|
||||
p.Status.Validate())
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (pl *PackageList) Validate() error {
|
||||
var result *multierror.Error
|
||||
// not validate ListMeta
|
||||
for _, p := range pl.Items {
|
||||
result = multierror.Append(result, p.Validate())
|
||||
}
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (f *Function) Validate() error {
|
||||
var result *multierror.Error
|
||||
|
||||
result = multierror.Append(result,
|
||||
validateMetadata("Function", f.Metadata),
|
||||
f.Spec.Validate())
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (fl *FunctionList) Validate() error {
|
||||
var result *multierror.Error
|
||||
for _, f := range fl.Items {
|
||||
result = multierror.Append(result, f.Validate())
|
||||
}
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (e *Environment) Validate() error {
|
||||
var result *multierror.Error
|
||||
|
||||
result = multierror.Append(result,
|
||||
validateMetadata("Environment", e.Metadata),
|
||||
e.Spec.Validate())
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (el *EnvironmentList) Validate() error {
|
||||
var result *multierror.Error
|
||||
for _, e := range el.Items {
|
||||
result = multierror.Append(result, e.Validate())
|
||||
}
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (h *HTTPTrigger) Validate() error {
|
||||
var result *multierror.Error
|
||||
|
||||
result = multierror.Append(result,
|
||||
validateMetadata("HTTPTrigger", h.Metadata),
|
||||
h.Spec.Validate())
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (hl *HTTPTriggerList) Validate() error {
|
||||
var result *multierror.Error
|
||||
for _, h := range hl.Items {
|
||||
result = multierror.Append(result, h.Validate())
|
||||
}
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (k *KubernetesWatchTrigger) Validate() error {
|
||||
var result *multierror.Error
|
||||
|
||||
result = multierror.Append(result,
|
||||
validateMetadata("KubernetesWatchTrigger", k.Metadata),
|
||||
k.Spec.Validate())
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (kl *KubernetesWatchTriggerList) Validate() error {
|
||||
var result *multierror.Error
|
||||
for _, k := range kl.Items {
|
||||
result = multierror.Append(result, k.Validate())
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (t *TimeTrigger) Validate() error {
|
||||
var result *multierror.Error
|
||||
|
||||
result = multierror.Append(result,
|
||||
validateMetadata("TimeTrigger", t.Metadata),
|
||||
t.Spec.Validate())
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (tl *TimeTriggerList) Validate() error {
|
||||
var result *multierror.Error
|
||||
for _, t := range tl.Items {
|
||||
result = multierror.Append(result, t.Validate())
|
||||
}
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (m *MessageQueueTrigger) Validate() error {
|
||||
var result *multierror.Error
|
||||
|
||||
result = multierror.Append(result,
|
||||
validateMetadata("MessageQueueTrigger", m.Metadata),
|
||||
m.Spec.Validate())
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (ml *MessageQueueTriggerList) Validate() error {
|
||||
var result *multierror.Error
|
||||
for _, m := range ml.Items {
|
||||
result = multierror.Append(result, m.Validate())
|
||||
}
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (r *Recorder) Validate() error {
|
||||
var result *multierror.Error
|
||||
|
||||
result = multierror.Append(result,
|
||||
validateMetadata("Recorder", r.Metadata),
|
||||
r.Spec.Validate())
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
@@ -270,6 +270,8 @@ func (api *API) Serve(port int) {
|
||||
r.HandleFunc("/proxy/workflows-apiserver/{path:.*}", api.WorkflowApiserverProxy)
|
||||
r.HandleFunc("/proxy/svcname", api.GetSvcName).Queries("application", "").Methods("GET")
|
||||
|
||||
r.Handle("/v2/apidocs.json", openAPI()).Methods("GET")
|
||||
|
||||
address := fmt.Sprintf(":%v", port)
|
||||
|
||||
api.logger.Info("server started", zap.Int("port", port))
|
||||
|
||||
@@ -22,6 +22,9 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
restfulspec "github.com/emicklei/go-restful-openapi"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/gorilla/mux"
|
||||
"go.uber.org/zap"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -31,6 +34,73 @@ import (
|
||||
config "github.com/fission/fission/pkg/featureconfig"
|
||||
)
|
||||
|
||||
func RegisterCanaryConfigRoute(ws *restful.WebService) {
|
||||
tags := []string{"CanaryConfig"}
|
||||
specTag = append(specTag, spec.Tag{TagProps: spec.TagProps{Name: "CanaryConfig", Description: "CanaryConfig Operation"}})
|
||||
|
||||
ws.Route(
|
||||
ws.GET("/v2/canaryconfigs").
|
||||
Doc("List all canary configs").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of canaryConfig").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Writes([]fv1.CanaryConfig{}).
|
||||
Returns(http.StatusOK, "List of canaryConfigs", []fv1.CanaryConfig{}))
|
||||
|
||||
ws.Route(
|
||||
ws.POST("/v2/canaryconfigs").
|
||||
Doc("Create canary config").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Produces(restful.MIME_JSON).
|
||||
Reads(fv1.CanaryConfig{}).
|
||||
Writes(metav1.ObjectMeta{}).
|
||||
Returns(http.StatusCreated, "Metadata of created canaryConfig", metav1.ObjectMeta{}))
|
||||
|
||||
ws.Route(
|
||||
ws.GET("/v2/canaryconfigs/{canaryConfig}").
|
||||
Doc("Get detail of canary config").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("canaryConfig", "CanaryConfig name").DataType("string").DefaultValue("").Required(true)).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of canaryConfig").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Writes(fv1.CanaryConfig{}). // on the response
|
||||
Returns(http.StatusOK, "A canaryConfig", fv1.CanaryConfig{}))
|
||||
|
||||
ws.Route(
|
||||
ws.PUT("/v2/canaryconfigs/{canaryConfig}").
|
||||
Doc("Update canary config").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("canaryConfig", "CanaryConfig name").DataType("string").DefaultValue("").Required(true)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Reads(fv1.CanaryConfig{}).
|
||||
Writes(metav1.ObjectMeta{}). // on the response
|
||||
Returns(http.StatusOK, "Metadata of updated canaryConfig", metav1.ObjectMeta{}))
|
||||
|
||||
ws.Route(
|
||||
ws.DELETE("/v2/canaryconfigs/{canaryConfig}").
|
||||
Doc("Delete canary config").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("canaryConfig", "CanaryConfig name").DataType("string").DefaultValue("").Required(true)).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of canaryConfig").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Returns(http.StatusOK, "Only HTTP status returned", nil))
|
||||
}
|
||||
|
||||
func (a *API) CanaryConfigApiCreate(w http.ResponseWriter, r *http.Request) {
|
||||
featureErr := a.featureStatus[config.CanaryFeature]
|
||||
if len(featureErr) > 0 {
|
||||
|
||||
@@ -49,6 +49,9 @@ func Start(logger *zap.Logger, port int, unitTestFlag bool) {
|
||||
}
|
||||
defer cancel()
|
||||
|
||||
// openapi service
|
||||
//go openAPI(cLogger)
|
||||
|
||||
api, err := MakeAPI(cLogger, featureStatus)
|
||||
if err != nil {
|
||||
cLogger.Fatal("failed to start controller", zap.Error(err))
|
||||
|
||||
@@ -21,6 +21,9 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
restfulspec "github.com/emicklei/go-restful-openapi"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/gorilla/mux"
|
||||
"go.uber.org/zap"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -29,6 +32,73 @@ import (
|
||||
ferror "github.com/fission/fission/pkg/error"
|
||||
)
|
||||
|
||||
func RegisterEnvironmentRoute(ws *restful.WebService) {
|
||||
tags := []string{"Environment"}
|
||||
specTag = append(specTag, spec.Tag{TagProps: spec.TagProps{Name: "Environment", Description: "Environment Operation"}})
|
||||
|
||||
ws.Route(
|
||||
ws.GET("/v2/environments").
|
||||
Doc("List all environments").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of environment").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Writes([]fv1.Environment{}).
|
||||
Returns(http.StatusOK, "List of environments", []fv1.Environment{}))
|
||||
|
||||
ws.Route(
|
||||
ws.POST("/v2/environments").
|
||||
Doc("Create environment").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Produces(restful.MIME_JSON).
|
||||
Reads(fv1.Environment{}).
|
||||
Writes(metav1.ObjectMeta{}).
|
||||
Returns(http.StatusCreated, "Metadata of created environment", metav1.ObjectMeta{}))
|
||||
|
||||
ws.Route(
|
||||
ws.GET("/v2/environments/{environment}").
|
||||
Doc("Get detail of environment").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("environment", "Environment name").DataType("string").DefaultValue("").Required(true)).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of environment").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Writes(fv1.Environment{}). // on the response
|
||||
Returns(http.StatusOK, "A environment", fv1.Environment{}))
|
||||
|
||||
ws.Route(
|
||||
ws.PUT("/v2/environments/{environment}").
|
||||
Doc("Update environment").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("environment", "Environment name").DataType("string").DefaultValue("").Required(true)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Reads(fv1.Environment{}).
|
||||
Writes(metav1.ObjectMeta{}). // on the response
|
||||
Returns(http.StatusOK, "Metadata of updated environment", metav1.ObjectMeta{}))
|
||||
|
||||
ws.Route(
|
||||
ws.DELETE("/v2/environments/{environment}").
|
||||
Doc("Delete environment").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("environment", "Environment name").DataType("string").DefaultValue("").Required(true)).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of environment").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Returns(http.StatusOK, "Only HTTP status returned", nil))
|
||||
}
|
||||
|
||||
func (a *API) EnvironmentApiList(w http.ResponseWriter, r *http.Request) {
|
||||
ns := a.extractQueryParamFromRequest(r, "namespace")
|
||||
if len(ns) == 0 {
|
||||
|
||||
@@ -26,6 +26,9 @@ import (
|
||||
"net/url"
|
||||
"sort"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
restfulspec "github.com/emicklei/go-restful-openapi"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/gorilla/mux"
|
||||
"go.uber.org/zap"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
@@ -36,6 +39,73 @@ import (
|
||||
ferror "github.com/fission/fission/pkg/error"
|
||||
)
|
||||
|
||||
func RegisterFunctionRoute(ws *restful.WebService) {
|
||||
tags := []string{"Function"}
|
||||
specTag = append(specTag, spec.Tag{TagProps: spec.TagProps{Name: "Function", Description: "Function Operation"}})
|
||||
|
||||
ws.Route(
|
||||
ws.GET("/v2/functions").
|
||||
Doc("List all functions").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of function").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Writes([]fv1.Function{}).
|
||||
Returns(http.StatusOK, "List of functions", []fv1.Function{}))
|
||||
|
||||
ws.Route(
|
||||
ws.POST("/v2/functions").
|
||||
Doc("Create function").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Produces(restful.MIME_JSON).
|
||||
Reads(fv1.Function{}).
|
||||
Writes(metav1.ObjectMeta{}).
|
||||
Returns(http.StatusOK, "Metadata of created function", metav1.ObjectMeta{}))
|
||||
|
||||
ws.Route(
|
||||
ws.GET("/v2/functions/{function}").
|
||||
Doc("Get detail of function").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("function", "Function name").DataType("string").DefaultValue("").Required(true)).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of function").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Writes(fv1.Function{}). // on the response
|
||||
Returns(http.StatusOK, "A function", fv1.Function{}))
|
||||
|
||||
ws.Route(
|
||||
ws.PUT("/v2/functions/{function}").
|
||||
Doc("Update function").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("function", "Function name").DataType("string").DefaultValue("").Required(true)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Reads(fv1.Function{}).
|
||||
Writes(metav1.ObjectMeta{}). // on the response
|
||||
Returns(http.StatusOK, "Metadata of updated function", metav1.ObjectMeta{}))
|
||||
|
||||
ws.Route(
|
||||
ws.DELETE("/v2/functions/{function}").
|
||||
Doc("Delete function").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("function", "Function name").DataType("string").DefaultValue("").Required(true)).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of function").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Returns(http.StatusOK, "Only HTTP status returned", nil))
|
||||
}
|
||||
|
||||
func (a *API) getIstioServiceLabels(fnName string) map[string]string {
|
||||
return map[string]string{
|
||||
"functionName": fnName,
|
||||
|
||||
@@ -22,6 +22,9 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
restfulspec "github.com/emicklei/go-restful-openapi"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/gorilla/mux"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
@@ -29,6 +32,73 @@ import (
|
||||
ferror "github.com/fission/fission/pkg/error"
|
||||
)
|
||||
|
||||
func RegisterHTTPTriggerRoute(ws *restful.WebService) {
|
||||
tags := []string{"HTTPTrigger"}
|
||||
specTag = append(specTag, spec.Tag{TagProps: spec.TagProps{Name: "HTTPTrigger", Description: "HTTPTrigger Operation"}})
|
||||
|
||||
ws.Route(
|
||||
ws.GET("/v2/triggers/http").
|
||||
Doc("List all HTTP triggers").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of httpTrigger").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Writes([]fv1.HTTPTrigger{}).
|
||||
Returns(http.StatusOK, "List of httpTriggers", []fv1.HTTPTrigger{}))
|
||||
|
||||
ws.Route(
|
||||
ws.POST("/v2/triggers/http").
|
||||
Doc("Create HTTP trigger").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Produces(restful.MIME_JSON).
|
||||
Reads(fv1.HTTPTrigger{}).
|
||||
Writes(metav1.ObjectMeta{}).
|
||||
Returns(http.StatusCreated, "Metadata of created httpTrigger", metav1.ObjectMeta{}))
|
||||
|
||||
ws.Route(
|
||||
ws.GET("/v2/triggers/http/{httpTrigger}").
|
||||
Doc("Get detail of HTTP trigger").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("httpTrigger", "HTTPTrigger name").DataType("string").DefaultValue("").Required(true)).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of httpTrigger").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Writes(fv1.HTTPTrigger{}). // on the response
|
||||
Returns(http.StatusOK, "A httpTrigger", fv1.HTTPTrigger{}))
|
||||
|
||||
ws.Route(
|
||||
ws.PUT("/v2/triggers/http/{httpTrigger}").
|
||||
Doc("Update HTTP trigger").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("httpTrigger", "HTTPTrigger name").DataType("string").DefaultValue("").Required(true)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Reads(fv1.HTTPTrigger{}).
|
||||
Writes(metav1.ObjectMeta{}). // on the response
|
||||
Returns(http.StatusOK, "Metadata of updated httpTrigger", metav1.ObjectMeta{}))
|
||||
|
||||
ws.Route(
|
||||
ws.DELETE("/v2/triggers/http/{httpTrigger}").
|
||||
Doc("Delete HTTP trigger").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("httpTrigger", "HTTPTrigger name").DataType("string").DefaultValue("").Required(true)).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of httpTrigger").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Returns(http.StatusOK, "Only HTTP status returned", nil))
|
||||
}
|
||||
|
||||
func (a *API) HTTPTriggerApiList(w http.ResponseWriter, r *http.Request) {
|
||||
ns := a.extractQueryParamFromRequest(r, "namespace")
|
||||
if len(ns) == 0 {
|
||||
|
||||
@@ -21,6 +21,9 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
restfulspec "github.com/emicklei/go-restful-openapi"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/gorilla/mux"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
@@ -28,6 +31,73 @@ import (
|
||||
ferror "github.com/fission/fission/pkg/error"
|
||||
)
|
||||
|
||||
func RegisterMessageQueueTriggerRoute(ws *restful.WebService) {
|
||||
tags := []string{"MessageQueueTrigger"}
|
||||
specTag = append(specTag, spec.Tag{TagProps: spec.TagProps{Name: "MessageQueueTrigger", Description: "MessageQueueTrigger Operation"}})
|
||||
|
||||
ws.Route(
|
||||
ws.GET("/v2/triggers/messagequeue").
|
||||
Doc("List all message queue triggers").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of messageQueueTrigger").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Writes([]fv1.MessageQueueTrigger{}).
|
||||
Returns(http.StatusOK, "List of messageQueueTriggers", []fv1.MessageQueueTrigger{}))
|
||||
|
||||
ws.Route(
|
||||
ws.POST("/v2/triggers/messagequeue").
|
||||
Doc("Create message queue trigger").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Produces(restful.MIME_JSON).
|
||||
Reads(fv1.MessageQueueTrigger{}).
|
||||
Writes(metav1.ObjectMeta{}).
|
||||
Returns(http.StatusCreated, "Metadata of created messageQueueTrigger", metav1.ObjectMeta{}))
|
||||
|
||||
ws.Route(
|
||||
ws.GET("/v2/triggers/messagequeue/{mqTrigger}").
|
||||
Doc("Get detail of message queue trigger").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("mqTrigger", "MessageQueueTriggers name").DataType("string").DefaultValue("").Required(true)).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of messageQueueTrigger").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Writes(fv1.MessageQueueTrigger{}). // on the response
|
||||
Returns(http.StatusOK, "A messageQueueTrigger", fv1.MessageQueueTrigger{}))
|
||||
|
||||
ws.Route(
|
||||
ws.PUT("/v2/triggers/messagequeue/{mqTrigger}").
|
||||
Doc("Update message queue trigger").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("mqTrigger", "MessageQueueTrigger name").DataType("string").DefaultValue("").Required(true)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Reads(fv1.MessageQueueTrigger{}).
|
||||
Writes(metav1.ObjectMeta{}). // on the response
|
||||
Returns(http.StatusOK, "Metadata of updated messageQueueTrigger", metav1.ObjectMeta{}))
|
||||
|
||||
ws.Route(
|
||||
ws.DELETE("/v2/triggers/messagequeue/{mqTrigger}").
|
||||
Doc("Delete message queue trigger").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("mqTrigger", "MessageQueueTrigger name").DataType("string").DefaultValue("").Required(true)).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of messageQueueTrigger").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Returns(http.StatusOK, "Only HTTP status returned", nil))
|
||||
}
|
||||
|
||||
func (a *API) MessageQueueTriggerApiList(w http.ResponseWriter, r *http.Request) {
|
||||
//mqType := r.FormValue("mqtype") // ignored for now
|
||||
ns := a.extractQueryParamFromRequest(r, "namespace")
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright 2019 The Fission 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.
|
||||
*/
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
restfulspec "github.com/emicklei/go-restful-openapi"
|
||||
"github.com/go-openapi/spec"
|
||||
)
|
||||
|
||||
var specTag []spec.Tag
|
||||
|
||||
func openAPI() http.Handler {
|
||||
restful.DefaultContainer.Add(openAPIWebService())
|
||||
|
||||
config := restfulspec.Config{
|
||||
WebServices: restful.RegisteredWebServices(),
|
||||
APIPath: "/v2/apidocs.json",
|
||||
PostBuildSwaggerObjectHandler: enrichSwaggerObject}
|
||||
|
||||
restful.DefaultContainer.Add(restfulspec.NewOpenAPIService(config))
|
||||
|
||||
return restful.DefaultContainer
|
||||
}
|
||||
|
||||
func openAPIWebService() *restful.WebService {
|
||||
ws := new(restful.WebService)
|
||||
|
||||
// CRD resource
|
||||
RegisterEnvironmentRoute(ws)
|
||||
RegisterFunctionRoute(ws)
|
||||
RegisterHTTPTriggerRoute(ws)
|
||||
RegisterMessageQueueTriggerRoute(ws)
|
||||
RegisterPackageRoute(ws)
|
||||
RegisterWatchRoute(ws)
|
||||
RegisterTimeTriggerRoute(ws)
|
||||
RegisterCanaryConfigRoute(ws)
|
||||
|
||||
// proxy
|
||||
RegisterStorageServiceProxyRoute(ws)
|
||||
|
||||
return ws
|
||||
}
|
||||
|
||||
func enrichSwaggerObject(swo *spec.Swagger) {
|
||||
swo.Info = &spec.Info{
|
||||
InfoProps: spec.InfoProps{
|
||||
Title: "Fission OpenAPI 2.0",
|
||||
Description: openapiDescription,
|
||||
Version: "v1",
|
||||
},
|
||||
}
|
||||
swo.Tags = specTag
|
||||
}
|
||||
|
||||
var openapiDescription = `
|
||||
OpenAPI 2.0 document for fission controller
|
||||
* Metadata (v1.ObjectMeta) should be empty when creating a CRD resource. Kubernetes will assign it automatically.
|
||||
* Following semantic errors are known issues and won't affect the API accessibility.
|
||||
- Operations must have unique operationIds.
|
||||
- All scale semantic errors. (Due to go-restful exposes inner fields of k8s struct).
|
||||
`
|
||||
@@ -23,7 +23,10 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/emicklei/go-restful"
|
||||
restfulspec "github.com/emicklei/go-restful-openapi"
|
||||
"github.com/fission/fission/pkg/types"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/gorilla/mux"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
@@ -31,6 +34,73 @@ import (
|
||||
ferror "github.com/fission/fission/pkg/error"
|
||||
)
|
||||
|
||||
func RegisterPackageRoute(ws *restful.WebService) {
|
||||
tags := []string{"Package"}
|
||||
specTag = append(specTag, spec.Tag{TagProps: spec.TagProps{Name: "Package", Description: "Package Operation"}})
|
||||
|
||||
ws.Route(
|
||||
ws.GET("/v2/packages").
|
||||
Doc("List all packages").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of package").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Writes([]fv1.Package{}).
|
||||
Returns(http.StatusOK, "List of packages", []fv1.Package{}))
|
||||
|
||||
ws.Route(
|
||||
ws.POST("/v2/packages").
|
||||
Doc("Create package").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Produces(restful.MIME_JSON).
|
||||
Reads(fv1.Package{}).
|
||||
Writes(metav1.ObjectMeta{}).
|
||||
Returns(http.StatusCreated, "Metadata of created package", metav1.ObjectMeta{}))
|
||||
|
||||
ws.Route(
|
||||
ws.GET("/v2/packages/{package}").
|
||||
Doc("Get detail of package").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("package", "Package name").DataType("string").DefaultValue("").Required(true)).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of package").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Writes(fv1.Package{}). // on the response
|
||||
Returns(http.StatusOK, "A package", fv1.Package{}))
|
||||
|
||||
ws.Route(
|
||||
ws.PUT("/v2/packages/{package}").
|
||||
Doc("Update package").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("package", "Package name").DataType("string").DefaultValue("").Required(true)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Reads(fv1.Package{}).
|
||||
Writes(metav1.ObjectMeta{}). // on the response
|
||||
Returns(http.StatusOK, "Metadata of updated package", metav1.ObjectMeta{}))
|
||||
|
||||
ws.Route(
|
||||
ws.DELETE("/v2/packages/{package}").
|
||||
Doc("Delete package").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("package", "Package name").DataType("string").DefaultValue("").Required(true)).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of package").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Returns(http.StatusOK, "Only HTTP status returned", nil))
|
||||
}
|
||||
|
||||
func (a *API) PackageApiList(w http.ResponseWriter, r *http.Request) {
|
||||
ns := a.extractQueryParamFromRequest(r, "namespace")
|
||||
if len(ns) == 0 {
|
||||
|
||||
@@ -22,9 +22,40 @@ import (
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
restfulspec "github.com/emicklei/go-restful-openapi"
|
||||
"github.com/go-openapi/spec"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func RegisterStorageServiceProxyRoute(ws *restful.WebService) {
|
||||
tags := []string{"StorageServiceProxy"}
|
||||
specTag = append(specTag, spec.Tag{TagProps: spec.TagProps{Name: "StorageServiceProxy", Description: "StorageServiceProxy Operation"}})
|
||||
|
||||
// workaround as go-restful has to set HTTP method explicitly.
|
||||
ws.Route(
|
||||
ws.POST("/proxy/storage/v1/archive").
|
||||
Doc("Create archive").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
ws.Route(
|
||||
ws.GET("/proxy/storage/v1/archive").
|
||||
Doc("Get archive").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
ws.Route(
|
||||
ws.DELETE("/proxy/storage/v1/archive").
|
||||
Doc("Delete archive").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
}
|
||||
|
||||
func (api *API) StorageServiceProxy(w http.ResponseWriter, r *http.Request) {
|
||||
u := api.storageServiceUrl
|
||||
ssUrl, err := url.Parse(u)
|
||||
|
||||
@@ -21,6 +21,9 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
restfulspec "github.com/emicklei/go-restful-openapi"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/robfig/cron"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -29,6 +32,73 @@ import (
|
||||
ferror "github.com/fission/fission/pkg/error"
|
||||
)
|
||||
|
||||
func RegisterTimeTriggerRoute(ws *restful.WebService) {
|
||||
tags := []string{"TimeTrigger"}
|
||||
specTag = append(specTag, spec.Tag{TagProps: spec.TagProps{Name: "TimeTrigger", Description: "TimeTrigger Operation"}})
|
||||
|
||||
ws.Route(
|
||||
ws.GET("/v2/triggers/time").
|
||||
Doc("List all time trigger").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of timeTrigger").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Writes([]fv1.TimeTrigger{}).
|
||||
Returns(http.StatusOK, "List of timeTriggers", []fv1.TimeTrigger{}))
|
||||
|
||||
ws.Route(
|
||||
ws.POST("/v2/triggers/time").
|
||||
Doc("Create time trigger").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Produces(restful.MIME_JSON).
|
||||
Reads(fv1.TimeTrigger{}).
|
||||
Writes(metav1.ObjectMeta{}).
|
||||
Returns(http.StatusCreated, "Metadata of created timeTrigger", metav1.ObjectMeta{}))
|
||||
|
||||
ws.Route(
|
||||
ws.GET("/v2/triggers/time/{timeTrigger}").
|
||||
Doc("Get detail of time trigger").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("timeTrigger", "TimeTrigger name").DataType("string").DefaultValue("").Required(true)).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of timeTrigger").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Writes(fv1.TimeTrigger{}). // on the response
|
||||
Returns(http.StatusOK, "A timeTrigger", fv1.TimeTrigger{}))
|
||||
|
||||
ws.Route(
|
||||
ws.PUT("/v2/triggers/time/{timeTrigger}").
|
||||
Doc("Update time trigger").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("timeTrigger", "TimeTrigger name").DataType("string").DefaultValue("").Required(true)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Reads(fv1.TimeTrigger{}).
|
||||
Writes(metav1.ObjectMeta{}). // on the response
|
||||
Returns(http.StatusOK, "Metadata of updated timeTrigger", metav1.ObjectMeta{}))
|
||||
|
||||
ws.Route(
|
||||
ws.DELETE("/v2/triggers/time/{timeTrigger}").
|
||||
Doc("Delete time trigger").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("timeTrigger", "TimeTrigger name").DataType("string").DefaultValue("").Required(true)).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of timeTrigger").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Returns(http.StatusOK, "Only HTTP status returned", nil))
|
||||
}
|
||||
|
||||
func (a *API) TimeTriggerApiList(w http.ResponseWriter, r *http.Request) {
|
||||
ns := a.extractQueryParamFromRequest(r, "namespace")
|
||||
if len(ns) == 0 {
|
||||
|
||||
@@ -21,6 +21,9 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
restfulspec "github.com/emicklei/go-restful-openapi"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/gorilla/mux"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
@@ -28,6 +31,73 @@ import (
|
||||
ferror "github.com/fission/fission/pkg/error"
|
||||
)
|
||||
|
||||
func RegisterWatchRoute(ws *restful.WebService) {
|
||||
tags := []string{"KubernetesWatch"}
|
||||
specTag = append(specTag, spec.Tag{TagProps: spec.TagProps{Name: "KubernetesWatch", Description: "KubernetesWatch Operation"}})
|
||||
|
||||
ws.Route(
|
||||
ws.GET("/v2/watches").
|
||||
Doc("List all kubernetes watch").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of kubernetesWatch").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Writes([]fv1.KubernetesWatchTrigger{}).
|
||||
Returns(http.StatusOK, "List of kubernetesWatchs", []fv1.KubernetesWatchTrigger{}))
|
||||
|
||||
ws.Route(
|
||||
ws.POST("/v2/watches").
|
||||
Doc("Create kubernetes watch").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Produces(restful.MIME_JSON).
|
||||
Reads(fv1.KubernetesWatchTrigger{}).
|
||||
Writes(metav1.ObjectMeta{}).
|
||||
Returns(http.StatusCreated, "Metadata of created kubernetesWatch", metav1.ObjectMeta{}))
|
||||
|
||||
ws.Route(
|
||||
ws.GET("/v2/watches/{watch}").
|
||||
Doc("Get detail of kubernetes watch").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("watch", "KubernetesWatch name").DataType("string").DefaultValue("").Required(true)).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of kubernetesWatch").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Writes(fv1.KubernetesWatchTrigger{}). // on the response
|
||||
Returns(http.StatusOK, "A kubernetesWatch", fv1.KubernetesWatchTrigger{}))
|
||||
|
||||
ws.Route(
|
||||
ws.PUT("/v2/watches/{watch}").
|
||||
Doc("Update kubernetes watch").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("watch", "KubernetesWatch name").DataType("string").DefaultValue("").Required(true)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Reads(fv1.KubernetesWatchTrigger{}).
|
||||
Writes(metav1.ObjectMeta{}). // on the response
|
||||
Returns(http.StatusOK, "Metadata of updated kubernetesWatch", metav1.ObjectMeta{}))
|
||||
|
||||
ws.Route(
|
||||
ws.DELETE("/v2/watches/{watch}").
|
||||
Doc("Delete kubernetes watch").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(func(req *restful.Request, resp *restful.Response) {
|
||||
resp.ResponseWriter.WriteHeader(http.StatusOK)
|
||||
}).
|
||||
Param(ws.PathParameter("watch", "KubernetesWatch name").DataType("string").DefaultValue("").Required(true)).
|
||||
Param(ws.QueryParameter("namespace", "Namespace of kubernetesWatch").DataType("string").DefaultValue(metav1.NamespaceAll).Required(false)).
|
||||
Produces(restful.MIME_JSON).
|
||||
Returns(http.StatusOK, "Only HTTP status returned", nil))
|
||||
}
|
||||
|
||||
func (a *API) WatchApiList(w http.ResponseWriter, r *http.Request) {
|
||||
ns := a.extractQueryParamFromRequest(r, "namespace")
|
||||
if len(ns) == 0 {
|
||||
|
||||
@@ -5,7 +5,7 @@ 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
|
||||
|
||||
tttp://www.apache.org/licenses/LICENSE-2.0
|
||||
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,
|
||||
|
||||
@@ -5,7 +5,7 @@ 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
|
||||
|
||||
tttp://www.apache.org/licenses/LICENSE-2.0
|
||||
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,
|
||||
|
||||
@@ -5,7 +5,7 @@ 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
|
||||
|
||||
tttp://www.apache.org/licenses/LICENSE-2.0
|
||||
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,
|
||||
|
||||
@@ -5,7 +5,7 @@ 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
|
||||
|
||||
tttp://www.apache.org/licenses/LICENSE-2.0
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user