1
0
mirror of https://github.com/rancher/types.git synced 2025-09-03 06:04:24 +00:00

Update norman

This commit is contained in:
Darren Shepherd
2017-12-05 09:28:09 -07:00
parent 68600ed35d
commit 66eaf237f9
10 changed files with 248 additions and 4 deletions

View File

@@ -4,6 +4,7 @@ import (
"encoding/json"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -47,6 +48,15 @@ func (p *ObjectClient) Create(o runtime.Object) (runtime.Object, error) {
if obj, ok := o.(metav1.Object); ok && obj.GetNamespace() != "" {
ns = obj.GetNamespace()
}
if t, err := meta.TypeAccessor(o); err == nil {
if t.GetKind() == "" {
t.SetKind(p.gvk.Kind)
}
if t.GetAPIVersion() == "" {
apiVersion, _ := p.gvk.ToAPIVersionAndKind()
t.SetAPIVersion(apiVersion)
}
}
result := p.Factory.Object()
err := p.restClient.Post().
Prefix(p.getAPIPrefix(), p.gvk.Group, p.gvk.Version).

View File

@@ -135,6 +135,36 @@ func generateType(outputDir string, schema *types.Schema, schemas *types.Schemas
})
}
func generateLifecycle(external bool, outputDir string, schema *types.Schema, schemas *types.Schemas) error {
filePath := strings.ToLower("zz_generated_" + addUnderscore(schema.ID) + "_lifecycle_adapter.go")
output, err := os.Create(path.Join(outputDir, filePath))
if err != nil {
return err
}
defer output.Close()
typeTemplate, err := template.New("lifecycle.template").
Funcs(funcs()).
Parse(strings.Replace(lifecycleTemplate, "%BACK%", "`", -1))
if err != nil {
return err
}
importPackage := ""
prefix := ""
if external {
parts := strings.Split(schema.PkgName, "/vendor/")
importPackage = fmt.Sprintf("\"%s\"", parts[len(parts)-1])
prefix = schema.Version.Version + "."
}
return typeTemplate.Execute(output, map[string]interface{}{
"schema": schema,
"importPackage": importPackage,
"prefix": prefix,
})
}
func generateController(external bool, outputDir string, schema *types.Schema, schemas *types.Schemas) error {
filePath := strings.ToLower("zz_generated_" + addUnderscore(schema.ID) + "_controller.go")
output, err := os.Create(path.Join(outputDir, filePath))
@@ -226,6 +256,10 @@ func GenerateControllerForTypes(version *types.APIVersion, k8sOutputPackage stri
if err := generateController(true, k8sDir, schema, schemas); err != nil {
return err
}
if err := generateLifecycle(true, k8sDir, schema, schemas); err != nil {
return err
}
}
if err := deepCopyGen(baseDir, k8sOutputPackage); err != nil {
@@ -267,6 +301,9 @@ func Generate(schemas *types.Schemas, cattleOutputPackage, k8sOutputPackage stri
if err := generateController(false, k8sDir, schema, schemas); err != nil {
return err
}
if err := generateLifecycle(false, k8sDir, schema, schemas); err != nil {
return err
}
}
generated = append(generated, schema)

View File

@@ -0,0 +1,43 @@
package generator
var lifecycleTemplate = `package {{.schema.Version.Version}}
import (
{{.importPackage}}
"k8s.io/apimachinery/pkg/runtime"
"github.com/rancher/norman/lifecycle"
)
type {{.schema.CodeName}}Lifecycle interface {
Initialize(obj *{{.prefix}}{{.schema.CodeName}}) error
Remove(obj *{{.prefix}}{{.schema.CodeName}}) error
Updated(obj *{{.prefix}}{{.schema.CodeName}}) error
}
type {{.schema.ID}}LifecycleAdapter struct {
lifecycle {{.schema.CodeName}}Lifecycle
}
func (w *{{.schema.ID}}LifecycleAdapter) Initialize(obj runtime.Object) error {
return w.lifecycle.Initialize(obj.(*{{.prefix}}{{.schema.CodeName}}))
}
func (w *{{.schema.ID}}LifecycleAdapter) Finalize(obj runtime.Object) error {
return w.lifecycle.Remove(obj.(*{{.prefix}}{{.schema.CodeName}}))
}
func (w *{{.schema.ID}}LifecycleAdapter) Updated(obj runtime.Object) error {
return w.lifecycle.Updated(obj.(*{{.prefix}}{{.schema.CodeName}}))
}
func New{{.schema.CodeName}}LifecycleAdapter(name string, client {{.schema.CodeName}}Interface, l {{.schema.CodeName}}Lifecycle) {{.schema.CodeName}}HandlerFunc {
adapter := &{{.schema.ID}}LifecycleAdapter{lifecycle: l}
syncFn := lifecycle.NewObjectLifecycleAdapter(name, adapter, client.ObjectClient())
return func(key string, obj *{{.prefix}}{{.schema.CodeName}}) error {
if obj == nil {
return syncFn(key, nil)
}
return syncFn(key, obj)
}
}
`

119
vendor/github.com/rancher/norman/lifecycle/object.go generated vendored Normal file
View File

@@ -0,0 +1,119 @@
package lifecycle
import (
"github.com/rancher/norman/clientbase"
"github.com/rancher/norman/types/slice"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
var (
initialized = "io.cattle.lifecycle.initialized"
)
type ObjectLifecycle interface {
Initialize(obj runtime.Object) error
Finalize(obj runtime.Object) error
Updated(obj runtime.Object) error
}
type objectLifecycleAdapter struct {
name string
lifecycle ObjectLifecycle
objectClient *clientbase.ObjectClient
}
func NewObjectLifecycleAdapter(name string, lifecycle ObjectLifecycle, objectClient *clientbase.ObjectClient) func(key string, obj runtime.Object) error {
o := objectLifecycleAdapter{
name: name,
lifecycle: lifecycle,
objectClient: objectClient,
}
return o.sync
}
func (o *objectLifecycleAdapter) sync(key string, obj runtime.Object) error {
if obj == nil {
return nil
}
metadata, err := meta.Accessor(obj)
if err != nil {
return err
}
if cont, err := o.finalize(metadata, obj); err != nil || !cont {
return err
}
if cont, err := o.initialize(metadata, obj); err != nil || !cont {
return err
}
return o.lifecycle.Updated(obj.DeepCopyObject())
}
func (o *objectLifecycleAdapter) finalize(metadata metav1.Object, obj runtime.Object) (bool, error) {
// Check finalize
if metadata.GetDeletionTimestamp() == nil {
return true, nil
}
if !slice.ContainsString(metadata.GetFinalizers(), o.name) {
return false, nil
}
obj = obj.DeepCopyObject()
metadata, err := meta.Accessor(obj)
if err != nil {
return false, err
}
var finalizers []string
for _, finalizer := range metadata.GetFinalizers() {
if finalizer == o.name {
continue
}
finalizers = append(finalizers, finalizer)
}
metadata.SetFinalizers(finalizers)
if err := o.lifecycle.Finalize(obj); err != nil {
return false, err
}
_, err = o.objectClient.Update(metadata.GetName(), obj)
return false, err
}
func (o *objectLifecycleAdapter) initializeKey() string {
return initialized + "." + o.name
}
func (o *objectLifecycleAdapter) initialize(metadata metav1.Object, obj runtime.Object) (bool, error) {
initialized := o.initializeKey()
if metadata.GetLabels()[initialized] == "true" {
return true, nil
}
obj = obj.DeepCopyObject()
metadata, err := meta.Accessor(obj)
if err != nil {
return false, err
}
if metadata.GetLabels() == nil {
metadata.SetLabels(map[string]string{})
}
metadata.SetFinalizers(append(metadata.GetFinalizers(), o.name))
metadata.GetLabels()[initialized] = "true"
if err := o.lifecycle.Initialize(obj); err != nil {
return false, err
}
_, err = o.objectClient.Update(metadata.GetName(), obj)
return false, err
}

View File

@@ -15,7 +15,7 @@ func NewMetadataMapper() types.Mapper {
Move{From: "deletionTimestamp", To: "removed"},
Drop{"deletionGracePeriodSeconds"},
Drop{"initializers"},
Drop{"finalizers"},
//Drop{"finalizers"},
Drop{"clusterName"},
ReadOnly{Field: "*"},
Access{

View File

@@ -24,3 +24,11 @@ func (v *APIVersion) Equals(other *APIVersion) bool {
func (s *Schema) CanList() bool {
return slice.ContainsString(s.CollectionMethods, http.MethodGet)
}
func (s *Schema) CanUpdate() bool {
return slice.ContainsString(s.ResourceMethods, http.MethodPut)
}
func (s *Schema) CanDelete() bool {
return slice.ContainsString(s.ResourceMethods, http.MethodDelete)
}

View File

@@ -60,7 +60,7 @@ func (s *Schemas) AddSchemas(schema *Schemas) *Schemas {
}
func (s *Schemas) AddSchema(schema *Schema) *Schemas {
schema.Type = "/v1-meta/schemas/schema"
schema.Type = "/meta/schemas/schema"
if schema.ID == "" {
s.errors = append(s.errors, fmt.Errorf("ID is not set on schema: %v", schema))
return s

View File

@@ -83,7 +83,7 @@ type APIContext struct {
URLBuilder URLBuilder
AccessControl AccessControl
SubContext map[string]string
Attributes map[string]interface{}
//Attributes map[string]interface{}
Request *http.Request
Response http.ResponseWriter
@@ -140,6 +140,7 @@ type URLBuilder interface {
SubContextCollection(subContext *Schema, contextName string, schema *Schema) string
SchemaLink(schema *Schema) string
ResourceLink(resource *RawResource) string
Link(linkName string, resource *RawResource) string
RelativeToRoot(path string) string
Version(version APIVersion) string
Marker(marker string) string

View File

@@ -1,5 +1,7 @@
package values
import "github.com/rancher/norman/types/convert"
func RemoveValue(data map[string]interface{}, keys ...string) (interface{}, bool) {
for i, key := range keys {
if i == len(keys)-1 {
@@ -13,6 +15,30 @@ func RemoveValue(data map[string]interface{}, keys ...string) (interface{}, bool
return nil, false
}
func GetStringSlice(data map[string]interface{}, keys ...string) ([]string, bool) {
val, ok := GetValue(data, keys...)
if !ok {
return nil, ok
}
slice, typeOk := val.([]string)
if typeOk {
return slice, typeOk
}
sliceNext, typeOk := val.([]interface{})
if !typeOk {
return nil, typeOk
}
var result []string
for _, item := range sliceNext {
result = append(result, convert.ToString(item))
}
return result, true
}
func GetSlice(data map[string]interface{}, keys ...string) ([]map[string]interface{}, bool) {
val, ok := GetValue(data, keys...)
if !ok {