-
Notifications
You must be signed in to change notification settings - Fork 0
/
stackregistry.go
147 lines (131 loc) · 5.07 KB
/
stackregistry.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package registry
import (
"context"
iv "github.com/docker/compose-on-kubernetes/internal/internalversion"
"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/registry/generic"
genericregistry "k8s.io/apiserver/pkg/registry/generic/registry"
"k8s.io/apiserver/pkg/registry/rest"
"k8s.io/apiserver/pkg/storage"
appsv1beta2 "k8s.io/client-go/kubernetes/typed/apps/v1beta2"
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
restclient "k8s.io/client-go/rest"
)
const composeOutOfDate = "# This compose file is outdated: the stack was updated by other means\n"
// StackREST is a storage for stack resource
type StackREST struct {
genericregistry.Store
}
type stackRESTGet interface {
GetStack(ctx context.Context, name string, options *metav1.GetOptions) (*iv.Stack, error)
}
type stackRESTStore interface {
stackRESTGet
CreateStack(ctx context.Context, newStack *iv.Stack, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (*iv.Stack, error)
UpdateStack(ctx context.Context, name string, transform StackTransform, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc,
forceAllowCreate bool, options *metav1.UpdateOptions) (*iv.Stack, bool, error)
}
// GetStack wraps the Get method in a more strictly typed way
func (s *StackREST) GetStack(ctx context.Context, name string, options *metav1.GetOptions) (*iv.Stack, error) {
obj, err := s.Get(ctx, name, options)
if err != nil {
return nil, err
}
stack, ok := obj.(*iv.Stack)
if !ok {
return nil, errors.New("Object is not a stack")
}
return stack, nil
}
// CreateStack wraps the Create method in a more strictly typed way
func (s *StackREST) CreateStack(ctx context.Context, newStack *iv.Stack, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (*iv.Stack, error) {
obj, err := s.Create(ctx, newStack, createValidation, options)
if err != nil {
return nil, err
}
stack, ok := obj.(*iv.Stack)
if !ok {
return nil, errors.New("Object is not a stack")
}
return stack, nil
}
// StackTransform is a transformation used in UpdateStack
type StackTransform func(ctx context.Context, newObj *iv.Stack, oldObj *iv.Stack) (transformedNewObj *iv.Stack, err error)
// UpdateStack wraps the Update method in a more strictly typed way
func (s *StackREST) UpdateStack(ctx context.Context, name string, transform StackTransform,
createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (*iv.Stack, bool, error) {
updateObjectInfo := rest.DefaultUpdatedObjectInfo(nil,
func(ctx context.Context, newObj runtime.Object, oldObj runtime.Object) (transformedNewObj runtime.Object, err error) {
if newObj == nil {
newObj = oldObj.DeepCopyObject()
}
oldStack, ok := oldObj.(*iv.Stack)
if !ok {
return nil, errors.New("oldObj is not a stack")
}
newStack, ok := newObj.(*iv.Stack)
if !ok {
return nil, errors.New("newObj is not a stack")
}
return transform(ctx, newStack, oldStack)
})
obj, created, err := s.Update(ctx, name, updateObjectInfo, createValidation, updateValidation, forceAllowCreate, options)
if err != nil {
return nil, false, err
}
stack, ok := obj.(*iv.Stack)
if !ok {
return nil, false, errors.New("result is not a stack")
}
return stack, created, err
}
// NewStackREST return a rest store
func NewStackREST(version APIVersion, scheme rest.RESTDeleteStrategy, optsGetter generic.RESTOptionsGetter, config *restclient.Config) (*StackREST, error) {
coreClient, err := corev1.NewForConfig(config)
if err != nil {
return nil, err
}
appsClient, err := appsv1beta2.NewForConfig(config)
if err != nil {
return nil, err
}
strategy := newStackStrategy(version, scheme, coreClient, appsClient)
store := &StackREST{
genericregistry.Store{
NewFunc: func() runtime.Object { return &iv.Stack{} },
NewListFunc: func() runtime.Object { return &iv.StackList{} },
PredicateFunc: matchStack,
DefaultQualifiedResource: iv.InternalSchemeGroupVersion.WithResource("stacks").GroupResource(),
CreateStrategy: strategy,
UpdateStrategy: strategy,
DeleteStrategy: strategy,
TableConvertor: stackTableConvertor{},
},
}
options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: getStackAttrs}
if err := store.CompleteWithOptions(options); err != nil {
return nil, err
}
return store, nil
}
func getStackAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
stack, ok := obj.(*iv.Stack)
if !ok {
return nil, nil, errors.New("given object is not a Stack")
}
return labels.Set(stack.ObjectMeta.Labels), stackToSelectableFields(stack), nil
}
func matchStack(label labels.Selector, field fields.Selector) storage.SelectionPredicate {
return storage.SelectionPredicate{
Label: label,
Field: field,
GetAttrs: getStackAttrs,
}
}
func stackToSelectableFields(obj *iv.Stack) fields.Set {
return generic.ObjectMetaFieldsSet(&obj.ObjectMeta, true)
}