mirror of
https://github.com/rancher/norman.git
synced 2025-09-26 07:12:30 +00:00
More initial dev
This commit is contained in:
186
api/builtin/builtin.go
Normal file
186
api/builtin/builtin.go
Normal file
@@ -0,0 +1,186 @@
|
||||
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,
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user