1
0
mirror of https://github.com/rancher/steve.git synced 2025-04-27 02:51:10 +00:00
steve/pkg/schemaserver/store/apiroot/apiroot.go
Darren Shepherd 8b42d0aff8 Refactor
2020-01-30 22:37:59 -07:00

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
}