add swagger ui
This commit is contained in:
@@ -6,5 +6,5 @@ RUN apk add --update ca-certificates \
|
||||
|
||||
COPY ./bin/* /usr/local/bin/
|
||||
COPY ./install/ingress-controller /etc/kubesphere/ingress-controller
|
||||
|
||||
COPY ./install/swagger-ui /usr/lib/kubesphere/swagger-ui
|
||||
CMD ["sh"]
|
||||
|
||||
65
Gopkg.lock
generated
65
Gopkg.lock
generated
@@ -7,6 +7,18 @@
|
||||
revision = "7da180ee92d8bd8bb8c37fc560e673e6557c392f"
|
||||
version = "v0.4.7"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/PuerkitoBio/purell"
|
||||
packages = ["."]
|
||||
revision = "0bcb03f4b4d0a9428594752bd2a3b9aa0a9d4bd4"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/PuerkitoBio/urlesc"
|
||||
packages = ["."]
|
||||
revision = "de5bf2ad457846296e2031421a34e2568e304e35"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/Sirupsen/logrus"
|
||||
packages = ["."]
|
||||
@@ -116,12 +128,42 @@
|
||||
revision = "3658237ded108b4134956c1b3050349d93e7b895"
|
||||
version = "v2.7.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/emicklei/go-restful-openapi"
|
||||
packages = ["."]
|
||||
revision = "51bf251d405ad1e23511fef0a2dbe40bc70ce2c6"
|
||||
version = "v0.11.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/ghodss/yaml"
|
||||
packages = ["."]
|
||||
revision = "0ca9ea5df5451ffdf184b4428c902747c2c11cd7"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/go-openapi/jsonpointer"
|
||||
packages = ["."]
|
||||
revision = "3a0015ad55fa9873f41605d3e8f28cd279c32ab2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/go-openapi/jsonreference"
|
||||
packages = ["."]
|
||||
revision = "3fb327e6747da3043567ee86abd02bb6376b6be2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/go-openapi/spec"
|
||||
packages = ["."]
|
||||
revision = "bce47c9386f9ecd6b86f450478a80103c3fe1402"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/go-openapi/swag"
|
||||
packages = ["."]
|
||||
revision = "2b0bd4f193d011c203529df626a65d63cb8a79e8"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/go-sql-driver/mysql"
|
||||
packages = ["."]
|
||||
@@ -218,6 +260,16 @@
|
||||
revision = "ca39e5af3ece67bbcda3d0f4f56a8e24d9f2dad4"
|
||||
version = "1.1.3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mailru/easyjson"
|
||||
packages = [
|
||||
"buffer",
|
||||
"jlexer",
|
||||
"jwriter"
|
||||
]
|
||||
revision = "3fdea8d05856a0c8df22ed4bc71b3219245e4485"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/modern-go/concurrent"
|
||||
packages = ["."]
|
||||
@@ -275,8 +327,14 @@
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = [
|
||||
"cpu",
|
||||
"unix",
|
||||
"windows"
|
||||
"windows",
|
||||
"windows/registry",
|
||||
"windows/svc",
|
||||
"windows/svc/debug",
|
||||
"windows/svc/eventlog",
|
||||
"windows/svc/mgr"
|
||||
]
|
||||
revision = "fc8bd948cf46f9c7af0f07d34151ce25fe90e477"
|
||||
|
||||
@@ -296,7 +354,8 @@
|
||||
"unicode/bidi",
|
||||
"unicode/cldr",
|
||||
"unicode/norm",
|
||||
"unicode/rangetable"
|
||||
"unicode/rangetable",
|
||||
"width"
|
||||
]
|
||||
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
|
||||
version = "v0.3.0"
|
||||
@@ -591,6 +650,6 @@
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "afd0a3a0e96a5054e6b99afd53b78888125726fc89c62f121984cd73a6ca4fb3"
|
||||
inputs-digest = "9f1ac4fe878dadee802b8971f67ba69171326c81e2c379247015003f2e0ba134"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
||||
BIN
install/swagger-ui/favicon-16x16.png
Normal file
BIN
install/swagger-ui/favicon-16x16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 445 B |
BIN
install/swagger-ui/favicon-32x32.png
Normal file
BIN
install/swagger-ui/favicon-32x32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
60
install/swagger-ui/index.html
Normal file
60
install/swagger-ui/index.html
Normal file
@@ -0,0 +1,60 @@
|
||||
<!-- HTML for static distribution bundle build -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Swagger UI</title>
|
||||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
|
||||
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
|
||||
<style>
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="./swagger-ui-bundle.js"> </script>
|
||||
<script src="./swagger-ui-standalone-preset.js"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
|
||||
// Build a system
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "/swagger-ui/api.json",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
|
||||
window.ui = ui
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
67
install/swagger-ui/oauth2-redirect.html
Normal file
67
install/swagger-ui/oauth2-redirect.html
Normal file
@@ -0,0 +1,67 @@
|
||||
<!doctype html>
|
||||
<html lang="en-US">
|
||||
<body onload="run()">
|
||||
</body>
|
||||
</html>
|
||||
<script>
|
||||
'use strict';
|
||||
function run () {
|
||||
var oauth2 = window.opener.swaggerUIRedirectOauth2;
|
||||
var sentState = oauth2.state;
|
||||
var redirectUrl = oauth2.redirectUrl;
|
||||
var isValid, qp, arr;
|
||||
|
||||
if (/code|token|error/.test(window.location.hash)) {
|
||||
qp = window.location.hash.substring(1);
|
||||
} else {
|
||||
qp = location.search.substring(1);
|
||||
}
|
||||
|
||||
arr = qp.split("&")
|
||||
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
|
||||
qp = qp ? JSON.parse('{' + arr.join() + '}',
|
||||
function (key, value) {
|
||||
return key === "" ? value : decodeURIComponent(value)
|
||||
}
|
||||
) : {}
|
||||
|
||||
isValid = qp.state === sentState
|
||||
|
||||
if ((
|
||||
oauth2.auth.schema.get("flow") === "accessCode"||
|
||||
oauth2.auth.schema.get("flow") === "authorizationCode"
|
||||
) && !oauth2.auth.code) {
|
||||
if (!isValid) {
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "warning",
|
||||
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
|
||||
});
|
||||
}
|
||||
|
||||
if (qp.code) {
|
||||
delete oauth2.state;
|
||||
oauth2.auth.code = qp.code;
|
||||
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
|
||||
} else {
|
||||
let oauthErrorMsg
|
||||
if (qp.error) {
|
||||
oauthErrorMsg = "["+qp.error+"]: " +
|
||||
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
|
||||
(qp.error_uri ? "More info: "+qp.error_uri : "");
|
||||
}
|
||||
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "error",
|
||||
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
|
||||
});
|
||||
}
|
||||
} else {
|
||||
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
|
||||
}
|
||||
window.close();
|
||||
}
|
||||
</script>
|
||||
104
install/swagger-ui/swagger-ui-bundle.js
Normal file
104
install/swagger-ui/swagger-ui-bundle.js
Normal file
File diff suppressed because one or more lines are too long
1
install/swagger-ui/swagger-ui-bundle.js.map
Normal file
1
install/swagger-ui/swagger-ui-bundle.js.map
Normal file
File diff suppressed because one or more lines are too long
14
install/swagger-ui/swagger-ui-standalone-preset.js
Normal file
14
install/swagger-ui/swagger-ui-standalone-preset.js
Normal file
File diff suppressed because one or more lines are too long
1
install/swagger-ui/swagger-ui-standalone-preset.js.map
Normal file
1
install/swagger-ui/swagger-ui-standalone-preset.js.map
Normal file
File diff suppressed because one or more lines are too long
3
install/swagger-ui/swagger-ui.css
Normal file
3
install/swagger-ui/swagger-ui.css
Normal file
File diff suppressed because one or more lines are too long
1
install/swagger-ui/swagger-ui.css.map
Normal file
1
install/swagger-ui/swagger-ui.css.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":[],"names":[],"mappings":"","file":"swagger-ui.css","sourceRoot":""}
|
||||
9
install/swagger-ui/swagger-ui.js
Normal file
9
install/swagger-ui/swagger-ui.js
Normal file
File diff suppressed because one or more lines are too long
1
install/swagger-ui/swagger-ui.js.map
Normal file
1
install/swagger-ui/swagger-ui.js.map
Normal file
File diff suppressed because one or more lines are too long
@@ -21,14 +21,23 @@ import (
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
|
||||
"github.com/emicklei/go-restful-openapi"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
)
|
||||
|
||||
func Register(ws *restful.WebService, subPath string) {
|
||||
|
||||
ws.Route(ws.GET(subPath).To(getClusterQuota).Produces(restful.MIME_JSON))
|
||||
ws.Route(ws.GET(subPath + "/namespaces/{namespace}").To(getNamespaceQuota).Produces(restful.MIME_JSON))
|
||||
tags := []string{"quota"}
|
||||
|
||||
ws.Route(ws.GET(subPath).To(getClusterQuota).Produces(restful.MIME_JSON).Doc("get whole "+
|
||||
"cluster's resource usage").Writes(models.ResourceQuota{}).Metadata(restfulspec.KeyOpenAPITags, tags))
|
||||
|
||||
ws.Route(ws.GET(subPath+"/namespaces/{namespace}").Doc("get specified namespace's resource "+
|
||||
"quota and usage").Param(ws.PathParameter("namespace",
|
||||
"namespace's name").DataType("string")).Writes(models.ResourceQuota{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).To(getNamespaceQuota).Produces(restful.MIME_JSON))
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -21,13 +21,21 @@ import (
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
|
||||
"github.com/emicklei/go-restful-openapi"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
)
|
||||
|
||||
func Register(ws *restful.WebService, subPath string) {
|
||||
|
||||
ws.Route(ws.GET(subPath + "/{resource}").To(listResource).Produces(restful.MIME_JSON))
|
||||
tags := []string{"resources"}
|
||||
|
||||
ws.Route(ws.GET(subPath+"/{resource}").To(listResource).Produces(restful.MIME_JSON).Metadata(restfulspec.KeyOpenAPITags, tags).Doc("Get resource" +
|
||||
" list").Param(ws.PathParameter("resource", "resource name").DataType(
|
||||
"string")).Param(ws.QueryParameter("conditions", "search "+
|
||||
"conditions").DataType("string")).Param(ws.QueryParameter("paging",
|
||||
"support paging function").DataType("string")).Writes(models.ResourceList{}))
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ import (
|
||||
"github.com/emicklei/go-restful"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
"github.com/emicklei/go-restful-openapi"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/models/iam"
|
||||
@@ -29,10 +31,17 @@ import (
|
||||
|
||||
func Register(ws *restful.WebService, subPath string) {
|
||||
|
||||
ws.Route(ws.POST(subPath).To(createUser).Consumes("*/*").Produces(restful.MIME_JSON))
|
||||
ws.Route(ws.DELETE(subPath).To(delUser).Produces(restful.MIME_JSON))
|
||||
ws.Route(ws.GET(subPath + "/kubectl").To(getKubectl).Produces(restful.MIME_JSON))
|
||||
ws.Route(ws.GET(subPath + "/kubeconfig").To(getKubeconfig).Produces(restful.MIME_JSON))
|
||||
tags := []string{"users"}
|
||||
|
||||
ws.Route(ws.POST(subPath).Doc("create user").Param(ws.PathParameter("user",
|
||||
"the username to be created").DataType("string")).Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
To(createUser).Consumes("*/*").Produces(restful.MIME_JSON))
|
||||
ws.Route(ws.DELETE(subPath).Doc("delete user").Param(ws.PathParameter("user",
|
||||
"the username to be deleted").DataType("string")).Metadata(restfulspec.KeyOpenAPITags, tags).To(delUser).Produces(restful.MIME_JSON))
|
||||
ws.Route(ws.GET(subPath+"/kubectl").Doc("get user's kubectl pod").Param(ws.PathParameter("user",
|
||||
"username").DataType("string")).Metadata(restfulspec.KeyOpenAPITags, tags).To(getKubectl).Produces(restful.MIME_JSON))
|
||||
ws.Route(ws.GET(subPath+"/kubeconfig").Doc("get users' kubeconfig").Param(ws.PathParameter("user",
|
||||
"username").DataType("string")).Metadata(restfulspec.KeyOpenAPITags, tags).To(getKubeconfig).Produces(restful.MIME_JSON))
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -21,14 +21,19 @@ import (
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
|
||||
"github.com/emicklei/go-restful-openapi"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
)
|
||||
|
||||
func Register(ws *restful.WebService, subPath string) {
|
||||
|
||||
ws.Route(ws.GET(subPath).To(getClusterStatus).Produces(restful.MIME_JSON))
|
||||
ws.Route(ws.GET(subPath + "/namespaces/{namespace}").To(getNamespaceStatus).Produces(restful.MIME_JSON))
|
||||
tags := []string{"workloadStatus"}
|
||||
|
||||
ws.Route(ws.GET(subPath).Doc("get abnormal workloads' count of whole cluster").Metadata(restfulspec.KeyOpenAPITags, tags).To(getClusterStatus).Produces(restful.MIME_JSON))
|
||||
ws.Route(ws.GET(subPath+"/namespaces/{namespace}").Doc("get abnormal workloads' count of specified namespace").Param(ws.PathParameter("namespace",
|
||||
"the name of namespace").DataType("string")).Metadata(restfulspec.KeyOpenAPITags, tags).To(getNamespaceStatus).Produces(restful.MIME_JSON))
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,9 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful-openapi"
|
||||
"github.com/go-openapi/spec"
|
||||
|
||||
_ "kubesphere.io/kubesphere/pkg/apis/v1alpha"
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
@@ -74,6 +77,28 @@ func preCheck() error {
|
||||
_, err = k8sClient.CoreV1().Namespaces().Create(&namespace)
|
||||
return err
|
||||
}
|
||||
|
||||
func registerSwagger() {
|
||||
config := restfulspec.Config{
|
||||
WebServices: restful.RegisteredWebServices(), // you control what services are visible
|
||||
APIPath: "/swagger-ui/api.json",
|
||||
PostBuildSwaggerObjectHandler: enrichSwaggerObject}
|
||||
restful.DefaultContainer.Add(restfulspec.NewOpenAPIService(config))
|
||||
http.Handle("/swagger-ui/", http.StripPrefix("/swagger-ui/", http.FileServer(http.Dir("/usr/lib/kubesphere/swagger-ui"))))
|
||||
}
|
||||
|
||||
func enrichSwaggerObject(swo *spec.Swagger) {
|
||||
swo.Info = &spec.Info{
|
||||
InfoProps: spec.InfoProps{
|
||||
Title: "KubeSphere",
|
||||
Description: "The extend apis of kubesphere",
|
||||
Version: "v1.0-alpha",
|
||||
},
|
||||
}
|
||||
swo.Tags = []spec.Tag{spec.Tag{TagProps: spec.TagProps{
|
||||
Name: "extend apis"}}}
|
||||
}
|
||||
|
||||
func (server *kubeSphereServer) run() {
|
||||
err := preCheck()
|
||||
if err != nil {
|
||||
@@ -83,6 +108,8 @@ func (server *kubeSphereServer) run() {
|
||||
|
||||
go controllers.Run()
|
||||
|
||||
registerSwagger()
|
||||
|
||||
if len(server.certFile) > 0 && len(server.keyFile) > 0 {
|
||||
servingCert, err := tls.LoadX509KeyPair(server.certFile, server.keyFile)
|
||||
if err != nil {
|
||||
|
||||
@@ -45,7 +45,7 @@ var resourceMap = map[string]string{daemonsetsKey: controllers.Daemonsets, deplo
|
||||
statefulsetsKey: controllers.Statefulsets, persistentvolumeclaimsKey: controllers.PersistentVolumeClaim, podsKey: controllers.Pods,
|
||||
namespaceKey: controllers.Namespaces, storageClassesKey: controllers.StorageClasses, clusterRolesKey: controllers.ClusterRoles}
|
||||
|
||||
type resourceQuota struct {
|
||||
type ResourceQuota struct {
|
||||
NameSpace string `json:"namespace"`
|
||||
Data v1.ResourceQuotaStatus `json:"data"`
|
||||
}
|
||||
@@ -58,7 +58,7 @@ func getUsage(namespace, resource string) int {
|
||||
return ctl.Count(namespace)
|
||||
}
|
||||
|
||||
func GetClusterQuota() (*resourceQuota, error) {
|
||||
func GetClusterQuota() (*ResourceQuota, error) {
|
||||
|
||||
quota := v1.ResourceQuotaStatus{Hard: make(v1.ResourceList), Used: make(v1.ResourceList)}
|
||||
for k, v := range resourceMap {
|
||||
@@ -68,11 +68,11 @@ func GetClusterQuota() (*resourceQuota, error) {
|
||||
quota.Used[v1.ResourceName(k)] = quantity
|
||||
}
|
||||
|
||||
return &resourceQuota{NameSpace: "\"\"", Data: quota}, nil
|
||||
return &ResourceQuota{NameSpace: "\"\"", Data: quota}, nil
|
||||
|
||||
}
|
||||
|
||||
func GetNamespaceQuota(namespace string) (*resourceQuota, error) {
|
||||
func GetNamespaceQuota(namespace string) (*ResourceQuota, error) {
|
||||
quota, err := getNamespaceResourceQuota(namespace)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
@@ -95,7 +95,7 @@ func GetNamespaceQuota(namespace string) (*resourceQuota, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return &resourceQuota{NameSpace: namespace, Data: *quota}, nil
|
||||
return &ResourceQuota{NameSpace: namespace, Data: *quota}, nil
|
||||
}
|
||||
|
||||
func updateNamespaceQuota(tmpResourceList, resourceList v1.ResourceList) {
|
||||
|
||||
Reference in New Issue
Block a user