Skip to content

Commit 7c268b3

Browse files
author
Antoine Pelisse
committed
Add support for ListType and ListMapKeys
These two new markers allow support for associative lists and sets.
1 parent 2a05a0f commit 7c268b3

File tree

5 files changed

+158
-2
lines changed

5 files changed

+158
-2
lines changed

pkg/crd/markers/topology.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
Copyright 2019 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package markers
18+
19+
import (
20+
"fmt"
21+
22+
apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
23+
"sigs.k8s.io/controller-tools/pkg/markers"
24+
)
25+
26+
// ToplogyMarkers list topology markers (i.e. markers that specify if a
27+
// list is an associative-list or a set, or if a map is atomic or not).
28+
var TopologyMarkers = []*definitionWithHelp{
29+
must(markers.MakeDefinition("listMapKey", markers.DescribesField, ListMapKey(""))).
30+
WithHelp(ListMapKey("").Help()),
31+
must(markers.MakeDefinition("listType", markers.DescribesField, ListType(""))).
32+
WithHelp(ListType("").Help()),
33+
}
34+
35+
func init() {
36+
AllDefinitions = append(AllDefinitions, TopologyMarkers...)
37+
}
38+
39+
// +controllertools:marker:generateHelp:category="CRD topology"
40+
41+
// ListType specifies the type of data-structure that the list
42+
// represents (map, set, atomic).
43+
//
44+
// Possible data-structure types of a list are:
45+
//
46+
// - "map": it needs to have a key field, which will be used to build an
47+
// associative list. A typical example is a the pod container list,
48+
// which is indexed by the container name.
49+
//
50+
// - "set": Fields need to be "scalar", and there can be only one
51+
// occurrence of each.
52+
//
53+
// - "atomic": All the fields in the list are treated as a single value,
54+
// are typically manipulated together by the same actor.
55+
type ListType string
56+
57+
// +controllertools:marker:generateHelp:category="CRD topology"
58+
59+
// ListMapKey specifies the keys to map listTypes.
60+
//
61+
// It indicates the index of a map list. They can be repeated if multiple keys
62+
// must be used. It can only be used when ListType is set to map, and the keys
63+
// should be scalar types.
64+
type ListMapKey string
65+
66+
func (l ListType) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
67+
if schema.Type != "array" {
68+
return fmt.Errorf("must apply listType to an array")
69+
}
70+
if l != "map" && l != "atomic" && l != "set" {
71+
return fmt.Errorf(`ListType must be either "map", "set" or "atomic"`)
72+
}
73+
p := string(l)
74+
schema.XListType = &p
75+
return nil
76+
}
77+
78+
func (l ListType) ApplyFirst() {}
79+
80+
func (l ListMapKey) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
81+
if schema.Type != "array" {
82+
return fmt.Errorf("must apply listMapKey to an array")
83+
}
84+
if schema.XListType == nil || *schema.XListType != "map" {
85+
return fmt.Errorf("must apply listMapKey to an associative-list")
86+
}
87+
schema.XListMapKeys = append(schema.XListMapKeys, string(l))
88+
return nil
89+
}

pkg/crd/markers/zz_generated.markerhelp.go

Lines changed: 24 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/crd/testdata/cronjob_types.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ type CronJobSpec struct {
126126
// +kubebuilder:validation:EmbeddedResource
127127
// +kubebuilder:validation:nullable
128128
UnprunedEmbeddedResource runtime.RawExtension `json:"unprunedEmbeddedResource"`
129+
130+
// This tests that associative lists work.
131+
// +listType=map
132+
// +listMapKey=name
133+
// +listMapKey=secondary
134+
AssociativeList []AssociativeType `json:"associativeList"`
129135
}
130136

131137
type NestedObject struct {
@@ -137,6 +143,12 @@ type RootObject struct {
137143
Nested NestedObject `json:"nested"`
138144
}
139145

146+
type AssociativeType struct {
147+
Name string `json:"name"`
148+
Secondary int `json:"secondary"`
149+
Foo string `json:"foo"`
150+
}
151+
140152
// +kubebuilder:validation:MinLength=4
141153
// This tests that markers that are allowed on both fields and types are applied to types
142154
type LongerString string

pkg/crd/testdata/testdata.kubebuilder.io_cronjobs.yaml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,26 @@ spec:
3636
spec:
3737
description: CronJobSpec defines the desired state of CronJob
3838
properties:
39+
associativeList:
40+
description: This tests that associative lists work.
41+
items:
42+
properties:
43+
foo:
44+
type: string
45+
name:
46+
type: string
47+
secondary:
48+
type: integer
49+
required:
50+
- foo
51+
- name
52+
- secondary
53+
type: object
54+
type: array
55+
x-kubernetes-list-map-keys:
56+
- name
57+
- secondary
58+
x-kubernetes-list-type: map
3959
binaryName:
4060
description: This tests byte slice schema generation.
4161
format: byte
@@ -1602,6 +1622,10 @@ spec:
16021622
- containerPort
16031623
type: object
16041624
type: array
1625+
x-kubernetes-list-map-keys:
1626+
- containerPort
1627+
- protocol
1628+
x-kubernetes-list-type: map
16051629
readinessProbe:
16061630
description: 'Periodic probe of container service
16071631
readiness. Container will be removed from
@@ -2795,6 +2819,10 @@ spec:
27952819
- containerPort
27962820
type: object
27972821
type: array
2822+
x-kubernetes-list-map-keys:
2823+
- containerPort
2824+
- protocol
2825+
x-kubernetes-list-type: map
27982826
readinessProbe:
27992827
description: 'Periodic probe of container service
28002828
readiness. Container will be removed from
@@ -5018,6 +5046,7 @@ spec:
50185046
type: object
50195047
x-kubernetes-preserve-unknown-fields: true
50205048
required:
5049+
- associativeList
50215050
- binaryName
50225051
- canBeNull
50235052
- defaultedObject

pkg/crd/zz_generated.markerhelp.go

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)