-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathschema.go
More file actions
206 lines (181 loc) · 6.5 KB
/
schema.go
File metadata and controls
206 lines (181 loc) · 6.5 KB
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
package resource
import (
"fmt"
"reflect"
"strings"
)
type SchemaScope string
const (
NamespacedScope = SchemaScope("Namespaced")
ClusterScope = SchemaScope("Cluster")
)
// Schema is an interface which represents an object schema for a particular group, version, and kind.
// It allows a user to create an empty/default instance of the associated go Object for that schema,
// and encapsulates methods for accessing information about the schema.
// When combined with read/write methods, it becomes a Kind.
type Schema interface {
// Group returns the Schema group
Group() string
// Version returns the Schema version
Version() string
// Kind returns the Schema kind
Kind() string
// Plural returns the plural name of the Schema kind
Plural() string
// ZeroValue returns the "zero-value", "default", or "empty" version of an Object of this Schema
ZeroValue() Object
// ZeroListValue returns a ListObject implementation which represents an empty (or appropriately "zero-value")
// version of the Schema's List.
ZeroListValue() ListObject
// Scope returns the scope of the schema object
Scope() SchemaScope
// SelectableFields returns a list of fully-qualified field selectors which can be used for querying
SelectableFields() []SelectableField
}
// SelectableField is a struct which represents the FieldSelector string and function to retrieve the value of that
// FieldSelector from an Object. SelectableFields may be generic for all Object implementations,
// or specific to one or a set.
type SelectableField struct {
FieldSelector string
// FieldValueFunc is a function which returns the value of the FieldSelector in the provided Object,
// or an error if the Object is not of the correct underlying type, or the value cannot be retrieved for any reason
FieldValueFunc func(Object) (string, error)
}
// SchemaGroup represents a group of Schemas. The interface does not require commonality between Schemas,
// but an implementation may require a relationship.
//
// Deprecated: Kinds are now favored over Schemas for usage.
type SchemaGroup interface {
Schemas() []Schema
}
// SimpleSchema is a simple implementation of Schema. It can be used for constructing simple Schemas,
// though the easiest way to define a schema is via codegen.
// TODO: codegen info
type SimpleSchema struct {
group string
version string
kind string
plural string
scope SchemaScope
selectableFields []SelectableField
zero Object
zeroList ListObject
}
// Group returns the SimpleSchema's Group
func (s *SimpleSchema) Group() string {
return s.group
}
// Version returns the SimpleSchema's Version
func (s *SimpleSchema) Version() string {
return s.version
}
// Kind returns the SimpleSchema's Kind
func (s *SimpleSchema) Kind() string {
return s.kind
}
// Plural returns the SimpleSchema's Plural
func (s *SimpleSchema) Plural() string {
return s.plural
}
// Scope returns the SimpleSchema's Scope
func (s *SimpleSchema) Scope() SchemaScope {
return s.scope
}
// ZeroValue returns a copy the SimpleSchema's zero-valued Object instance
// It can be used directly, as the returned interface is a copy.
func (s *SimpleSchema) ZeroValue() Object {
return s.zero.Copy()
}
// ZeroListValue returns a copy the SimpleSchema's zero-valued ListObject instance
// It can be used directly, as the returned interface is a copy.
func (s *SimpleSchema) ZeroListValue() ListObject {
return s.zeroList.Copy()
}
// SelectableFields returns the list of field selectors that can be used for querying this schema
// TODO: should this be in the kind instead of the schema?
func (s *SimpleSchema) SelectableFields() []SelectableField {
return s.selectableFields
}
// SimpleSchemaGroup collects schemas with the same group and version
//
// Deprecated: Kinds are now favored over Schemas for usage. Use KindGroup instead.
type SimpleSchemaGroup struct {
group string
version string
schemas []Schema
}
// Schemas returns the SimpleSchemaGroup's list of Schemas
func (g *SimpleSchemaGroup) Schemas() []Schema {
return g.schemas
}
// AddSchema creates a new SimpleSchema with the SimpleSchemaGroup's group and version,
// adds it to the SimpleSchemaGroup, and returns the created SimpleSchema
func (g *SimpleSchemaGroup) AddSchema(zeroVal Object, zeroList ListObject, opts ...SimpleSchemaOption) *SimpleSchema {
s := NewSimpleSchema(g.group, g.version, zeroVal, zeroList, opts...)
g.schemas = append(g.schemas, s)
return s
}
// SimpleSchemaOption is an options function that can be passed to NewSimpleSchema to modify the resulting output
type SimpleSchemaOption func(*SimpleSchema)
// WithPlural returns a SimpleSchemaOption that sets the SimpleSchema's Plural to the provided string
func WithPlural(plural string) func(*SimpleSchema) {
return func(s *SimpleSchema) {
s.plural = plural
}
}
// WithKind returns a SimpleSchemaOption that sets the SimpleSchema's Kind to the provided string
// TODO: still unsure on whether kind should be optional?
// It feels non-idiomatic to grab the kind from the reflected type name
func WithKind(kind string) func(*SimpleSchema) {
return func(s *SimpleSchema) {
s.kind = kind
}
}
// WithScope returns a SimpleSchemaOption that sets the SimpleSchema's Scope to the provided SchemaScope
func WithScope(scope SchemaScope) func(schema *SimpleSchema) {
return func(s *SimpleSchema) {
s.scope = scope
}
}
// WithSelectableFields returns a SimpleSchemaOption that sets the SimpleSchema's SelectableFields to the provided selectableFields
func WithSelectableFields(selectableFields []SelectableField) func(schema *SimpleSchema) {
return func(s *SimpleSchema) {
s.selectableFields = selectableFields
}
}
// NewSimpleSchema returns a new SimpleSchema
func NewSimpleSchema(group, version string, zeroVal Object, zeroList ListObject, opts ...SimpleSchemaOption) *SimpleSchema {
s := SimpleSchema{
group: group,
version: version,
zero: zeroVal,
zeroList: zeroList,
}
for _, opt := range opts {
opt(&s)
}
if s.kind == "" {
t := reflect.TypeOf(zeroVal)
for t.Kind() == reflect.Pointer {
t = t.Elem()
}
s.kind = t.Name()
}
if s.scope == "" {
s.scope = NamespacedScope
}
if s.plural == "" {
s.plural = fmt.Sprintf("%ss", strings.ToLower(s.kind))
}
return &s
}
// NewSimpleSchemaGroup returns a new SimpleSchemaGroup
//
// Deprecated: Kinds are now favored over Schemas for usage. Use KindGroup instead.
func NewSimpleSchemaGroup(group, version string) *SimpleSchemaGroup {
return &SimpleSchemaGroup{
group: group,
version: version,
schemas: make([]Schema, 0),
}
}