Skip to content

Commit

Permalink
Merge pull request #384 from justinsb/set_generation
Browse files Browse the repository at this point in the history
mockkubeapiserver: set generation on objects
  • Loading branch information
k8s-ci-robot committed Jun 10, 2024
2 parents e4510cb + 0712ebd commit 2ee9f09
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 29 deletions.
6 changes: 0 additions & 6 deletions mockkubeapiserver/hooks/crd.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,6 @@ func (s *CRDHook) updateCRDConditions(ev *storage.WatchEvent) error {
return fmt.Errorf("status was of unexpected type %T", statusObj)
}

generation := u.GetGeneration()
if generation == 0 {
generation = 1
u.SetGeneration(generation)
}

var conditions []interface{}
conditions = append(conditions, map[string]interface{}{
"type": "NamesAccepted",
Expand Down
8 changes: 1 addition & 7 deletions mockkubeapiserver/hooks/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,6 @@ func (s *DeploymentHook) deploymentChanged(ev *storage.WatchEvent) error {
return fmt.Errorf("status was of unexpected type %T", statusObj)
}

generation := u.GetGeneration()
if generation == 0 {
generation = 1
u.SetGeneration(generation)
}

replicasVal, _, err := unstructured.NestedFieldNoCopy(u.Object, "spec", "replicas")
if err != nil {
return fmt.Errorf("error getting spec.replicas: %w", err)
Expand Down Expand Up @@ -91,7 +85,7 @@ func (s *DeploymentHook) deploymentChanged(ev *storage.WatchEvent) error {
status["replicas"] = replicas
status["updatedReplicas"] = replicas

observedGeneration := generation
observedGeneration := u.GetGeneration()
status["observedGeneration"] = observedGeneration

return nil
Expand Down
15 changes: 15 additions & 0 deletions mockkubeapiserver/patchresource.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"fmt"
"io"
"net/http"
"reflect"
"strconv"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -79,6 +80,11 @@ func (req *patchResource) Run(ctx context.Context, s *MockKubeAPIServer) error {
// TODO: Should we treat this like an apply to an empty object?

patched := body

if resource.SetsGeneration() {
patched.SetGeneration(1)
}

if err := resource.CreateObject(ctx, id, patched); err != nil {
return err
}
Expand Down Expand Up @@ -124,6 +130,15 @@ func (req *patchResource) Run(ctx context.Context, s *MockKubeAPIServer) error {
klog.Infof("skipping write, object not changed")
return req.writeResponse(existingObj)
} else {
if resource.SetsGeneration() {
specIsSame := reflect.DeepEqual(existingObj.Object["spec"], updated.Object["spec"])
if !specIsSame {
generation := updated.GetGeneration()
generation++
updated.SetGeneration(generation)
}
}

if err := resource.UpdateObject(ctx, id, updated); err != nil {
return err
}
Expand Down
4 changes: 4 additions & 0 deletions mockkubeapiserver/postresource.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ func (req *postResource) Run(ctx context.Context, s *MockKubeAPIServer) error {
return fmt.Errorf("name must be provided in payload")
}

if resource.SetsGeneration() {
obj.SetGeneration(1)
}

if err := resource.CreateObject(ctx, id, obj); err != nil {
return err
}
Expand Down
9 changes: 9 additions & 0 deletions mockkubeapiserver/putresource.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,15 @@ func (req *putResource) Run(ctx context.Context, s *MockKubeAPIServer) error {
return req.writeResponse(original)
}

if resource.SetsGeneration() {
specIsSame := reflect.DeepEqual(original.Object["spec"], updated.Object["spec"])
if !specIsSame {
generation := updated.GetGeneration()
generation++
updated.SetGeneration(generation)
}
}

if err := resource.UpdateObject(ctx, id, updated); err != nil {
return err
}
Expand Down
4 changes: 4 additions & 0 deletions mockkubeapiserver/storage/memorystorage/memorystorage.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ func (s *MemoryStorage) AddObject(obj *unstructured.Unstructured) error {
return fmt.Errorf("object group/version/kind %v not known", gvk)
}

if resource.SetsGeneration() {
obj.SetGeneration(1)
}

return resource.CreateObject(ctx, id, obj)
}

Expand Down
16 changes: 16 additions & 0 deletions mockkubeapiserver/storage/memorystorage/resourceinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,19 @@ func (r *memoryResourceInfo) ListGVK() schema.GroupVersionKind {
func (r *memoryResourceInfo) ParseableType() *typed.ParseableType {
return r.parseableType
}

func (r *memoryResourceInfo) SetsGeneration() bool {
// Not all resources support metadata.generation; it looks like only those with status do (?)
// For now, exclude some well-known types that do not set metadata.generation.
switch r.gvk.GroupKind() {
case schema.GroupKind{Group: "", Kind: "ConfigMap"}:
return false
case schema.GroupKind{Group: "", Kind: "Secret"}:
return false
case schema.GroupKind{Group: "", Kind: "Namespace"}:
return false

default:
return true
}
}
3 changes: 3 additions & 0 deletions mockkubeapiserver/storage/resourceinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ type ResourceInfo interface {
ListGVK() schema.GroupVersionKind
ParseableType() *typed.ParseableType

// SetsGeneration is true if we should automatically set metadata.generation for this resource kind.
SetsGeneration() bool

GetObject(ctx context.Context, id types.NamespacedName) (*unstructured.Unstructured, bool, error)

ListObjects(ctx context.Context, filter ListFilter) (*unstructured.UnstructuredList, error)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ Accept: application/json, */*

200 OK
Cache-Control: no-cache, private
Content-Length: 364
Content-Length: 379
Content-Type: application/json
Date: (removed)

{"apiVersion":"addons.example.org/v1alpha1","items":[{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"creationTimestamp":"2022-01-01T00:00:01Z","name":"simple1","namespace":"ns1","resourceVersion":"2","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"}}],"kind":"SimpleTestList","metadata":{"resourceVersion":"2"}}
{"apiVersion":"addons.example.org/v1alpha1","items":[{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"creationTimestamp":"2022-01-01T00:00:01Z","generation":1,"name":"simple1","namespace":"ns1","resourceVersion":"2","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"}}],"kind":"SimpleTestList","metadata":{"resourceVersion":"2"}}

---

Expand Down Expand Up @@ -219,16 +219,16 @@ PUT http://kube-apiserver/apis/addons.example.org/v1alpha1/namespaces/ns1/simple
Accept: application/json, */*
Content-Type: application/json

{"kind":"SimpleTest","apiVersion":"addons.example.org/v1alpha1","metadata":{"name":"simple1","namespace":"ns1","uid":"00000000-0000-0000-0000-000000000002","resourceVersion":"2","creationTimestamp":"2022-01-01T00:00:01Z"},"spec":{"channel":"stable"},"status":{"healthy":true}}
{"kind":"SimpleTest","apiVersion":"addons.example.org/v1alpha1","metadata":{"name":"simple1","namespace":"ns1","uid":"00000000-0000-0000-0000-000000000002","resourceVersion":"2","generation":1,"creationTimestamp":"2022-01-01T00:00:01Z"},"spec":{"channel":"stable"},"status":{"healthy":true}}


200 OK
Cache-Control: no-cache, private
Content-Length: 276
Content-Length: 291
Content-Type: application/json
Date: (removed)

{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"creationTimestamp":"2022-01-01T00:00:01Z","name":"simple1","namespace":"ns1","resourceVersion":"5","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"healthy":true}}
{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"creationTimestamp":"2022-01-01T00:00:01Z","generation":1,"name":"simple1","namespace":"ns1","resourceVersion":"5","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"healthy":true}}

---

Expand Down Expand Up @@ -301,13 +301,13 @@ PUT http://kube-apiserver/apis/addons.example.org/v1alpha1/namespaces/ns1/simple
Accept: application/json, */*
Content-Type: application/json

{"kind":"SimpleTest","apiVersion":"addons.example.org/v1alpha1","metadata":{"name":"simple1","namespace":"ns1","uid":"00000000-0000-0000-0000-000000000002","resourceVersion":"5","creationTimestamp":"2022-01-01T00:00:01Z"},"spec":{"channel":"stable"},"status":{"healthy":true}}
{"kind":"SimpleTest","apiVersion":"addons.example.org/v1alpha1","metadata":{"name":"simple1","namespace":"ns1","uid":"00000000-0000-0000-0000-000000000002","resourceVersion":"5","generation":1,"creationTimestamp":"2022-01-01T00:00:01Z"},"spec":{"channel":"stable"},"status":{"healthy":true}}


200 OK
Cache-Control: no-cache, private
Content-Length: 276
Content-Length: 291
Content-Type: application/json
Date: (removed)

{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"creationTimestamp":"2022-01-01T00:00:01Z","name":"simple1","namespace":"ns1","resourceVersion":"5","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"healthy":true}}
{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"creationTimestamp":"2022-01-01T00:00:01Z","generation":1,"name":"simple1","namespace":"ns1","resourceVersion":"5","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"healthy":true}}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ Accept: application/json, */*

200 OK
Cache-Control: no-cache, private
Content-Length: 364
Content-Length: 379
Content-Type: application/json
Date: (removed)

{"apiVersion":"addons.example.org/v1alpha1","items":[{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"creationTimestamp":"2022-01-01T00:00:01Z","name":"simple1","namespace":"ns1","resourceVersion":"2","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"}}],"kind":"SimpleTestList","metadata":{"resourceVersion":"2"}}
{"apiVersion":"addons.example.org/v1alpha1","items":[{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"creationTimestamp":"2022-01-01T00:00:01Z","generation":1,"name":"simple1","namespace":"ns1","resourceVersion":"2","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"}}],"kind":"SimpleTestList","metadata":{"resourceVersion":"2"}}

---

Expand Down Expand Up @@ -118,16 +118,16 @@ PUT http://kube-apiserver/apis/addons.example.org/v1alpha1/namespaces/ns1/simple
Accept: application/json, */*
Content-Type: application/json

{"kind":"SimpleTest","apiVersion":"addons.example.org/v1alpha1","metadata":{"name":"simple1","namespace":"ns1","uid":"00000000-0000-0000-0000-000000000002","resourceVersion":"2","creationTimestamp":"2022-01-01T00:00:01Z","labels":{"applyset.kubernetes.io/id":"applyset-xbxAWnAItX3p1Gxrs86F-ZQAGwGoys9xxQGK3IED7bY-v1"},"annotations":{"applyset.kubernetes.io/additional-namespaces":"","applyset.kubernetes.io/contains-group-kinds":"ConfigMap,Deployment.apps","applyset.kubernetes.io/tooling":"SimpleTest/"}},"spec":{"channel":"stable"},"status":{"healthy":false}}
{"kind":"SimpleTest","apiVersion":"addons.example.org/v1alpha1","metadata":{"name":"simple1","namespace":"ns1","uid":"00000000-0000-0000-0000-000000000002","resourceVersion":"2","generation":1,"creationTimestamp":"2022-01-01T00:00:01Z","labels":{"applyset.kubernetes.io/id":"applyset-xbxAWnAItX3p1Gxrs86F-ZQAGwGoys9xxQGK3IED7bY-v1"},"annotations":{"applyset.kubernetes.io/additional-namespaces":"","applyset.kubernetes.io/contains-group-kinds":"ConfigMap,Deployment.apps","applyset.kubernetes.io/tooling":"SimpleTest/"}},"spec":{"channel":"stable"},"status":{"healthy":false}}


200 OK
Cache-Control: no-cache, private
Content-Length: 561
Content-Length: 576
Content-Type: application/json
Date: (removed)

{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"annotations":{"applyset.kubernetes.io/additional-namespaces":"","applyset.kubernetes.io/contains-group-kinds":"ConfigMap,Deployment.apps","applyset.kubernetes.io/tooling":"SimpleTest/"},"creationTimestamp":"2022-01-01T00:00:01Z","labels":{"applyset.kubernetes.io/id":"applyset-xbxAWnAItX3p1Gxrs86F-ZQAGwGoys9xxQGK3IED7bY-v1"},"name":"simple1","namespace":"ns1","resourceVersion":"3","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"healthy":false}}
{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"annotations":{"applyset.kubernetes.io/additional-namespaces":"","applyset.kubernetes.io/contains-group-kinds":"ConfigMap,Deployment.apps","applyset.kubernetes.io/tooling":"SimpleTest/"},"creationTimestamp":"2022-01-01T00:00:01Z","generation":1,"labels":{"applyset.kubernetes.io/id":"applyset-xbxAWnAItX3p1Gxrs86F-ZQAGwGoys9xxQGK3IED7bY-v1"},"name":"simple1","namespace":"ns1","resourceVersion":"3","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"healthy":false}}

---

Expand Down Expand Up @@ -193,15 +193,15 @@ PUT http://kube-apiserver/apis/addons.example.org/v1alpha1/namespaces/ns1/simple
Accept: application/json, */*
Content-Type: application/json

{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"annotations":{"applyset.kubernetes.io/additional-namespaces":"","applyset.kubernetes.io/contains-group-kinds":"ConfigMap,Deployment.apps","applyset.kubernetes.io/tooling":"SimpleTest/"},"creationTimestamp":"2022-01-01T00:00:01Z","labels":{"applyset.kubernetes.io/id":"applyset-xbxAWnAItX3p1Gxrs86F-ZQAGwGoys9xxQGK3IED7bY-v1"},"name":"simple1","namespace":"ns1","resourceVersion":"3","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"conditions":[{"lastTransitionTime":"2022-01-01T00:00:00Z","message":"all manifests are reconciled.","reason":"Normal","status":"True","type":"Ready"}],"healthy":true,"phase":"Current"}}
{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"annotations":{"applyset.kubernetes.io/additional-namespaces":"","applyset.kubernetes.io/contains-group-kinds":"ConfigMap,Deployment.apps","applyset.kubernetes.io/tooling":"SimpleTest/"},"creationTimestamp":"2022-01-01T00:00:01Z","generation":1,"labels":{"applyset.kubernetes.io/id":"applyset-xbxAWnAItX3p1Gxrs86F-ZQAGwGoys9xxQGK3IED7bY-v1"},"name":"simple1","namespace":"ns1","resourceVersion":"3","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"conditions":[{"lastTransitionTime":"2022-01-01T00:00:00Z","message":"all manifests are reconciled.","reason":"Normal","status":"True","type":"Ready"}],"healthy":true,"phase":"Current"}}

200 OK
Cache-Control: no-cache, private
Content-Length: 730
Content-Length: 745
Content-Type: application/json
Date: (removed)

{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"annotations":{"applyset.kubernetes.io/additional-namespaces":"","applyset.kubernetes.io/contains-group-kinds":"ConfigMap,Deployment.apps","applyset.kubernetes.io/tooling":"SimpleTest/"},"creationTimestamp":"2022-01-01T00:00:01Z","labels":{"applyset.kubernetes.io/id":"applyset-xbxAWnAItX3p1Gxrs86F-ZQAGwGoys9xxQGK3IED7bY-v1"},"name":"simple1","namespace":"ns1","resourceVersion":"6","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"conditions":[{"lastTransitionTime":"2022-01-01T00:00:00Z","message":"all manifests are reconciled.","reason":"Normal","status":"True","type":"Ready"}],"healthy":true,"phase":"Current"}}
{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"annotations":{"applyset.kubernetes.io/additional-namespaces":"","applyset.kubernetes.io/contains-group-kinds":"ConfigMap,Deployment.apps","applyset.kubernetes.io/tooling":"SimpleTest/"},"creationTimestamp":"2022-01-01T00:00:01Z","generation":1,"labels":{"applyset.kubernetes.io/id":"applyset-xbxAWnAItX3p1Gxrs86F-ZQAGwGoys9xxQGK3IED7bY-v1"},"name":"simple1","namespace":"ns1","resourceVersion":"6","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"conditions":[{"lastTransitionTime":"2022-01-01T00:00:00Z","message":"all manifests are reconciled.","reason":"Normal","status":"True","type":"Ready"}],"healthy":true,"phase":"Current"}}

---

Expand Down

0 comments on commit 2ee9f09

Please sign in to comment.