kubewarden / kubewarden-controller

Manage admission policies in your Kubernetes cluster with ease
https://kubewarden.io
Apache License 2.0
191 stars 33 forks source link

Minor bug: policyserver controller errors as watch enters twice per ClusterAdmissionPolicies deletion #136

Closed viccuad closed 2 years ago

viccuad commented 2 years ago

Changes to ClusterAdmissionPolicies such as performing a Delete trigger the watch of policyserver_controller.go twice (or so it seems). This doesn't break the functionality, but makes the operations fail on the second run, printing inocuous, albeit bad looking errors.

Example 1

Instantiate an ClusterAdmissionPolicy into the default PolicyServer. Wait for it to be active. Then delete it. Notice that there is an error:

  1. "the object has been modified; please apply your changes to the latest version and try again".

The policy gets Deleted. The change in the object triggers the watch in policyserver_controller.go, exiting through https://github.com/viccuad/kubewarden-controller/blob/a0b9e9397b0d8f66ac17cdebe26ab773a20a4ced/controllers/policies/policyserver_controller.go#L200-L206. No change has been performed in the policy inside the watch, we go through directly to the PolicyServer reconciler loop, that will take care of de-registering the policy webhooks and removing the Finalizer. Still, we get an error.

2021-12-10T11:03:16.962Z    DEBUG    controller-runtime.webhook.webhooks    received request    {"webhook": "/mutate-policies-kubewarden-io-v1alpha2-clusteradmissionpolicy", "UID": "12da5674-874c-4ee2-b8dc-534a73bee5da", "kind": "policies.kubewarden.io/v1alpha2, Kind=ClusterAdmission
Policy", "resource": {"group":"policies.kubewarden.io","version":"v1alpha2","resource":"clusteradmissionpolicies"}}                                                                                                                                                                         
2021-12-10T11:03:16.962Z    INFO    clusteradmissionpolicy-resource    default    {"name": "local-pod-privileged-policy2"}                                                                                                                                                                  
2021-12-10T11:03:16.963Z    DEBUG    controller-runtime.webhook.webhooks    wrote response    {"webhook": "/mutate-policies-kubewarden-io-v1alpha2-clusteradmissionpolicy", "code": 200, "reason": "", "UID": "12da5674-874c-4ee2-b8dc-534a73bee5da", "allowed": true}                      
2021-12-10T11:03:16.968Z    DEBUG    controller-runtime.webhook.webhooks    received request    {"webhook": "/validate-policies-kubewarden-io-v1alpha2-clusteradmissionpolicy", "UID": "dcf32249-d38a-457f-b7a5-4e7f1f312f42", "kind": "policies.kubewarden.io/v1alpha2, Kind=ClusterAdmissi
onPolicy", "resource": {"group":"policies.kubewarden.io","version":"v1alpha2","resource":"clusteradmissionpolicies"}}                                                                                                                                                                       
2021-12-10T11:03:16.968Z    INFO    clusteradmissionpolicy-resource    validate create    {"name": "local-pod-privileged-policy2"}                                                                                                                                                          
2021-12-10T11:03:16.968Z    DEBUG    controller-runtime.webhook.webhooks    wrote response    {"webhook": "/validate-policies-kubewarden-io-v1alpha2-clusteradmissionpolicy", "code": 200, "reason": "", "UID": "dcf32249-d38a-457f-b7a5-4e7f1f312f42", "allowed": true}                    
2021-12-10T11:03:16.984Z    INFO    controllers.policies.ClusterAdmissionPolicy    policy local-pod-privileged-policy2 pending                                                                                                                                                              
2021-12-10T11:03:17.033Z    INFO    controllers.policies.ClusterAdmissionPolicy    deployment patched    {"policyserver": "/default"}                                                                                                                                                       
2021-12-10T11:03:17.043Z    INFO    controllers.policies.ClusterAdmissionPolicy    delaying policy registration since policy server is not yet ready    {"policyserver": "/default"}                                                                                                        
2021-12-10T11:03:22.117Z    INFO    controllers.policies.ClusterAdmissionPolicy    delaying policy registration since policy server is not yet ready    {"policyserver": "/default"}                                                                                                        
2021-12-10T11:03:27.213Z    INFO    controllers.policies.ClusterAdmissionPolicy    delaying policy registration since policy server is not yet ready    {"policyserver": "/default"}                                                                                                        
2021-12-10T11:03:32.261Z    INFO    controllers.policies.ClusterAdmissionPolicy    delaying policy registration since policy server is not yet ready    {"policyserver": "/default"}                                                                                                        
2021-12-10T11:03:37.306Z    INFO    controllers.policies.ClusterAdmissionPolicy    policy local-pod-privileged-policy2 active    {"policyserver": "/default"}                                                                                                                               
2021-12-10T11:03:44.282Z    ERROR    controllers.policies.ClusterAdmissionPolicy    cannot update status of policy local-pod-privileged-policy2    {"error": "failed to update status of ClusterAdmissionPolicy \"&ObjectMeta{Name:local-pod-privileged-policy2,GenerateName:,Namespace:,S
elfLink:,UID:0050cdda-3a62-423f-b804-1566bdc87887,ResourceVersion:7612,Generation:1,CreationTimestamp:2021-12-10 11:03:16 +0000 UTC,DeletionTimestamp:<nil>,DeletionGracePeriodSeconds:nil,Labels:map[string]string{},Annotations:map[string]string{kubectl.kubernetes.io/last-applied-confi
guration: {\\\"apiVersion\\\":\\\"policies.kubewarden.io/v1alpha2\\\",\\\"kind\\\":\\\"ClusterAdmissionPolicy\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"name\\\":\\\"local-pod-privileged-policy2\\\"},\\\"spec\\\":{\\\"module\\\":\\\"registry://ghcr.io/kubewarden/policies/psp-ca
pabilities:v0.1.3\\\",\\\"mutating\\\":false,\\\"rules\\\":[{\\\"apiGroups\\\":[\\\"\\\"],\\\"apiVersions\\\":[\\\"v1\\\"],\\\"operations\\\":[\\\"CREATE\\\",\\\"UPDATE\\\"],\\\"resources\\\":[\\\"pods\\\"]}]}}\\n,},OwnerReferences:[]OwnerReference{},Finalizers:[kubewarden],ClusterNa
me:,ManagedFields:[]ManagedFieldsEntry{ManagedFieldsEntry{Manager:kubectl-client-side-apply,Operation:Update,APIVersion:policies.kubewarden.io/v1alpha2,Time:2021-12-10 11:03:16 +0000 UTC,FieldsType:FieldsV1,FieldsV1:{\\\"f:metadata\\\":{\\\"f:annotations\\\":{\\\".\\\":{},\\\"f:kubec
tl.kubernetes.io/last-applied-configuration\\\":{}}},\\\"f:spec\\\":{\\\".\\\":{},\\\"f:module\\\":{},\\\"f:mutating\\\":{},\\\"f:policyServer\\\":{},\\\"f:rules\\\":{}}},Subresource:,},ManagedFieldsEntry{Manager:manager,Operation:Update,APIVersion:policies.kubewarden.io/v1alpha2,Tim
e:2021-12-10 11:03:37 +0000 UTC,FieldsType:FieldsV1,FieldsV1:{\\\"f:status\\\":{\\\".\\\":{},\\\"f:conditions\\\":{\\\".\\\":{},\\\"k:{\\\\\\\"type\\\\\\\":\\\\\\\"PolicyActive\\\\\\\"}\\\":{\\\".\\\":{},\\\"f:lastTransitionTime\\\":{},\\\"f:message\\\":{},\\\"f:reason\\\":{},\\\"f:s
tatus\\\":{},\\\"f:type\\\":{}}},\\\"f:policyStatus\\\":{}}},Subresource:,},},}\", \"Operation cannot be fulfilled on clusteradmissionpolicies.policies.kubewarden.io \\\"local-pod-privileged-policy2\\\": the object has been modified; please apply your changes to the latest version an
d try again\""}                                                                                                                                                                                                                                                                             
sigs.k8s.io/controller-runtime/pkg/handler.(*enqueueRequestsFromMapFunc).Update                                                                                                                                                                                                             
    /go/pkg/mod/sigs.k8s.io/controller-runtime@v0.10.0/pkg/handler/enqueue_mapped.go:63                                                                                                                                                                                                     
sigs.k8s.io/controller-runtime/pkg/source/internal.EventHandler.OnUpdate                                                                                                                                                                                                                    
    /go/pkg/mod/sigs.k8s.io/controller-runtime@v0.10.0/pkg/source/internal/eventsource.go:94                                                                                                                                                                                                
k8s.io/client-go/tools/cache.(*processorListener).run.func1                                                                                                                                                                                                                                 
    /go/pkg/mod/k8s.io/client-go@v0.22.1/tools/cache/shared_informer.go:775                                                                                                                                                                                                                 
k8s.io/apimachinery/pkg/util/wait.BackoffUntil.func1                                                                                                                                                                                                                                        
    /go/pkg/mod/k8s.io/apimachinery@v0.22.1/pkg/util/wait/wait.go:155                                                                                                                                                                                                                       
k8s.io/apimachinery/pkg/util/wait.BackoffUntil                                                                                                                                                                                                                                              
    /go/pkg/mod/k8s.io/apimachinery@v0.22.1/pkg/util/wait/wait.go:156                                                                                                                                                                                                                       
k8s.io/apimachinery/pkg/util/wait.JitterUntil                                                                                                                                                                                                                                               
    /go/pkg/mod/k8s.io/apimachinery@v0.22.1/pkg/util/wait/wait.go:133                                                                                                                                                                                                                       
k8s.io/apimachinery/pkg/util/wait.Until                                                                                                                                                                                                                                                     
    /go/pkg/mod/k8s.io/apimachinery@v0.22.1/pkg/util/wait/wait.go:90                                                                                                                                                                                                                        
k8s.io/client-go/tools/cache.(*processorListener).run                                                                                                                                                                                                                                       
    /go/pkg/mod/k8s.io/client-go@v0.22.1/tools/cache/shared_informer.go:771                                                                                                                                                                                                                 
k8s.io/apimachinery/pkg/util/wait.(*Group).Start.func1                                                                                                                                                                                                                                      
    /go/pkg/mod/k8s.io/apimachinery@v0.22.1/pkg/util/wait/wait.go:73                                                                                                                                                                                                                        
2021-12-10T11:03:44.290Z    DEBUG    controller-runtime.webhook.webhooks    received request    {"webhook": "/mutate-policies-kubewarden-io-v1alpha2-clusteradmissionpolicy", "UID": "86791fe2-5d34-4853-9895-3c3c14e94513", "kind": "policies.kubewarden.io/v1alpha2, Kind=ClusterAdmission
Policy", "resource": {"group":"policies.kubewarden.io","version":"v1alpha2","resource":"clusteradmissionpolicies"}}                                                                                                                                                                         
2021-12-10T11:03:44.290Z    INFO    clusteradmissionpolicy-resource    default    {"name": "local-pod-privileged-policy2"}                                                                                                                                                                  
2021-12-10T11:03:44.291Z    DEBUG    controller-runtime.webhook.webhooks    wrote response    {"webhook": "/mutate-policies-kubewarden-io-v1alpha2-clusteradmissionpolicy", "code": 200, "reason": "", "UID": "86791fe2-5d34-4853-9895-3c3c14e94513", "allowed": true}                      
2021-12-10T11:03:44.292Z    DEBUG    controller-runtime.webhook.webhooks    received request    {"webhook": "/validate-policies-kubewarden-io-v1alpha2-clusteradmissionpolicy", "UID": "0f90d2aa-29f9-4dad-b4bf-7449efc8ae85", "kind": "policies.kubewarden.io/v1alpha2, Kind=ClusterAdmissi
onPolicy", "resource": {"group":"policies.kubewarden.io","version":"v1alpha2","resource":"clusteradmissionpolicies"}}                                                                                                                                                                       
2021-12-10T11:03:44.293Z    INFO    clusteradmissionpolicy-resource    validate update    {"name": "local-pod-privileged-policy2"}                                                                                                                                                          
2021-12-10T11:03:44.293Z    DEBUG    controller-runtime.webhook.webhooks    wrote response    {"webhook": "/validate-policies-kubewarden-io-v1alpha2-clusteradmissionpolicy", "code": 200, "reason": "", "UID": "0f90d2aa-29f9-4dad-b4bf-7449efc8ae85", "allowed": true}                    
2021-12-10T11:03:44.331Z    INFO    controllers.policies.ClusterAdmissionPolicy    deployment patched    {"policyserver": "/default"}                                                                                                                                                       
2021-12-10T11:03:44.342Z    INFO    controllers.policies.ClusterAdmissionPolicy    delaying policy registration since policy server is not yet ready    {"policyserver": "/default"}                                                                                                        
2021-12-10T11:03:44.384Z    INFO    controllers.policies.ClusterAdmissionPolicy    delaying policy registration since policy server is not yet ready    {"policyserver": "/default"}

Example 2

Instantiate a ClusterAdmissionPolicy that specifies an nonexistent PolicyServer. Wait for it to be unschedulable. Then, delete it (with the code from PR https://github.com/kubewarden/kubewarden-controller/pull/135). Notice that there are 2 errors:

  1. the object has been modified; please apply your changes to the latest version and try again
  2. clusteradmissionpolicies.policies.kubewarden.io \"local-pod-privileged-policy2\" not found

Error 1 seems analogous to example 1. Error 2, after debugging, seems to appear while going through https://github.com/viccuad/kubewarden-controller/blob/a0b9e9397b0d8f66ac17cdebe26ab773a20a4ced/controllers/policies/policyserver_controller.go#L181-L187. There, we are just removing the Finalizer. Which to me indicates that we go once, remove the finalizer, which triggers the watch on policyserver_controller.go and the watch of the Kubernetes controller for garbage collecting. The garbage collection happens, fully removing the policy Object from etcd. Our watch goes through, seeing a policy object with DeletionTimestamp and unschedulable, tries to remove the Finalizer, and tada, there's no object.

2021-12-10T11:12:50.704Z    DEBUG    controller-runtime.webhook.webhooks    received request    {"webhook": "/mutate-policies-kubewarden-io-v1alpha2-clusteradmissionpolicy", "UID": "a9979ba0-ec32-4545-abc4-354465cb8196", "kind": "policies.kubewarden.io/v1alpha2, Kind=ClusterAdmission
Policy", "resource": {"group":"policies.kubewarden.io","version":"v1alpha2","resource":"clusteradmissionpolicies"}}                                                                                                                                                                         
2021-12-10T11:12:50.704Z    INFO    clusteradmissionpolicy-resource    default    {"name": "local-pod-privileged-policy2"}                                                                                                                                                                  
2021-12-10T11:12:50.704Z    DEBUG    controller-runtime.webhook.webhooks    wrote response    {"webhook": "/mutate-policies-kubewarden-io-v1alpha2-clusteradmissionpolicy", "code": 200, "reason": "", "UID": "a9979ba0-ec32-4545-abc4-354465cb8196", "allowed": true}                      
2021-12-10T11:12:50.712Z    DEBUG    controller-runtime.webhook.webhooks    received request    {"webhook": "/validate-policies-kubewarden-io-v1alpha2-clusteradmissionpolicy", "UID": "a5c6808b-6df0-419a-a9f8-2d8ad7ba936a", "kind": "policies.kubewarden.io/v1alpha2, Kind=ClusterAdmissi
onPolicy", "resource": {"group":"policies.kubewarden.io","version":"v1alpha2","resource":"clusteradmissionpolicies"}}                                                                                                                                                                       
2021-12-10T11:12:50.712Z    INFO    clusteradmissionpolicy-resource    validate create    {"name": "local-pod-privileged-policy2"}                                                                                                                                                          
2021-12-10T11:12:50.712Z    DEBUG    controller-runtime.webhook.webhooks    wrote response    {"webhook": "/validate-policies-kubewarden-io-v1alpha2-clusteradmissionpolicy", "code": 200, "reason": "", "UID": "a5c6808b-6df0-419a-a9f8-2d8ad7ba936a", "allowed": true}                    
2021-12-10T11:12:50.735Z    INFO    controllers.policies.ClusterAdmissionPolicy    policy local-pod-privileged-policy2 cannot be scheduled: no matching PolicyServer                                                                                                                        
2021-12-10T11:13:14.211Z    ERROR    controllers.policies.ClusterAdmissionPolicy    cannot 2 update status of policy local-pod-privileged-policy2    {"error": "failed to update status of ClusterAdmissionPolicy \"&ObjectMeta{Name:local-pod-privileged-policy2,GenerateName:,Namespace:,S
elfLink:,UID:e5a19af1-a595-435e-a2ff-77ecee5d5c4a,ResourceVersion:9211,Generation:1,CreationTimestamp:2021-12-10 11:12:50 +0000 UTC,DeletionTimestamp:<nil>,DeletionGracePeriodSeconds:nil,Labels:map[string]string{},Annotations:map[string]string{kubectl.kubernetes.io/last-applied-confi
guration: {\\\"apiVersion\\\":\\\"policies.kubewarden.io/v1alpha2\\\",\\\"kind\\\":\\\"ClusterAdmissionPolicy\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"name\\\":\\\"local-pod-privileged-policy2\\\"},\\\"spec\\\":{\\\"module\\\":\\\"registry://ghcr.io/kubewarden/policies/psp-ca
pabilities:v0.1.3\\\",\\\"mutating\\\":false,\\\"policyServer\\\":\\\"unexistent\\\",\\\"rules\\\":[{\\\"apiGroups\\\":[\\\"\\\"],\\\"apiVersions\\\":[\\\"v1\\\"],\\\"operations\\\":[\\\"CREATE\\\",\\\"UPDATE\\\"],\\\"resources\\\":[\\\"pods\\\"]}]}}\\n,},OwnerReferences:[]OwnerRefer
ence{},Finalizers:[kubewarden],ClusterName:,ManagedFields:[]ManagedFieldsEntry{ManagedFieldsEntry{Manager:kubectl-client-side-apply,Operation:Update,APIVersion:policies.kubewarden.io/v1alpha2,Time:2021-12-10 11:12:50 +0000 UTC,FieldsType:FieldsV1,FieldsV1:{\\\"f:metadata\\\":{\\\"f:a
nnotations\\\":{\\\".\\\":{},\\\"f:kubectl.kubernetes.io/last-applied-configuration\\\":{}}},\\\"f:spec\\\":{\\\".\\\":{},\\\"f:module\\\":{},\\\"f:mutating\\\":{},\\\"f:policyServer\\\":{},\\\"f:rules\\\":{}}},Subresource:,},ManagedFieldsEntry{Manager:manager,Operation:Update,APIVer
sion:policies.kubewarden.io/v1alpha2,Time:2021-12-10 11:12:50 +0000 UTC,FieldsType:FieldsV1,FieldsV1:{\\\"f:status\\\":{\\\".\\\":{},\\\"f:policyStatus\\\":{}}},Subresource:,},},}\", \"Operation cannot be fulfilled on clusteradmissionpolicies.policies.kubewarden.io \\\"local-pod-priv
ileged-policy2\\\": the object has been modified; please apply your changes to the latest version and try again\""}                                                                                                                                                                         
sigs.k8s.io/controller-runtime/pkg/handler.(*enqueueRequestsFromMapFunc).Update                                                                                                                                                                                                             
    /go/pkg/mod/sigs.k8s.io/controller-runtime@v0.10.0/pkg/handler/enqueue_mapped.go:63                                                                                                                                                                                                     
sigs.k8s.io/controller-runtime/pkg/source/internal.EventHandler.OnUpdate                                                                                                                                                                                                                    
    /go/pkg/mod/sigs.k8s.io/controller-runtime@v0.10.0/pkg/source/internal/eventsource.go:94                                                                                                                                                                                                
k8s.io/client-go/tools/cache.(*processorListener).run.func1                                                                                                                                                                                                                                 
    /go/pkg/mod/k8s.io/client-go@v0.22.1/tools/cache/shared_informer.go:775                                                                                                                                                                                                                 
k8s.io/apimachinery/pkg/util/wait.BackoffUntil.func1                                                                                                                                                                                                                                        
    /go/pkg/mod/k8s.io/apimachinery@v0.22.1/pkg/util/wait/wait.go:155                                                                                                                                                                                                                       
k8s.io/apimachinery/pkg/util/wait.BackoffUntil                                                                                                                                                                                                                                              
    /go/pkg/mod/k8s.io/apimachinery@v0.22.1/pkg/util/wait/wait.go:156                                                                                                                                                                                                                       
k8s.io/apimachinery/pkg/util/wait.JitterUntil                                                                                                                                                                                                                                               
    /go/pkg/mod/k8s.io/apimachinery@v0.22.1/pkg/util/wait/wait.go:133                                                                                                                                                                                                                       
k8s.io/apimachinery/pkg/util/wait.Until                                                                                                                                                                                                                                                     
    /go/pkg/mod/k8s.io/apimachinery@v0.22.1/pkg/util/wait/wait.go:90                                                                                                                                                                                                                        
k8s.io/client-go/tools/cache.(*processorListener).run                                                                                                                                                                                                                                       
    /go/pkg/mod/k8s.io/client-go@v0.22.1/tools/cache/shared_informer.go:771                                                                                                                                                                                                                 
k8s.io/apimachinery/pkg/util/wait.(*Group).Start.func1                                                                                                                                                                                                                                      
    /go/pkg/mod/k8s.io/apimachinery@v0.22.1/pkg/util/wait/wait.go:73                                                                                                                                                                                                                        
2021-12-10T11:13:14.211Z    INFO    controllers.policies.ClusterAdmissionPolicy    policy local-pod-privileged-policy2 cannot be scheduled: no matching PolicyServer                                                                                                                        
2021-12-10T11:13:14.214Z    DEBUG    controller-runtime.webhook.webhooks    received request    {"webhook": "/mutate-policies-kubewarden-io-v1alpha2-clusteradmissionpolicy", "UID": "e5ce388e-ec8a-433c-bda9-b7d140402711", "kind": "policies.kubewarden.io/v1alpha2, Kind=ClusterAdmission
Policy", "resource": {"group":"policies.kubewarden.io","version":"v1alpha2","resource":"clusteradmissionpolicies"}}                                                                                                                                                                         
2021-12-10T11:13:14.214Z    INFO    clusteradmissionpolicy-resource    default    {"name": "local-pod-privileged-policy2"}                                                                                                                                                                  
2021-12-10T11:13:14.214Z    DEBUG    controller-runtime.webhook.webhooks    wrote response    {"webhook": "/mutate-policies-kubewarden-io-v1alpha2-clusteradmissionpolicy", "code": 200, "reason": "", "UID": "e5ce388e-ec8a-433c-bda9-b7d140402711", "allowed": true}                      
2021-12-10T11:13:14.216Z    DEBUG    controller-runtime.webhook.webhooks    received request    {"webhook": "/validate-policies-kubewarden-io-v1alpha2-clusteradmissionpolicy", "UID": "b6af84fd-29bc-4647-a077-6892024ac7e3", "kind": "policies.kubewarden.io/v1alpha2, Kind=ClusterAdmissi
onPolicy", "resource": {"group":"policies.kubewarden.io","version":"v1alpha2","resource":"clusteradmissionpolicies"}}                                                                                                                                                                       
2021-12-10T11:13:14.216Z    INFO    clusteradmissionpolicy-resource    validate update    {"name": "local-pod-privileged-policy2"}                                                                                                                                                          
2021-12-10T11:13:14.216Z    DEBUG    controller-runtime.webhook.webhooks    wrote response    {"webhook": "/validate-policies-kubewarden-io-v1alpha2-clusteradmissionpolicy", "code": 200, "reason": "", "UID": "b6af84fd-29bc-4647-a077-6892024ac7e3", "allowed": true}                    
2021-12-10T11:13:14.224Z    ERROR    controllers.policies.ClusterAdmissionPolicy    cannot 1 update status of policy local-pod-privileged-policy2    {"error": "clusteradmissionpolicies.policies.kubewarden.io \"local-pod-privileged-policy2\" not found"}                                
sigs.k8s.io/controller-runtime/pkg/handler.(*enqueueRequestsFromMapFunc).Delete                                                                                                                                                                                                             
    /go/pkg/mod/sigs.k8s.io/controller-runtime@v0.10.0/pkg/handler/enqueue_mapped.go:70                                                                                                                                                                                                     
sigs.k8s.io/controller-runtime/pkg/source/internal.EventHandler.OnDelete                                                                                                                                                                                                                    
    /go/pkg/mod/sigs.k8s.io/controller-runtime@v0.10.0/pkg/source/internal/eventsource.go:137                                                                                                                                                                                               
k8s.io/client-go/tools/cache.(*processorListener).run.func1                                                                                                                                                                                                                                 
    /go/pkg/mod/k8s.io/client-go@v0.22.1/tools/cache/shared_informer.go:779                                                                                                                                                                                                                 
k8s.io/apimachinery/pkg/util/wait.BackoffUntil.func1                                                                                                                                                                                                                                        
    /go/pkg/mod/k8s.io/apimachinery@v0.22.1/pkg/util/wait/wait.go:155                                                                                                                                                                                                                       
k8s.io/apimachinery/pkg/util/wait.BackoffUntil                                                                                                                                                                                                                                              
    /go/pkg/mod/k8s.io/apimachinery@v0.22.1/pkg/util/wait/wait.go:156                                                                                                                                                                                                                       
k8s.io/apimachinery/pkg/util/wait.JitterUntil                                                                                                                                                                                                                                               
    /go/pkg/mod/k8s.io/apimachinery@v0.22.1/pkg/util/wait/wait.go:133                                                                                                                                                                                                                       
k8s.io/apimachinery/pkg/util/wait.Until                                                                                                                                                                                                                                                     
    /go/pkg/mod/k8s.io/apimachinery@v0.22.1/pkg/util/wait/wait.go:90                                                                                                                                                                                                                        
k8s.io/client-go/tools/cache.(*processorListener).run                                                                                                                                                                                                                                       
    /go/pkg/mod/k8s.io/client-go@v0.22.1/tools/cache/shared_informer.go:771                                                                                                                                                                                                                 
k8s.io/apimachinery/pkg/util/wait.(*Group).Start.func1                                                                                                                                                                                                                                      
    /go/pkg/mod/k8s.io/apimachinery@v0.22.1/pkg/util/wait/wait.go:73
jvanz commented 2 years ago

This bug seems to be pretty similar to https://github.com/kubewarden/kubewarden-controller/issues/115. I guess they are the same issue. Don't you agree? If so, I believe we can close the bug that I've opened as a duplicate of this one.

viccuad commented 2 years ago

argh, yes, it's the same one. Sorry for opening a new one instead of commenting on that one. Given that here we have 2 examples, I'm happy closing that one as duplicate of this one.

jvanz commented 2 years ago

argh, yes, it's the same one. Sorry for opening a new one instead of commenting on that one. Given that here we have 2 examples, I'm happy closing that one as duplicate of this one.

Done! ;)

As the closed bug was in the Development board and you are working on this. I'm adding it in the board as well. ;)

raulcabello commented 2 years ago

It looks like watch is called twice in an update. The first time gets called with the old object and then it gets called with the new one. When we do an update or delete (which is an update because it just add the deletion timestamp), first is called with the old object, then with the new. But when is called with the old object we modify the status from active to pending https://github.com/kubewarden/kubewarden-controller/blob/main/controllers/policies/policyserver_controller.go#L185 then next time it calls with the new object and it says the error the object has been modified; please apply your changes to the latest version and try again

https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/handler@v0.10.0#EnqueueRequestsFromMapFunc

raulcabello commented 2 years ago

I would suggest moving https://github.com/kubewarden/kubewarden-controller/blob/main/controllers/policies/policyserver_controller.go#L185-L186 inside the PolicyServer reconciliation loop

viccuad commented 2 years ago

I would suggest moving https://github.com/kubewarden/kubewarden-controller/blob/main/controllers/policies/policyserver_controller.go#L185-L186 inside the PolicyServer reconciliation loop

I'm not sure it's possible. Inside the reconciliation loop one has access to the list of policies associated with the PolicyServer, but doesn't know which one is new or updated with new settings, etc. The best we could do is to mark all policies as "pending" when a PolicyServer reconcile loop is started, but I think that's wrong.

Hence, marking the policy as pending if there's a new change in it in the watch, and waiting for the PolicyServer reconcile loop to mark it as active seems a better approach.

viccuad commented 2 years ago

Looking at https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/handler@v0.10.0, I see no useful options for the handler function, so I'm sticking with handler.EnqueueRequestsFromMapFunc().

So, 2 objects per call, 1 old, 1 new. I see no way to skip the old one, which gets evaluated first. Any update on it invalidates the watch call for the new object, and triggers 2 more watch calls with the updated object.

After thinking, I see no difference between having 2 watches. I prefer not having 2 watches to reduce the number of pointers to old and new objects.

Given that any update invalidates the second watch call, I tried to minimize updates.

1. As first step, the watch defaults PolicyStatus to unscheduled, updating the object and invalidating the next watch call.

I tried to default the PolicyStatus to unscheduled on the CRD definition to reduce the amount of updates, and at least not have the first one:

  1. the kubebuilder marker // +kubebuilder:default:=unscheduled for enums doesn't take effect. See upstream issue https://github.com/kubernetes-sigs/controller-tools/issues/622 2, Tried to craft a kustomize patch, but with strategicMerge it will substitute the whole versions` list:
    # The following patch sets the Clusteradmissionpolicy status to unscheduled.
    # This is a workaround for a bug with:
    # `// +kubebuilder:default:=unscheduled`
    # as it doesn't take effect.
    # See upstream issue https://github.com/kubernetes-sigs/controller-tools/issues/622
    apiVersion: apiextensions.k8s.io/v1
    kind: CustomResourceDefinition
    metadata:
    name: clusteradmissionpolicies.policies.kubewarden.io
    spec:
    versions:
    - $patch: merge
    - additionalPrinterColumns:
    schema:
      openAPIV3Schema:
        properties:
          status:
            properties:
              policyStatus:
                default: unscheduled
  2. Changing the strategy to just Merge can only be done in the field definition. https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md#syntax-2. The field is versions, which I don't think can be changed.

2. Normal updates happen

Two cases:

None of those updates can be postponed. Minimum we have 2 updates (point 1 and 2) on the case of policies with PolicyServer. Setting PolicyStatus to pending can't be done in the reconcile loop for only the changed policies.

Then?

I can't see other way besides creating a reconciler for ClusterAdmissionPolicies. It would:

In the watch, we could then only trigger the PolicyServer reconciler for those policies that have the correct status, and are associated with a PolicyServer. This way, the watch doesn't do any Update of the object, and we can use the marked statuses in the policies to cribe calls to reconcile.

raulcabello commented 2 years ago

We might have race conditions if we add a ClusterAdmissionPolicy reconciler as both would be updating the policy status. We do not know when a ClusterAdmissionPolicy becomes active in the ClusterAdmissionPolicy reconciler, so we would still need to do this in the PolicyServer reconciler.

We check in the PolicyServer reconciler loop if any ClusterAdmissionPolicy has changed, if so we do a rollout of a new policy server. Could we check there which policy has changed and mark it as pending? I think that was done here https://github.com/kubewarden/kubewarden-controller/blob/200eb77938def4757defb88d43772b3129dc65c2/internal/pkg/admission/policy-server-configmap.go#L64 and also in the webhook reconciliation

I think we should update the ClusterAdmissionPolicy status always in the PolicyServer reconciler loop if possible. The watch should just trigger PolicyServer reconciler loop or handle orphan policies that don't have PolicyServer

Or try to find a way to sync both reconciliers, so we don't have race conditions. I don't know if it's possible to always run them in a specific order