1
0
mirror of https://github.com/rancher/norman.git synced 2025-08-26 19:08:27 +00:00
norman/api/builtin/builtin.go
2017-11-10 21:46:30 -07:00

187 lines
4.8 KiB
Go

package builtin
import (
"net/http"
"github.com/rancher/norman/store/empty"
"github.com/rancher/norman/store/schema"
"github.com/rancher/norman/types"
)
var (
Version = types.APIVersion{
Group: "io.cattle.builtin",
Version: "v3",
Path: "/v3",
}
Schema = types.Schema{
ID: "schema",
Version: Version,
CollectionMethods: []string{"GET"},
ResourceMethods: []string{"GET"},
ResourceFields: map[string]types.Field{
"collectionActions": {Type: "map[json]"},
"collectionFields": {Type: "map[json]"},
"collectionFitlers": {Type: "map[json]"},
"collectionMethods": {Type: "array[string]"},
"pluralName": {Type: "string"},
"resourceActions": {Type: "map[json]"},
"resourceFields": {Type: "map[json]"},
"resourceMethods": {Type: "array[string]"},
"version": {Type: "map[json]"},
},
Formatter: SchemaFormatter,
Store: schema.NewSchemaStore(),
}
Error = types.Schema{
ID: "error",
Version: Version,
ResourceMethods: []string{},
CollectionMethods: []string{},
ResourceFields: map[string]types.Field{
"code": {Type: "string"},
"detail": {Type: "string"},
"message": {Type: "string"},
"status": {Type: "int"},
},
}
Collection = types.Schema{
ID: "error",
Version: Version,
ResourceMethods: []string{},
CollectionMethods: []string{},
ResourceFields: map[string]types.Field{
"data": {Type: "array[json]"},
"pagination": {Type: "map[json]"},
"sort": {Type: "map[json]"},
"filters": {Type: "map[json]"},
},
}
APIRoot = types.Schema{
ID: "apiRoot",
Version: Version,
ResourceMethods: []string{},
CollectionMethods: []string{},
ResourceFields: map[string]types.Field{
"apiVersion": {Type: "map[json]"},
"path": {Type: "string"},
},
Formatter: APIRootFormatter,
Store: NewAPIRootStore(nil),
}
Schemas = types.NewSchemas().
AddSchema(&Schema).
AddSchema(&Error).
AddSchema(&Collection).
AddSchema(&APIRoot)
)
func apiVersionFromMap(apiVersion map[string]interface{}) types.APIVersion {
path, _ := apiVersion["path"].(string)
version, _ := apiVersion["version"].(string)
group, _ := apiVersion["group"].(string)
return types.APIVersion{
Path: path,
Version: version,
Group: group,
}
}
func SchemaFormatter(apiContext *types.APIContext, resource *types.RawResource) {
data, _ := resource.Values["version"].(map[string]interface{})
apiVersion := apiVersionFromMap(data)
schema := apiContext.Schemas.Schema(&apiVersion, resource.ID)
collectionLink := getSchemaCollectionLink(apiContext, schema)
if collectionLink != "" {
resource.Links["collection"] = collectionLink
}
}
func getSchemaCollectionLink(apiContext *types.APIContext, schema *types.Schema) string {
if schema != nil && contains(schema.CollectionMethods, http.MethodGet) {
return apiContext.URLBuilder.Collection(schema)
}
return ""
}
func contains(list []string, needle string) bool {
for _, v := range list {
if v == needle {
return true
}
}
return false
}
func APIRootFormatter(apiContext *types.APIContext, resource *types.RawResource) {
path, _ := resource.Values["path"].(string)
if path == "" {
return
}
resource.Links["root"] = apiContext.URLBuilder.RelativeToRoot(path)
data, _ := resource.Values["apiVersion"].(map[string]interface{})
apiVersion := apiVersionFromMap(data)
for name, schema := range apiContext.Schemas.SchemasForVersion(apiVersion) {
collectionLink := getSchemaCollectionLink(apiContext, schema)
if collectionLink != "" {
resource.Links[name] = collectionLink
}
}
}
type APIRootStore struct {
empty.Store
roots []string
}
func NewAPIRootStore(roots []string) types.Store {
return &APIRootStore{roots: roots}
}
func (a *APIRootStore) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) {
for _, version := range apiContext.Schemas.Versions() {
if version.Path == id {
return apiVersionToAPIRootMap(version), nil
}
}
return nil, nil
}
func (a *APIRootStore) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) {
roots := []map[string]interface{}{}
for _, version := range apiContext.Schemas.Versions() {
roots = append(roots, apiVersionToAPIRootMap(version))
}
for _, root := range a.roots {
roots = append(roots, map[string]interface{}{
"path": root,
})
}
return roots, nil
}
func apiVersionToAPIRootMap(version types.APIVersion) map[string]interface{} {
return map[string]interface{}{
"type": "/v3/apiRoot",
"apiVersion": map[string]interface{}{
"version": version.Version,
"group": version.Group,
"path": version.Path,
},
"path": version.Path,
}
}