Skip to content

Commit 7aa4e39

Browse files
committed
Work
1 parent a61e2ad commit 7aa4e39

File tree

3 files changed

+106
-131
lines changed

3 files changed

+106
-131
lines changed

go.mod

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ module sigs.k8s.io/controller-runtime
22

33
go 1.24.0
44

5+
replace k8s.io/apimachinery => /Users/alvaro/git/go/src/k8s.io/kubernetes/staging/src/k8s.io/apimachinery
6+
7+
replace k8s.io/client-go => /Users/alvaro/git/go/src/k8s.io/kubernetes/staging/src/k8s.io/client-go
8+
59
require (
610
github.com/blang/semver/v4 v4.0.0
711
github.com/evanphx/json-patch/v5 v5.9.11

pkg/client/fake/client.go

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ func (f *ClientBuilder) Build() client.WithWatch {
277277
// Use corresponding scheme to ensure the converter error
278278
// for types it can't handle.
279279
clientgoapplyconfigurations.NewTypeConverter(clientgoscheme.Scheme),
280-
managedfields.NewDeducedTypeConverter(),
280+
managedfields.NewDeducedTypeConverter(), // TODO: Don't do this by default
281281
}
282282
}
283283
f.objectTracker = testing.NewFieldManagedObjectTracker(
@@ -409,6 +409,9 @@ func convertFromUnstructuredIfNecessary(s *runtime.Scheme, o runtime.Object) (ru
409409
if err != nil {
410410
return nil, fmt.Errorf("scheme recognizes %s but failed to produce an object for it: %w", gvk, err)
411411
}
412+
if _, isTypedUnstructured := typed.(runtime.Unstructured); isTypedUnstructured {
413+
return o, nil
414+
}
412415

413416
unstructuredSerialized, err := json.Marshal(u)
414417
if err != nil {
@@ -418,6 +421,16 @@ func convertFromUnstructuredIfNecessary(s *runtime.Scheme, o runtime.Object) (ru
418421
return nil, fmt.Errorf("failed to unmarshal the content of %T into %T: %w", u, typed, err)
419422
}
420423

424+
// Clear out apiVersion
425+
if metaType, isMetaType := typed.(interface {
426+
// Yes, there is a metav1.Type interface but metav1.TypeMeta does not implement it
427+
SetGroupVersionKind(gvk schema.GroupVersionKind)
428+
}); isMetaType {
429+
metaType.SetGroupVersionKind(schema.GroupVersionKind{})
430+
println("setting")
431+
}
432+
println("returning converted")
433+
421434
return typed, nil
422435
}
423436

@@ -431,15 +444,36 @@ func (t versionedTracker) Update(gvr schema.GroupVersionResource, obj runtime.Ob
431444
}
432445

433446
func (t versionedTracker) update(gvr schema.GroupVersionResource, obj runtime.Object, ns string, isStatus, deleting bool, opts metav1.UpdateOptions) error {
434-
obj, err := t.updateObject(gvr, obj, ns, isStatus, deleting, opts.DryRun)
447+
gvk, err := apiutil.GVKForObject(obj, t.scheme)
448+
if err != nil {
449+
return err
450+
}
451+
obj, err = t.updateObject(gvr, obj, ns, isStatus, deleting, opts.DryRun)
435452
if err != nil {
436453
return err
437454
}
438455
if obj == nil {
439456
return nil
440457
}
441458

442-
return t.ObjectTracker.Update(gvr, obj, ns, opts)
459+
//TODO: Need to convert back
460+
// obj, err = convertFromUnstructuredIfNecessary(t.scheme, obj)
461+
// if err != nil {
462+
// return err
463+
// }
464+
465+
// TODO this should not get cleared in updateObject
466+
if u, unstructured := obj.(*unstructured.Unstructured); unstructured {
467+
u.SetGroupVersionKind(gvk)
468+
}
469+
470+
println("Kind", obj.GetObjectKind().GroupVersionKind().Kind)
471+
fmt.Printf("%T\n", obj)
472+
err = t.ObjectTracker.Update(gvr, obj, ns, opts)
473+
if err != nil {
474+
println("upstream tracker err", err.Error())
475+
}
476+
return err
443477
}
444478

445479
func (t versionedTracker) Patch(gvr schema.GroupVersionResource, obj runtime.Object, ns string, opts ...metav1.PatchOptions) error {
@@ -560,6 +594,9 @@ func (t versionedTracker) updateObject(gvr schema.GroupVersionResource, obj runt
560594
func (c *fakeClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {
561595
c.schemeLock.RLock()
562596
defer c.schemeLock.RUnlock()
597+
if err := c.addToSchemeIfUnknownAndUnstructured(obj); err != nil {
598+
return err
599+
}
563600
gvr, err := getGVRFromObject(obj, c.scheme)
564601
if err != nil {
565602
return err
@@ -594,6 +631,9 @@ func (c *fakeClient) Get(ctx context.Context, key client.ObjectKey, obj client.O
594631
}
595632

596633
func (c *fakeClient) Watch(ctx context.Context, list client.ObjectList, opts ...client.ListOption) (watch.Interface, error) {
634+
if err := c.addToSchemeIfUnknownAndUnstructured(list); err != nil {
635+
return nil, err
636+
}
597637
gvk, err := apiutil.GVKForObject(list, c.scheme)
598638
if err != nil {
599639
return nil, err
@@ -611,6 +651,9 @@ func (c *fakeClient) Watch(ctx context.Context, list client.ObjectList, opts ...
611651
func (c *fakeClient) List(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) error {
612652
c.schemeLock.RLock()
613653
defer c.schemeLock.RUnlock()
654+
if err := c.addToSchemeIfUnknownAndUnstructured(obj); err != nil {
655+
return err
656+
}
614657
gvk, err := apiutil.GVKForObject(obj, c.scheme)
615658
if err != nil {
616659
return err
@@ -780,6 +823,11 @@ func (c *fakeClient) IsObjectNamespaced(obj runtime.Object) (bool, error) {
780823
func (c *fakeClient) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error {
781824
c.schemeLock.RLock()
782825
defer c.schemeLock.RUnlock()
826+
827+
if err := c.addToSchemeIfUnknownAndUnstructured(obj); err != nil {
828+
return err
829+
}
830+
783831
createOptions := &client.CreateOptions{}
784832
createOptions.ApplyOptions(opts)
785833

@@ -818,6 +866,10 @@ func (c *fakeClient) Create(ctx context.Context, obj client.Object, opts ...clie
818866
func (c *fakeClient) Delete(ctx context.Context, obj client.Object, opts ...client.DeleteOption) error {
819867
c.schemeLock.RLock()
820868
defer c.schemeLock.RUnlock()
869+
870+
if err := c.addToSchemeIfUnknownAndUnstructured(obj); err != nil {
871+
return err
872+
}
821873
gvr, err := getGVRFromObject(obj, c.scheme)
822874
if err != nil {
823875
return err
@@ -865,6 +917,10 @@ func (c *fakeClient) Delete(ctx context.Context, obj client.Object, opts ...clie
865917
func (c *fakeClient) DeleteAllOf(ctx context.Context, obj client.Object, opts ...client.DeleteAllOfOption) error {
866918
c.schemeLock.RLock()
867919
defer c.schemeLock.RUnlock()
920+
921+
if err := c.addToSchemeIfUnknownAndUnstructured(obj); err != nil {
922+
return err
923+
}
868924
gvk, err := apiutil.GVKForObject(obj, c.scheme)
869925
if err != nil {
870926
return err
@@ -916,6 +972,10 @@ func (c *fakeClient) Update(ctx context.Context, obj client.Object, opts ...clie
916972
func (c *fakeClient) update(obj client.Object, isStatus bool, opts ...client.UpdateOption) error {
917973
c.schemeLock.RLock()
918974
defer c.schemeLock.RUnlock()
975+
976+
if err := c.addToSchemeIfUnknownAndUnstructured(obj); err != nil {
977+
return err
978+
}
919979
updateOptions := &client.UpdateOptions{}
920980
updateOptions.ApplyOptions(opts)
921981

@@ -946,6 +1006,11 @@ func (c *fakeClient) Patch(ctx context.Context, obj client.Object, patch client.
9461006
func (c *fakeClient) patch(obj client.Object, patch client.Patch, opts ...client.PatchOption) error {
9471007
c.schemeLock.RLock()
9481008
defer c.schemeLock.RUnlock()
1009+
1010+
if err := c.addToSchemeIfUnknownAndUnstructured(obj); err != nil {
1011+
return err
1012+
}
1013+
9491014
patchOptions := &client.PatchOptions{}
9501015
patchOptions.ApplyOptions(opts)
9511016

@@ -1659,3 +1724,27 @@ func AddIndex(c client.Client, obj runtime.Object, field string, extractValue cl
16591724

16601725
return nil
16611726
}
1727+
1728+
func (f *fakeClient) addToSchemeIfUnknownAndUnstructured(obj runtime.Object) error {
1729+
f.schemeLock.Lock()
1730+
defer f.schemeLock.Unlock()
1731+
1732+
_, isUnstructured := obj.(*unstructured.Unstructured)
1733+
_, isUnstructuredList := obj.(*unstructured.UnstructuredList)
1734+
_, isPartial := obj.(*metav1.PartialObjectMetadata)
1735+
_, isPartialList := obj.(*metav1.PartialObjectMetadataList)
1736+
if !isUnstructured && !isUnstructuredList && !isPartial && !isPartialList {
1737+
return nil
1738+
}
1739+
1740+
gvk, err := apiutil.GVKForObject(obj, f.scheme)
1741+
if err != nil {
1742+
return err
1743+
}
1744+
1745+
if !f.scheme.Recognizes(gvk) {
1746+
f.scheme.AddKnownTypeWithName(gvk, obj)
1747+
}
1748+
1749+
return nil
1750+
}

pkg/client/fake/client_test.go

Lines changed: 10 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -587,29 +587,24 @@ var _ = Describe("Fake client", func() {
587587
obj := &corev1.ConfigMap{}
588588
err = cl.Get(context.Background(), namespacedName, obj)
589589
Expect(err).ToNot(HaveOccurred())
590+
obj.SetManagedFields(newcm.GetManagedFields())
590591
Expect(obj).To(Equal(newcm))
591592
Expect(obj.ObjectMeta.ResourceVersion).To(Equal("1000"))
592593
})
593594

594595
It("should allow patch when the patch sets RV to 'null'", func() {
595-
schemeBuilder := &scheme.Builder{GroupVersion: schema.GroupVersion{Group: "test", Version: "v1"}}
596-
schemeBuilder.Register(&WithPointerMeta{}, &WithPointerMetaList{})
597-
598-
scheme := runtime.NewScheme()
599-
Expect(schemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred())
600-
601-
cl := NewClientBuilder().WithScheme(scheme).Build()
602-
original := &WithPointerMeta{
603-
ObjectMeta: &metav1.ObjectMeta{
596+
cl := NewClientBuilder().Build()
597+
original := &appsv1.Deployment{
598+
ObjectMeta: metav1.ObjectMeta{
604599
Name: "obj",
605600
Namespace: "ns2",
606601
}}
607602

608603
err := cl.Create(context.Background(), original)
609604
Expect(err).ToNot(HaveOccurred())
610605

611-
newObj := &WithPointerMeta{
612-
ObjectMeta: &metav1.ObjectMeta{
606+
newObj := &appsv1.Deployment{
607+
ObjectMeta: metav1.ObjectMeta{
613608
Name: original.Name,
614609
Namespace: original.Namespace,
615610
Annotations: map[string]string{
@@ -619,7 +614,7 @@ var _ = Describe("Fake client", func() {
619614

620615
Expect(cl.Patch(context.Background(), newObj, client.MergeFrom(original))).To(Succeed())
621616

622-
patched := &WithPointerMeta{}
617+
patched := &appsv1.Deployment{}
623618
Expect(cl.Get(context.Background(), client.ObjectKeyFromObject(original), patched)).To(Succeed())
624619
Expect(patched.Annotations).To(Equal(map[string]string{"foo": "bar"}))
625620
})
@@ -1938,12 +1933,13 @@ var _ = Describe("Fake client", func() {
19381933
obj.APIVersion = u.GetAPIVersion()
19391934
obj.Kind = u.GetKind()
19401935
obj.ResourceVersion = actual.ResourceVersion
1936+
obj.ManagedFields = actual.ManagedFields
19411937
// only the spec mutation should persist
19421938
obj.Spec.RestartPolicy = corev1.RestartPolicyNever
19431939
Expect(cmp.Diff(obj, actual)).To(BeEmpty())
19441940
})
19451941

1946-
It("should not change non-status field of known unstructured objects that have a status subresource on status update", func() {
1942+
FIt("should not change non-status field of known unstructured objects that have a status subresource on status update", func() {
19471943
obj := &corev1.Pod{
19481944
ObjectMeta: metav1.ObjectMeta{
19491945
Name: "pod",
@@ -1975,6 +1971,7 @@ var _ = Describe("Fake client", func() {
19751971
actual := &corev1.Pod{}
19761972
Expect(cl.Get(context.Background(), client.ObjectKeyFromObject(obj), actual)).To(Succeed())
19771973
obj.ResourceVersion = actual.ResourceVersion
1974+
obj.ManagedFields = actual.ManagedFields
19781975
// only the status mutation should persist
19791976
obj.Status.Phase = corev1.PodRunning
19801977
Expect(cmp.Diff(obj, actual)).To(BeEmpty())
@@ -2142,121 +2139,6 @@ var _ = Describe("Fake client", func() {
21422139
Expect(podList.Items[0].TypeMeta).To(Equal(metav1.TypeMeta{}))
21432140
})
21442141

2145-
It("should be able to Get an object that has pointer fields for metadata", func() {
2146-
schemeBuilder := &scheme.Builder{GroupVersion: schema.GroupVersion{Group: "test", Version: "v1"}}
2147-
schemeBuilder.Register(&WithPointerMeta{}, &WithPointerMetaList{})
2148-
scheme := runtime.NewScheme()
2149-
Expect(schemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred())
2150-
2151-
cl := NewClientBuilder().
2152-
WithScheme(scheme).
2153-
WithObjects(&WithPointerMeta{ObjectMeta: &metav1.ObjectMeta{
2154-
Name: "foo",
2155-
}}).
2156-
Build()
2157-
2158-
var object WithPointerMeta
2159-
Expect(cl.Get(context.Background(), client.ObjectKey{Name: "foo"}, &object)).NotTo(HaveOccurred())
2160-
})
2161-
2162-
It("should be able to List an object type that has pointer fields for metadata", func() {
2163-
schemeBuilder := &scheme.Builder{GroupVersion: schema.GroupVersion{Group: "test", Version: "v1"}}
2164-
schemeBuilder.Register(&WithPointerMeta{}, &WithPointerMetaList{})
2165-
scheme := runtime.NewScheme()
2166-
Expect(schemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred())
2167-
2168-
cl := NewClientBuilder().
2169-
WithScheme(scheme).
2170-
WithObjects(&WithPointerMeta{ObjectMeta: &metav1.ObjectMeta{
2171-
Name: "foo",
2172-
}}).
2173-
Build()
2174-
2175-
var objectList WithPointerMetaList
2176-
Expect(cl.List(context.Background(), &objectList)).NotTo(HaveOccurred())
2177-
Expect(objectList.Items).To(HaveLen(1))
2178-
})
2179-
2180-
It("should be able to List an object type that has pointer fields for metadata with no results", func() {
2181-
schemeBuilder := &scheme.Builder{GroupVersion: schema.GroupVersion{Group: "test", Version: "v1"}}
2182-
schemeBuilder.Register(&WithPointerMeta{}, &WithPointerMetaList{})
2183-
scheme := runtime.NewScheme()
2184-
Expect(schemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred())
2185-
2186-
cl := NewClientBuilder().
2187-
WithScheme(scheme).
2188-
Build()
2189-
2190-
var objectList WithPointerMetaList
2191-
Expect(cl.List(context.Background(), &objectList)).NotTo(HaveOccurred())
2192-
Expect(objectList.Items).To(BeEmpty())
2193-
})
2194-
2195-
It("should be able to Patch an object type that has pointer fields for metadata", func() {
2196-
schemeBuilder := &scheme.Builder{GroupVersion: schema.GroupVersion{Group: "test", Version: "v1"}}
2197-
schemeBuilder.Register(&WithPointerMeta{}, &WithPointerMetaList{})
2198-
scheme := runtime.NewScheme()
2199-
Expect(schemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred())
2200-
2201-
obj := &WithPointerMeta{ObjectMeta: &metav1.ObjectMeta{
2202-
Name: "foo",
2203-
}}
2204-
cl := NewClientBuilder().
2205-
WithScheme(scheme).
2206-
WithObjects(obj).
2207-
Build()
2208-
2209-
original := obj.DeepCopy()
2210-
obj.Labels = map[string]string{"foo": "bar"}
2211-
Expect(cl.Patch(context.Background(), obj, client.MergeFrom(original))).NotTo(HaveOccurred())
2212-
2213-
Expect(cl.Get(context.Background(), client.ObjectKey{Name: "foo"}, obj)).NotTo(HaveOccurred())
2214-
Expect(obj.Labels).To(Equal(map[string]string{"foo": "bar"}))
2215-
})
2216-
2217-
It("should be able to Update an object type that has pointer fields for metadata", func() {
2218-
schemeBuilder := &scheme.Builder{GroupVersion: schema.GroupVersion{Group: "test", Version: "v1"}}
2219-
schemeBuilder.Register(&WithPointerMeta{}, &WithPointerMetaList{})
2220-
scheme := runtime.NewScheme()
2221-
Expect(schemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred())
2222-
2223-
obj := &WithPointerMeta{ObjectMeta: &metav1.ObjectMeta{
2224-
Name: "foo",
2225-
}}
2226-
cl := NewClientBuilder().
2227-
WithScheme(scheme).
2228-
WithObjects(obj).
2229-
Build()
2230-
2231-
Expect(cl.Get(context.Background(), client.ObjectKey{Name: "foo"}, obj)).NotTo(HaveOccurred())
2232-
2233-
obj.Labels = map[string]string{"foo": "bar"}
2234-
Expect(cl.Update(context.Background(), obj)).NotTo(HaveOccurred())
2235-
2236-
Expect(cl.Get(context.Background(), client.ObjectKey{Name: "foo"}, obj)).NotTo(HaveOccurred())
2237-
Expect(obj.Labels).To(Equal(map[string]string{"foo": "bar"}))
2238-
})
2239-
2240-
It("should be able to Delete an object type that has pointer fields for metadata", func() {
2241-
schemeBuilder := &scheme.Builder{GroupVersion: schema.GroupVersion{Group: "test", Version: "v1"}}
2242-
schemeBuilder.Register(&WithPointerMeta{}, &WithPointerMetaList{})
2243-
scheme := runtime.NewScheme()
2244-
Expect(schemeBuilder.AddToScheme(scheme)).NotTo(HaveOccurred())
2245-
2246-
obj := &WithPointerMeta{ObjectMeta: &metav1.ObjectMeta{
2247-
Name: "foo",
2248-
}}
2249-
cl := NewClientBuilder().
2250-
WithScheme(scheme).
2251-
WithObjects(obj).
2252-
Build()
2253-
2254-
Expect(cl.Delete(context.Background(), obj)).NotTo(HaveOccurred())
2255-
2256-
err := cl.Get(context.Background(), client.ObjectKey{Name: "foo"}, obj)
2257-
Expect(apierrors.IsNotFound(err)).To(BeTrue())
2258-
})
2259-
22602142
It("should allow concurrent patches to a configMap", func() {
22612143
scheme := runtime.NewScheme()
22622144
Expect(corev1.AddToScheme(scheme)).To(Succeed())

0 commit comments

Comments
 (0)