mirror of
https://github.com/rancher/steve.git
synced 2025-04-27 02:51:10 +00:00
136 lines
3.3 KiB
Go
136 lines
3.3 KiB
Go
package apiroot
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/rancher/steve/pkg/schemaserver/store/empty"
|
|
"github.com/rancher/steve/pkg/schemaserver/types"
|
|
"github.com/rancher/wrangler/pkg/schemas"
|
|
)
|
|
|
|
func Register(apiSchemas *types.APISchemas, versions, roots []string) {
|
|
apiSchemas.MustAddSchema(types.APISchema{
|
|
Schema: &schemas.Schema{
|
|
ID: "apiRoot",
|
|
CollectionMethods: []string{"GET"},
|
|
ResourceMethods: []string{"GET"},
|
|
ResourceFields: map[string]schemas.Field{
|
|
"apiVersion": {Type: "map[json]"},
|
|
"path": {Type: "string"},
|
|
},
|
|
},
|
|
Formatter: Formatter,
|
|
Store: NewAPIRootStore(versions, roots),
|
|
})
|
|
}
|
|
|
|
func Formatter(apiOp *types.APIRequest, resource *types.RawResource) {
|
|
data := resource.APIObject.Data()
|
|
path, _ := data["path"].(string)
|
|
if path == "" {
|
|
return
|
|
}
|
|
delete(data, "path")
|
|
|
|
resource.Links["root"] = apiOp.URLBuilder.RelativeToRoot(path)
|
|
|
|
if data, isAPIRoot := data["apiVersion"].(map[string]interface{}); isAPIRoot {
|
|
apiVersion := apiVersionFromMap(apiOp.Schemas, data)
|
|
resource.Links["self"] = apiOp.URLBuilder.RelativeToRoot(apiVersion)
|
|
|
|
resource.Links["schemas"] = apiOp.URLBuilder.RelativeToRoot(path)
|
|
for _, schema := range apiOp.Schemas.Schemas {
|
|
addCollectionLink(apiOp, schema, resource.Links)
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func addCollectionLink(apiOp *types.APIRequest, schema *types.APISchema, links map[string]string) {
|
|
collectionLink := getSchemaCollectionLink(apiOp, schema)
|
|
if collectionLink != "" {
|
|
links[schema.PluralName] = collectionLink
|
|
}
|
|
}
|
|
|
|
func getSchemaCollectionLink(apiOp *types.APIRequest, schema *types.APISchema) string {
|
|
if schema != nil && contains(schema.CollectionMethods, http.MethodGet) {
|
|
return apiOp.URLBuilder.Collection(schema)
|
|
}
|
|
return ""
|
|
}
|
|
|
|
type Store struct {
|
|
empty.Store
|
|
roots []string
|
|
versions []string
|
|
}
|
|
|
|
func NewAPIRootStore(versions []string, roots []string) types.Store {
|
|
return &Store{
|
|
roots: roots,
|
|
versions: versions,
|
|
}
|
|
}
|
|
|
|
func (a *Store) ByID(apiOp *types.APIRequest, schema *types.APISchema, id string) (types.APIObject, error) {
|
|
return types.DefaultByID(a, apiOp, schema, id)
|
|
}
|
|
|
|
func (a *Store) List(apiOp *types.APIRequest, schema *types.APISchema) (types.APIObjectList, error) {
|
|
var roots types.APIObjectList
|
|
|
|
versions := a.versions
|
|
|
|
for _, version := range versions {
|
|
roots.Objects = append(roots.Objects, types.APIObject{
|
|
Type: "apiRoot",
|
|
ID: version,
|
|
Object: apiVersionToAPIRootMap(version),
|
|
})
|
|
}
|
|
|
|
for _, root := range a.roots {
|
|
parts := strings.SplitN(root, ":", 2)
|
|
if len(parts) == 2 {
|
|
roots.Objects = append(roots.Objects, types.APIObject{
|
|
Type: "apiRoot",
|
|
ID: parts[0],
|
|
Object: map[string]interface{}{
|
|
"id": parts[0],
|
|
"path": parts[1],
|
|
},
|
|
})
|
|
}
|
|
}
|
|
|
|
return roots, nil
|
|
}
|
|
|
|
func apiVersionToAPIRootMap(version string) map[string]interface{} {
|
|
return map[string]interface{}{
|
|
"id": version,
|
|
"type": "apiRoot",
|
|
"apiVersion": map[string]interface{}{
|
|
"version": version,
|
|
},
|
|
"path": "/" + version,
|
|
}
|
|
}
|
|
|
|
func apiVersionFromMap(schemas *types.APISchemas, apiVersion map[string]interface{}) string {
|
|
version, _ := apiVersion["version"].(string)
|
|
return version
|
|
}
|
|
|
|
func contains(list []string, needle string) bool {
|
|
for _, v := range list {
|
|
if v == needle {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|