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:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user