Skip to content

Commit ed7d3ad

Browse files
committed
Add support for registring other types with klient
- Exposes the scheme so that users can add types to the Resource objects scheme - Add test which ensures that types registered in this way can be used by the Resource object Signed-off-by: John Schnake <[email protected]>
1 parent 7a45350 commit ed7d3ad

File tree

9 files changed

+265
-12
lines changed

9 files changed

+265
-12
lines changed

go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require (
88
k8s.io/apimachinery v0.23.0
99
k8s.io/client-go v0.23.0
1010
k8s.io/klog/v2 v2.30.0
11-
sigs.k8s.io/controller-runtime v0.11.0
11+
sigs.k8s.io/controller-runtime v0.11.1
1212
)
1313

1414
require (
@@ -17,8 +17,8 @@ require (
1717
github.com/go-logr/logr v1.2.0 // indirect
1818
github.com/gogo/protobuf v1.3.2 // indirect
1919
github.com/golang/protobuf v1.5.2 // indirect
20-
github.com/google/go-cmp v0.5.5 // indirect
21-
github.com/google/gofuzz v1.1.0 // indirect
20+
github.com/google/go-cmp v0.5.6 // indirect
21+
github.com/google/gofuzz v1.2.0 // indirect
2222
github.com/googleapis/gnostic v0.5.5 // indirect
2323
github.com/imdario/mergo v0.3.12 // indirect
2424
github.com/json-iterator/go v1.1.12 // indirect
@@ -27,7 +27,7 @@ require (
2727
github.com/pkg/errors v0.9.1 // indirect
2828
github.com/spf13/pflag v1.0.5 // indirect
2929
golang.org/x/net v0.0.0-20210825183410-e898025ed96a // indirect
30-
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect
30+
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
3131
golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8 // indirect
3232
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect
3333
golang.org/x/text v0.3.7 // indirect

go.sum

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -211,11 +211,13 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
211211
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
212212
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
213213
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
214-
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
215214
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
215+
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
216+
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
216217
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
217-
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
218218
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
219+
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
220+
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
219221
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
220222
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
221223
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@@ -594,8 +596,9 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ
594596
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
595597
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
596598
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
597-
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f h1:Qmd2pbz05z7z6lm0DrgQVVPuBm92jqujBKMHMOlOQEw=
598599
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
600+
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
601+
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
599602
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
600603
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
601604
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -934,8 +937,8 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8
934937
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
935938
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
936939
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.25/go.mod h1:Mlj9PNLmG9bZ6BHFwFKDo5afkpWyUISkb9Me0GnK66I=
937-
sigs.k8s.io/controller-runtime v0.11.0 h1:DqO+c8mywcZLFJWILq4iktoECTyn30Bkj0CwgqMpZWQ=
938-
sigs.k8s.io/controller-runtime v0.11.0/go.mod h1:KKwLiTooNGu+JmLZGn9Sl3Gjmfj66eMbCQznLP5zcqA=
940+
sigs.k8s.io/controller-runtime v0.11.1 h1:7YIHT2QnHJArj/dk9aUkYhfqfK5cIxPOX5gPECfdZLU=
941+
sigs.k8s.io/controller-runtime v0.11.1/go.mod h1:KKwLiTooNGu+JmLZGn9Sl3Gjmfj66eMbCQznLP5zcqA=
939942
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 h1:fD1pz4yfdADVNfFmcP2aBEtudwUQ1AlLnRBALr33v3s=
940943
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs=
941944
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=

klient/k8s/resources/resources.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,10 @@ import (
2121
"errors"
2222
"time"
2323

24-
"k8s.io/apimachinery/pkg/runtime"
25-
"k8s.io/client-go/rest"
26-
2724
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25+
"k8s.io/apimachinery/pkg/runtime"
2826
"k8s.io/client-go/kubernetes/scheme"
27+
"k8s.io/client-go/rest"
2928
cr "sigs.k8s.io/controller-runtime/pkg/client"
3029
"sigs.k8s.io/e2e-framework/klient/k8s"
3130
)
@@ -179,3 +178,7 @@ func (r *Resources) Annotate(obj k8s.Object, annotation map[string]string) {
179178
func (r *Resources) Label(obj k8s.Object, label map[string]string) {
180179
obj.SetLabels(label)
181180
}
181+
182+
func (r *Resources) GetScheme() *runtime.Scheme {
183+
return r.scheme
184+
}

klient/k8s/resources/resources_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@ import (
2020
"context"
2121
"encoding/json"
2222
"testing"
23+
"time"
2324

25+
"github.com/vladimirvivien/gexe"
2426
log "k8s.io/klog/v2"
27+
"sigs.k8s.io/e2e-framework/klient/k8s/resources/testdata/projectExample"
2528

2629
appsv1 "k8s.io/api/apps/v1"
2730
corev1 "k8s.io/api/core/v1"
@@ -237,3 +240,43 @@ func TestListAllPods(t *testing.T) {
237240

238241
t.Logf("pod list contains %d pods", len(pods.Items))
239242
}
243+
244+
func TestGetCRDs(t *testing.T) {
245+
res, err := New(cfg)
246+
if err != nil {
247+
t.Fatalf("Error creating new resources object: %v", err)
248+
}
249+
250+
// Register type for the API server.
251+
e := gexe.New()
252+
p := e.RunProc(`kubectl apply -f ./testdata/projectExample/resourcedefinition.yaml`)
253+
if p.Err() != nil {
254+
t.Fatalf("Failed to register CRD: %v %v", p.Err(), p.Result())
255+
}
256+
// Sometimes CRDs need just a bit of time before being ready to use.
257+
time.Sleep(5 * time.Second)
258+
259+
// Create one
260+
p = e.RunProc(`kubectl apply -f ./testdata/projectExample/project.yaml`)
261+
if p.Err() != nil {
262+
t.Fatalf("Failed to create a CRD via yaml: %v %v", p.Err(), p.Result())
263+
}
264+
265+
// See that we can't list it because we don't know the type.
266+
ps := &projectExample.ProjectList{}
267+
err = res.List(context.TODO(), ps)
268+
if err == nil {
269+
t.Error("Expected error while listing custom resources before adding it to scheme, but got none")
270+
}
271+
272+
// Register type with klient.
273+
if err := projectExample.AddToScheme(res.GetScheme()); err != nil {
274+
t.Fatalf("Failed to add to resource scheme: %v", err)
275+
}
276+
277+
// See that we can after registering it.
278+
err = res.List(context.TODO(), ps)
279+
if err != nil {
280+
t.Error("error while listing custom resources", err)
281+
}
282+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
apiVersion: "example.martin-helmich.de/v1alpha1"
2+
kind: "Project"
3+
metadata:
4+
name: "example-project"
5+
namespace: "default"
6+
spec:
7+
replicas: 1
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
Copyright 2022 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+
/*
18+
MIT License
19+
20+
Copyright (c) 2018 Martin Helmich <[email protected]>
21+
22+
Permission is hereby granted, free of charge, to any person obtaining a copy
23+
of this software and associated documentation files (the "Software"), to deal
24+
in the Software without restriction, including without limitation the rights
25+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
26+
copies of the Software, and to permit persons to whom the Software is
27+
furnished to do so, subject to the following conditions:
28+
29+
The above copyright notice and this permission notice shall be included in all
30+
copies or substantial portions of the Software.
31+
32+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38+
SOFTWARE.
39+
*/
40+
41+
package projectExample
42+
43+
import (
44+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
45+
"k8s.io/apimachinery/pkg/runtime"
46+
"k8s.io/apimachinery/pkg/runtime/schema"
47+
)
48+
49+
const GroupName = "example.martin-helmich.de"
50+
const GroupVersion = "v1alpha1"
51+
52+
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: GroupVersion}
53+
54+
var (
55+
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
56+
AddToScheme = SchemeBuilder.AddToScheme
57+
)
58+
59+
func addKnownTypes(scheme *runtime.Scheme) error {
60+
scheme.AddKnownTypes(SchemeGroupVersion,
61+
&Project{},
62+
&ProjectList{},
63+
)
64+
65+
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
66+
return nil
67+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
apiVersion: "apiextensions.k8s.io/v1"
2+
kind: "CustomResourceDefinition"
3+
metadata:
4+
name: "projects.example.martin-helmich.de"
5+
spec:
6+
group: "example.martin-helmich.de"
7+
scope: "Namespaced"
8+
names:
9+
plural: "projects"
10+
singular: "project"
11+
kind: "Project"
12+
versions:
13+
- name: "v1alpha1"
14+
# Each version can be enabled/disabled by Served flag.
15+
served: true
16+
# One and only one version must be marked as the storage version.
17+
storage: true
18+
schema:
19+
openAPIV3Schema:
20+
type: object
21+
required: ["spec"]
22+
properties:
23+
spec:
24+
type: object
25+
required: ["replicas"]
26+
properties:
27+
replicas:
28+
type: "integer"
29+
minimum: 1
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
Copyright 2022 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+
/*
18+
MIT License
19+
20+
Copyright (c) 2018 Martin Helmich <[email protected]>
21+
22+
Permission is hereby granted, free of charge, to any person obtaining a copy
23+
of this software and associated documentation files (the "Software"), to deal
24+
in the Software without restriction, including without limitation the rights
25+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
26+
copies of the Software, and to permit persons to whom the Software is
27+
furnished to do so, subject to the following conditions:
28+
29+
The above copyright notice and this permission notice shall be included in all
30+
copies or substantial portions of the Software.
31+
32+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38+
SOFTWARE.
39+
*/
40+
41+
package projectExample
42+
43+
import (
44+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
45+
"k8s.io/apimachinery/pkg/runtime"
46+
)
47+
48+
type ProjectSpec struct {
49+
CronSpec string `json:"cronSpec"`
50+
Image string `json:"image"`
51+
Replicas int `json:"replicas"`
52+
}
53+
54+
type Project struct {
55+
metav1.TypeMeta `json:",inline"`
56+
metav1.ObjectMeta `json:"metadata,omitempty"`
57+
58+
Spec ProjectSpec `json:"spec"`
59+
}
60+
61+
type ProjectList struct {
62+
metav1.TypeMeta `json:",inline"`
63+
metav1.ListMeta `json:"metadata,omitempty"`
64+
65+
Items []Project `json:"items"`
66+
}
67+
68+
// DeepCopyInto copies all properties of this object into another object of the
69+
// same type that is provided as a pointer.
70+
func (in *Project) DeepCopyInto(out *Project) {
71+
out.TypeMeta = in.TypeMeta
72+
out.ObjectMeta = in.ObjectMeta
73+
out.Spec = ProjectSpec{
74+
Replicas: in.Spec.Replicas,
75+
}
76+
}
77+
78+
// DeepCopyObject returns a generically typed copy of an object
79+
func (in *Project) DeepCopyObject() runtime.Object {
80+
out := Project{}
81+
in.DeepCopyInto(&out)
82+
83+
return &out
84+
}
85+
86+
// DeepCopyObject returns a generically typed copy of an object
87+
func (in *ProjectList) DeepCopyObject() runtime.Object {
88+
out := ProjectList{}
89+
out.TypeMeta = in.TypeMeta
90+
out.ListMeta = in.ListMeta
91+
92+
if in.Items != nil {
93+
out.Items = make([]Project, len(in.Items))
94+
for i := range in.Items {
95+
in.Items[i].DeepCopyInto(&out.Items[i])
96+
}
97+
}
98+
99+
return &out
100+
}

pkg/envconf/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ func (c *Config) NewClient() (klient.Client, error) {
112112
return nil, fmt.Errorf("envconfig: client failed: %w", err)
113113
}
114114
c.client = client
115+
115116
return c.client, nil
116117
}
117118

0 commit comments

Comments
 (0)