schema.go raw

   1  package schema
   2  
   3  import (
   4  	"encoding/json"
   5  	"fmt"
   6  	"reflect"
   7  
   8  	"github.com/mimuret/golang-iij-dpf/pkg/api"
   9  	"github.com/mimuret/golang-iij-dpf/pkg/apis"
  10  	"github.com/mimuret/golang-iij-dpf/pkg/meta"
  11  )
  12  
  13  var SchemaSet = NewSchemaSet()
  14  
  15  type Register struct {
  16  	Group string
  17  }
  18  
  19  func NewRegister(groupName string) *Register {
  20  	return &Register{Group: groupName}
  21  }
  22  
  23  func (r *Register) Add(items ...apis.Spec) {
  24  	SchemaSet.Add(r.Group, items)
  25  }
  26  
  27  func NewSchemaSet() *schemaSet {
  28  	return &schemaSet{}
  29  }
  30  
  31  type schemaSet map[string]*schema
  32  
  33  func (s schemaSet) Add(groupName string, items []apis.Spec) {
  34  	if _, ok := s[groupName]; !ok {
  35  		s[groupName] = &schema{group: groupName, objectMap: make(map[string]apis.Spec)}
  36  	}
  37  	s[groupName].Add(items)
  38  }
  39  
  40  type schema struct {
  41  	group     string
  42  	objectMap map[string]apis.Spec
  43  }
  44  
  45  func (s *schema) Add(items []apis.Spec) {
  46  	for _, item := range items {
  47  		st := reflect.TypeOf(item)
  48  		if st.Kind() != reflect.Ptr {
  49  			name := st.Elem().Name()
  50  			panic(fmt.Sprintf("schema.Add name: `%s` is not ptr %v", name, item))
  51  		}
  52  		name := st.Elem().Name()
  53  		if v, ok := s.objectMap[name]; ok {
  54  			panic(fmt.Sprintf("schema.Add name: `%s` is duplicated, old: %v, new: %v", name, v, item))
  55  		}
  56  		s.objectMap[name] = item
  57  	}
  58  }
  59  
  60  func (s schemaSet) Parse(bs []byte) (apis.Spec, error) {
  61  	kv := &meta.KindVersion{}
  62  	if err := json.Unmarshal(bs, kv); err != nil {
  63  		return nil, fmt.Errorf("failed to parse json: %w", err)
  64  	}
  65  	if kv.Kind == "" {
  66  		return nil, fmt.Errorf("kind value is not exist")
  67  	}
  68  	if kv.APIVersion == "" {
  69  		return nil, fmt.Errorf("apiVersion value is not exist")
  70  	}
  71  	gs, ok := s[kv.APIVersion]
  72  	if !ok {
  73  		return nil, fmt.Errorf("apiVersion `%s` is not support", kv.APIVersion)
  74  	}
  75  
  76  	spec, ok := gs.objectMap[kv.Kind]
  77  	if !ok {
  78  		return nil, fmt.Errorf("kind value `%s` is not supported", kv.Kind)
  79  	}
  80  	obj, ok := spec.DeepCopyObject().(apis.Spec)
  81  	if !ok {
  82  		return nil, fmt.Errorf("kind value `%s` DeepCopyObject is invalid", kv.Kind)
  83  	}
  84  	if err := api.UnMarshalInput(bs, obj); err != nil {
  85  		return nil, fmt.Errorf("failed to parse resource: %w", err)
  86  	}
  87  	return obj, nil
  88  }
  89