mirror of
https://github.com/rancher/norman.git
synced 2025-09-03 16:25:09 +00:00
Refactor types
This commit is contained in:
@@ -12,8 +12,8 @@ var (
|
||||
<!DOCTYPE html>
|
||||
<!-- If you are reading this, there is a good chance you would prefer sending an
|
||||
"Accept: application/json" header and receiving actual JSON responses. -->
|
||||
<link rel="stylesheet" type="text/css" href="https://releases.rancher.com/api-ui/1.1.1/ui.min.css" />
|
||||
<script src="https://releases.rancher.com/api-ui/1.1.1/ui.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="https://releases.rancher.com/api-ui/1.1.2/ui.min.css" />
|
||||
<script src="https://releases.rancher.com/api-ui/1.1.2/ui.min.js"></script>
|
||||
<script>
|
||||
var user = "admin";
|
||||
var curlUser='${CATTLE_ACCESS_KEY}:${CATTLE_SECRET_KEY}';
|
||||
|
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/rancher/norman/parse"
|
||||
"github.com/rancher/norman/parse/builder"
|
||||
"github.com/rancher/norman/types"
|
||||
"github.com/rancher/norman/types/definition"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@@ -90,7 +91,7 @@ func toString(val interface{}) string {
|
||||
}
|
||||
|
||||
func (j *JSONResponseWriter) convert(b *builder.Builder, context *types.APIContext, input map[string]interface{}) *types.RawResource {
|
||||
schema := context.Schemas.Schema(context.Version, fmt.Sprint(input["type"]))
|
||||
schema := context.Schemas.Schema(context.Version, definition.GetFullType(input))
|
||||
if schema == nil {
|
||||
return nil
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/rancher/norman/api"
|
||||
"github.com/rancher/norman/store/crd"
|
||||
"github.com/rancher/norman/types"
|
||||
"github.com/rancher/norman/types/factory"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
)
|
||||
|
||||
@@ -29,7 +30,7 @@ var (
|
||||
Path: "/example/v1",
|
||||
}
|
||||
|
||||
Schemas = types.NewSchemas()
|
||||
Schemas = factory.Schemas(&version)
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@@ -63,7 +63,7 @@ type {{.schema.CodeName}}Interface interface {
|
||||
Get(name string, opts metav1.GetOptions) (*{{.prefix}}{{.schema.CodeName}}, error)
|
||||
Update(*{{.prefix}}{{.schema.CodeName}}) (*{{.prefix}}{{.schema.CodeName}}, error)
|
||||
Delete(name string, options *metav1.DeleteOptions) error
|
||||
List(opts metav1.ListOptions) (*{{.prefix}}{{.schema.CodeName}}List, error)
|
||||
List(opts metav1.ListOptions) (*{{.schema.CodeName}}List, error)
|
||||
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
|
||||
Controller() {{.schema.CodeName}}Controller
|
||||
@@ -181,9 +181,9 @@ func (s *{{.schema.ID}}Client) Delete(name string, options *metav1.DeleteOptions
|
||||
return s.objectClient.Delete(name, options)
|
||||
}
|
||||
|
||||
func (s *{{.schema.ID}}Client) List(opts metav1.ListOptions) (*{{.prefix}}{{.schema.CodeName}}List, error) {
|
||||
func (s *{{.schema.ID}}Client) List(opts metav1.ListOptions) (*{{.schema.CodeName}}List, error) {
|
||||
obj, err := s.objectClient.List(opts)
|
||||
return obj.(*{{.prefix}}{{.schema.CodeName}}List), err
|
||||
return obj.(*{{.schema.CodeName}}List), err
|
||||
}
|
||||
|
||||
func (s *{{.schema.ID}}Client) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
|
@@ -113,6 +113,10 @@ func (b *Builder) checkDefaultAndRequired(schema *types.Schema, input map[string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if op == List && fieldMatchesOp(field, List) && definition.IsReferenceType(field.Type) && !hasKey {
|
||||
result[fieldName] = nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -264,7 +268,7 @@ func (b *Builder) convertReferenceType(fieldType string, value interface{}) (str
|
||||
func (b *Builder) convertArray(fieldType string, value interface{}, op Operation) ([]interface{}, error) {
|
||||
if strSliceValue, ok := value.([]string); ok {
|
||||
// Form data will be []string
|
||||
result := []interface{}{}
|
||||
var result []interface{}
|
||||
for _, value := range strSliceValue {
|
||||
result = append(result, value)
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
"github.com/rancher/norman/types"
|
||||
"github.com/rancher/norman/types/convert"
|
||||
"github.com/rancher/norman/types/mapper"
|
||||
"github.com/rancher/norman/types/values"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -41,6 +41,11 @@ func NewProxyStore(k8sClient rest.Interface,
|
||||
}
|
||||
|
||||
func (p *Store) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) {
|
||||
_, result, err := p.byID(apiContext, schema, id)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (p *Store) byID(apiContext *types.APIContext, schema *types.Schema, id string) (string, map[string]interface{}, error) {
|
||||
namespace, id := splitID(id)
|
||||
|
||||
req := p.common(namespace, p.k8sClient.Get()).
|
||||
@@ -132,11 +137,11 @@ func (p *Store) Create(apiContext *types.APIContext, schema *types.Schema, data
|
||||
namespace, _ := data["namespaceId"].(string)
|
||||
p.toInternal(schema.Mapper, data)
|
||||
|
||||
name, _ := mapper.GetValueN(data, "metadata", "name").(string)
|
||||
name, _ := values.GetValueN(data, "metadata", "name").(string)
|
||||
if name == "" {
|
||||
generated, _ := mapper.GetValueN(data, "metadata", "generateName").(string)
|
||||
generated, _ := values.GetValueN(data, "metadata", "generateName").(string)
|
||||
if generated == "" {
|
||||
mapper.PutValue(data, strings.ToLower(schema.ID+"-"), "metadata", "generateName")
|
||||
values.PutValue(data, strings.ToLower(schema.ID+"-"), "metadata", "generateName")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +150,8 @@ func (p *Store) Create(apiContext *types.APIContext, schema *types.Schema, data
|
||||
Object: data,
|
||||
})
|
||||
|
||||
return p.singleResult(schema, req)
|
||||
_, result, err := p.singleResult(schema, req)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (p *Store) toInternal(mapper types.Mapper, data map[string]interface{}) {
|
||||
@@ -162,7 +168,7 @@ func (p *Store) toInternal(mapper types.Mapper, data map[string]interface{}) {
|
||||
}
|
||||
|
||||
func (p *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) {
|
||||
existing, err := p.ByID(apiContext, schema, id)
|
||||
resourceVersion, existing, err := p.byID(apiContext, schema, id)
|
||||
if err != nil {
|
||||
return data, nil
|
||||
}
|
||||
@@ -174,13 +180,16 @@ func (p *Store) Update(apiContext *types.APIContext, schema *types.Schema, data
|
||||
p.toInternal(schema.Mapper, existing)
|
||||
namespace, id := splitID(id)
|
||||
|
||||
values.PutValue(existing, resourceVersion, "metadata", "resourceVersion")
|
||||
|
||||
req := p.common(namespace, p.k8sClient.Put()).
|
||||
Body(&unstructured.Unstructured{
|
||||
Object: existing,
|
||||
}).
|
||||
Name(id)
|
||||
|
||||
return p.singleResult(schema, req)
|
||||
_, result, err := p.singleResult(schema, req)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (p *Store) Delete(apiContext *types.APIContext, schema *types.Schema, id string) error {
|
||||
@@ -196,15 +205,16 @@ func (p *Store) Delete(apiContext *types.APIContext, schema *types.Schema, id st
|
||||
return req.Do().Error()
|
||||
}
|
||||
|
||||
func (p *Store) singleResult(schema *types.Schema, req *rest.Request) (map[string]interface{}, error) {
|
||||
func (p *Store) singleResult(schema *types.Schema, req *rest.Request) (string, map[string]interface{}, error) {
|
||||
result := &unstructured.Unstructured{}
|
||||
err := req.Do().Into(result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
version := result.GetResourceVersion()
|
||||
p.fromInternal(schema, result.Object)
|
||||
return result.Object, nil
|
||||
return version, result.Object, nil
|
||||
}
|
||||
|
||||
func splitID(id string) (string, string) {
|
||||
|
@@ -1,6 +1,10 @@
|
||||
package definition
|
||||
|
||||
import "strings"
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/norman/types/convert"
|
||||
)
|
||||
|
||||
func IsMapType(fieldType string) bool {
|
||||
return strings.HasPrefix(fieldType, "map[") && strings.HasSuffix(fieldType, "]")
|
||||
@@ -26,3 +30,12 @@ func SubType(fieldType string) string {
|
||||
|
||||
return fieldType[i+1 : len(fieldType)-1]
|
||||
}
|
||||
|
||||
func GetType(data map[string]interface{}) string {
|
||||
parts := strings.Split(GetFullType(data), "/")
|
||||
return parts[len(parts)-1]
|
||||
}
|
||||
|
||||
func GetFullType(data map[string]interface{}) string {
|
||||
return convert.ToString(data["type"])
|
||||
}
|
||||
|
@@ -8,12 +8,16 @@ import (
|
||||
|
||||
func Schemas(version *types.APIVersion) *types.Schemas {
|
||||
s := types.NewSchemas()
|
||||
s.DefaultMappers = []types.Mapper{
|
||||
s.DefaultMappers = func() []types.Mapper {
|
||||
return []types.Mapper{
|
||||
mapper.NewObject(),
|
||||
}
|
||||
s.DefaultPostMappers = []types.Mapper{
|
||||
}
|
||||
s.DefaultPostMappers = func() []types.Mapper {
|
||||
return []types.Mapper{
|
||||
&mapper.RenameReference{},
|
||||
}
|
||||
}
|
||||
s.AddMapperForType(version, v1.ObjectMeta{}, mapper.NewMetadataMapper())
|
||||
return s
|
||||
}
|
||||
|
@@ -1,13 +1,16 @@
|
||||
package mapper
|
||||
|
||||
import "github.com/rancher/norman/types"
|
||||
import (
|
||||
"github.com/rancher/norman/types"
|
||||
"github.com/rancher/norman/types/values"
|
||||
)
|
||||
|
||||
type LabelField struct {
|
||||
Field string
|
||||
}
|
||||
|
||||
func (e LabelField) FromInternal(data map[string]interface{}) {
|
||||
v, ok := RemoveValue(data, "labels", "io.cattle.field."+e.Field)
|
||||
v, ok := values.RemoveValue(data, "labels", "io.cattle.field."+e.Field)
|
||||
if ok {
|
||||
data[e.Field] = v
|
||||
}
|
||||
@@ -16,7 +19,7 @@ func (e LabelField) FromInternal(data map[string]interface{}) {
|
||||
func (e LabelField) ToInternal(data map[string]interface{}) {
|
||||
v, ok := data[e.Field]
|
||||
if ok {
|
||||
PutValue(data, v, "labels", "io.cattle.field."+e.Field)
|
||||
values.PutValue(data, v, "labels", "io.cattle.field."+e.Field)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/rancher/norman/types"
|
||||
"github.com/rancher/norman/types/convert"
|
||||
"github.com/rancher/norman/types/definition"
|
||||
"github.com/rancher/norman/types/values"
|
||||
)
|
||||
|
||||
type Move struct {
|
||||
@@ -17,14 +18,14 @@ type Move struct {
|
||||
}
|
||||
|
||||
func (m Move) FromInternal(data map[string]interface{}) {
|
||||
if v, ok := RemoveValue(data, strings.Split(m.From, "/")...); ok {
|
||||
PutValue(data, v, strings.Split(m.To, "/")...)
|
||||
if v, ok := values.RemoveValue(data, strings.Split(m.From, "/")...); ok {
|
||||
values.PutValue(data, v, strings.Split(m.To, "/")...)
|
||||
}
|
||||
}
|
||||
|
||||
func (m Move) ToInternal(data map[string]interface{}) {
|
||||
if v, ok := RemoveValue(data, strings.Split(m.To, "/")...); ok {
|
||||
PutValue(data, v, strings.Split(m.From, "/")...)
|
||||
if v, ok := values.RemoveValue(data, strings.Split(m.To, "/")...); ok {
|
||||
values.PutValue(data, v, strings.Split(m.From, "/")...)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,8 @@
|
||||
package mapper
|
||||
|
||||
import "github.com/rancher/norman/types"
|
||||
import (
|
||||
"github.com/rancher/norman/types"
|
||||
)
|
||||
|
||||
type Object struct {
|
||||
types.Mappers
|
||||
@@ -12,8 +14,8 @@ func NewObject(mappers ...types.Mapper) Object {
|
||||
&Embed{Field: "metadata"},
|
||||
&Embed{Field: "spec", Optional: true},
|
||||
&ReadOnly{Field: "status", Optional: true},
|
||||
&Drop{"kind"},
|
||||
&Drop{"apiVersion"},
|
||||
Drop{"kind"},
|
||||
Drop{"apiVersion"},
|
||||
&Scope{
|
||||
IfNot: types.NamespaceScope,
|
||||
Mappers: []types.Mapper{
|
||||
|
@@ -6,6 +6,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/norman/types"
|
||||
"github.com/rancher/norman/types/values"
|
||||
)
|
||||
|
||||
type SetValue struct {
|
||||
@@ -15,24 +16,24 @@ type SetValue struct {
|
||||
}
|
||||
|
||||
func (s SetValue) FromInternal(data map[string]interface{}) {
|
||||
v, ok := GetValue(data, strings.Split(s.From, "/")...)
|
||||
v, ok := values.GetValue(data, strings.Split(s.From, "/")...)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if v == s.IfEq {
|
||||
PutValue(data, s.Value, strings.Split(s.To, "/")...)
|
||||
values.PutValue(data, s.Value, strings.Split(s.To, "/")...)
|
||||
}
|
||||
}
|
||||
|
||||
func (s SetValue) ToInternal(data map[string]interface{}) {
|
||||
v, ok := GetValue(data, strings.Split(s.To, "/")...)
|
||||
v, ok := values.GetValue(data, strings.Split(s.To, "/")...)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if v == s.Value {
|
||||
PutValue(data, s.IfEq, strings.Split(s.From, "/")...)
|
||||
values.PutValue(data, s.IfEq, strings.Split(s.From, "/")...)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -142,10 +142,14 @@ func (s *Schemas) importType(version *APIVersion, t reflect.Type, overrides ...r
|
||||
}
|
||||
|
||||
mappers := s.mapper(&schema.Version, schema.ID)
|
||||
if s.DefaultMappers != nil {
|
||||
if schema.CanList() {
|
||||
mappers = append(s.DefaultMappers, mappers...)
|
||||
mappers = append(s.DefaultMappers(), mappers...)
|
||||
}
|
||||
}
|
||||
if s.DefaultPostMappers != nil {
|
||||
mappers = append(mappers, s.DefaultPostMappers()...)
|
||||
}
|
||||
mappers = append(mappers, s.DefaultPostMappers...)
|
||||
|
||||
if len(mappers) > 0 {
|
||||
copy, err := s.newSchemaFromType(version, t, typeName)
|
||||
|
@@ -15,12 +15,14 @@ type SchemaCollection struct {
|
||||
|
||||
type SchemaInitFunc func(*Schemas) *Schemas
|
||||
|
||||
type MappersFactory func() []Mapper
|
||||
|
||||
type Schemas struct {
|
||||
schemasByPath map[string]map[string]*Schema
|
||||
schemasBySubContext map[string]*Schema
|
||||
mappers map[string]map[string][]Mapper
|
||||
DefaultMappers []Mapper
|
||||
DefaultPostMappers []Mapper
|
||||
DefaultMappers MappersFactory
|
||||
DefaultPostMappers MappersFactory
|
||||
versions []APIVersion
|
||||
schemas []*Schema
|
||||
errors []error
|
||||
|
@@ -1,4 +1,4 @@
|
||||
package mapper
|
||||
package values
|
||||
|
||||
func RemoveValue(data map[string]interface{}, keys ...string) (interface{}, bool) {
|
||||
for i, key := range keys {
|
Reference in New Issue
Block a user