@@ -21,8 +21,10 @@ import (
21
21
22
22
apierrors "k8s.io/apimachinery/pkg/api/errors"
23
23
"k8s.io/apimachinery/pkg/api/meta"
24
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24
25
"k8s.io/apimachinery/pkg/runtime"
25
26
"k8s.io/apimachinery/pkg/runtime/schema"
27
+ "k8s.io/apimachinery/pkg/util/validation/field"
26
28
"sigs.k8s.io/controller-runtime/pkg/client"
27
29
)
28
30
@@ -36,14 +38,16 @@ type NamespacedClient struct {
36
38
37
39
// Get returns a single object.
38
40
func (n * NamespacedClient ) Get (ctx context.Context , key client.ObjectKey , obj client.Object , opts ... client.GetOption ) error {
39
- if key .Namespace != "default" {
40
- return apierrors .NewNotFound (schema.GroupResource {}, key .Name )
41
+ if ns := key .Namespace ; ns != metav1 .NamespaceDefault {
42
+ return apierrors .NewInvalid (obj .GetObjectKind ().GroupVersionKind ().GroupKind (), obj .GetName (),
43
+ field.ErrorList {field .Invalid (field .NewPath ("metadata" , "namespace" ), ns , "must be 'default'" )})
41
44
}
42
45
key .Namespace = n .clusterName
43
- if err := n .Client .Get (ctx , key , obj , opts ... ); err != nil {
46
+ err := n .Client .Get (ctx , key , obj , opts ... )
47
+ if err != nil {
44
48
return err
45
49
}
46
- obj .SetNamespace ("default" )
50
+ obj .SetNamespace (metav1 . NamespaceDefault )
47
51
return nil
48
52
}
49
53
@@ -53,49 +57,126 @@ func (n *NamespacedClient) List(ctx context.Context, list client.ObjectList, opt
53
57
for _ , o := range opts {
54
58
o .ApplyToList (& copts )
55
59
}
56
- if copts .Namespace != "default" {
60
+ if copts .Namespace != metav1 . NamespaceDefault {
57
61
return apierrors .NewNotFound (schema.GroupResource {}, copts .Namespace )
58
62
}
59
63
if err := n .Client .List (ctx , list , append (opts , client .InNamespace (n .clusterName ))... ); err != nil {
60
64
return err
61
65
}
62
66
return meta .EachListItem (list , func (obj runtime.Object ) error {
63
- obj .(client.Object ).SetNamespace ("default" )
67
+ obj .(client.Object ).SetNamespace (metav1 . NamespaceDefault )
64
68
return nil
65
69
})
66
70
}
67
71
68
72
// Create creates a new object.
69
73
func (n * NamespacedClient ) Create (ctx context.Context , obj client.Object , opts ... client.CreateOption ) error {
70
- panic ("implement me" )
74
+ if ns := obj .GetNamespace (); ns != metav1 .NamespaceDefault {
75
+ return apierrors .NewInvalid (obj .GetObjectKind ().GroupVersionKind ().GroupKind (), obj .GetName (),
76
+ field.ErrorList {field .Invalid (field .NewPath ("metadata" , "namespace" ), ns , "must be 'default'" )})
77
+ }
78
+ obj .SetNamespace (n .clusterName )
79
+ defer obj .SetNamespace (metav1 .NamespaceDefault )
80
+ return n .Client .Create (ctx , obj , opts ... )
71
81
}
72
82
73
83
// Delete deletes an object.
74
84
func (n * NamespacedClient ) Delete (ctx context.Context , obj client.Object , opts ... client.DeleteOption ) error {
75
- panic ("implement me" )
85
+ if ns := obj .GetNamespace (); ns != metav1 .NamespaceDefault {
86
+ return apierrors .NewInvalid (obj .GetObjectKind ().GroupVersionKind ().GroupKind (), obj .GetName (),
87
+ field.ErrorList {field .Invalid (field .NewPath ("metadata" , "namespace" ), ns , "must be 'default'" )})
88
+ }
89
+ obj .SetNamespace (n .clusterName )
90
+ defer obj .SetNamespace (metav1 .NamespaceDefault )
91
+ return n .Client .Delete (ctx , obj , opts ... )
76
92
}
77
93
78
94
// Update updates an object.
79
95
func (n * NamespacedClient ) Update (ctx context.Context , obj client.Object , opts ... client.UpdateOption ) error {
80
- panic ("implement me" )
96
+ if ns := obj .GetNamespace (); ns != metav1 .NamespaceDefault {
97
+ return apierrors .NewInvalid (obj .GetObjectKind ().GroupVersionKind ().GroupKind (), obj .GetName (),
98
+ field.ErrorList {field .Invalid (field .NewPath ("metadata" , "namespace" ), ns , "must be 'default'" )})
99
+ }
100
+ obj .SetNamespace (n .clusterName )
101
+ defer obj .SetNamespace (metav1 .NamespaceDefault )
102
+ return n .Client .Update (ctx , obj , opts ... )
81
103
}
82
104
83
105
// Patch patches an object.
84
106
func (n * NamespacedClient ) Patch (ctx context.Context , obj client.Object , patch client.Patch , opts ... client.PatchOption ) error {
85
- panic ("implement me" )
107
+ // TODO(sttts): this is not thas easy here. We likely have to support all the different patch types.
108
+ // But other than that, this is just an example provider, so ¯\_(ツ)_/¯.
109
+ panic ("implement the three patch types" )
86
110
}
87
111
88
112
// DeleteAllOf deletes all objects of the given type.
89
113
func (n * NamespacedClient ) DeleteAllOf (ctx context.Context , obj client.Object , opts ... client.DeleteAllOfOption ) error {
90
- panic ("implement me" )
114
+ if ns := obj .GetNamespace (); ns != metav1 .NamespaceDefault {
115
+ return apierrors .NewInvalid (obj .GetObjectKind ().GroupVersionKind ().GroupKind (), obj .GetName (),
116
+ field.ErrorList {field .Invalid (field .NewPath ("metadata" , "namespace" ), ns , "must be 'default'" )})
117
+ }
118
+ obj .SetNamespace (n .clusterName )
119
+ defer obj .SetNamespace (metav1 .NamespaceDefault )
120
+ return n .Client .DeleteAllOf (ctx , obj , opts ... )
91
121
}
92
122
93
123
// Status returns a subresource writer.
94
124
func (n * NamespacedClient ) Status () client.SubResourceWriter {
95
- panic ( "implement me" )
125
+ return & SubResourceNamespacedClient { clusterName : n . clusterName , client : n . Client . SubResource ( "status" )}
96
126
}
97
127
98
128
// SubResource returns a subresource client.
99
129
func (n * NamespacedClient ) SubResource (subResource string ) client.SubResourceClient {
100
- panic ("implement me" )
130
+ return & SubResourceNamespacedClient {clusterName : n .clusterName , client : n .Client .SubResource (subResource )}
131
+ }
132
+
133
+ var _ client.SubResourceClient = & SubResourceNamespacedClient {}
134
+
135
+ // SubResourceNamespacedClient is a client that operates on a specific namespace
136
+ // and subresource.
137
+ type SubResourceNamespacedClient struct {
138
+ clusterName string
139
+ client client.SubResourceClient
140
+ }
141
+
142
+ // Get returns a single object from a subresource.
143
+ func (s SubResourceNamespacedClient ) Get (ctx context.Context , obj client.Object , subResource client.Object , opts ... client.SubResourceGetOption ) error {
144
+ if ns := obj .GetNamespace (); ns != metav1 .NamespaceDefault {
145
+ return apierrors .NewInvalid (obj .GetObjectKind ().GroupVersionKind ().GroupKind (), obj .GetName (),
146
+ field.ErrorList {field .Invalid (field .NewPath ("metadata" , "namespace" ), ns , "must be 'default'" )})
147
+ }
148
+ obj .SetNamespace (s .clusterName )
149
+ defer obj .SetNamespace (metav1 .NamespaceDefault )
150
+ defer subResource .SetNamespace (metav1 .NamespaceDefault )
151
+ return s .client .Get (ctx , obj , subResource , opts ... )
152
+ }
153
+
154
+ // Create creates a new object in a subresource.
155
+ func (s SubResourceNamespacedClient ) Create (ctx context.Context , obj client.Object , subResource client.Object , opts ... client.SubResourceCreateOption ) error {
156
+ if ns := obj .GetNamespace (); ns != metav1 .NamespaceDefault {
157
+ return apierrors .NewInvalid (obj .GetObjectKind ().GroupVersionKind ().GroupKind (), obj .GetName (),
158
+ field.ErrorList {field .Invalid (field .NewPath ("metadata" , "namespace" ), ns , "must be 'default'" )})
159
+ }
160
+ obj .SetNamespace (s .clusterName )
161
+ defer obj .SetNamespace (metav1 .NamespaceDefault )
162
+ defer subResource .SetNamespace (metav1 .NamespaceDefault )
163
+ return s .client .Create (ctx , obj , subResource , opts ... )
164
+ }
165
+
166
+ // Update updates an object in a subresource.
167
+ func (s SubResourceNamespacedClient ) Update (ctx context.Context , obj client.Object , opts ... client.SubResourceUpdateOption ) error {
168
+ if ns := obj .GetNamespace (); ns != metav1 .NamespaceDefault {
169
+ return apierrors .NewInvalid (obj .GetObjectKind ().GroupVersionKind ().GroupKind (), obj .GetName (),
170
+ field.ErrorList {field .Invalid (field .NewPath ("metadata" , "namespace" ), ns , "must be 'default'" )})
171
+ }
172
+ obj .SetNamespace (s .clusterName )
173
+ defer obj .SetNamespace (metav1 .NamespaceDefault )
174
+ return s .client .Update (ctx , obj , opts ... )
175
+ }
176
+
177
+ // Patch patches an object in a subresource.
178
+ func (s SubResourceNamespacedClient ) Patch (ctx context.Context , obj client.Object , patch client.Patch , opts ... client.SubResourcePatchOption ) error {
179
+ // TODO(sttts): this is not thas easy here. We likely have to support all the different patch types.
180
+ // But other than that, this is just an example provider, so ¯\_(ツ)_/¯.
181
+ panic ("implement the three patch types" )
101
182
}
0 commit comments