diff --git a/pkg/controller/constraint/constraint_controller.go b/pkg/controller/constraint/constraint_controller.go index 4b3db3d19f7..03d40e1e1aa 100644 --- a/pkg/controller/constraint/constraint_controller.go +++ b/pkg/controller/constraint/constraint_controller.go @@ -49,8 +49,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes" - rest "k8s.io/client-go/rest" "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/apiutil" @@ -75,11 +73,12 @@ var ( ErrValidatingAdmissionPolicyAPIDisabled = errors.New("ValidatingAdmissionPolicy API is not enabled") ErrVAPConditionsNotSatisfied = errors.New("Conditions are not satisfied to generate ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding") ) -var vapMux sync.RWMutex -var VapAPIEnabled *bool +// var vapMux sync.RWMutex -var GroupVersion *schema.GroupVersion +// var VapAPIEnabled *bool + +// var GroupVersion *schema.GroupVersion type Adder struct { CFClient *constraintclient.Client @@ -317,7 +316,7 @@ func (r *ReconcileConstraint) Reconcile(ctx context.Context, request reconcile.R isAPIEnabled := false var groupVersion *schema.GroupVersion if generateVAPB { - isAPIEnabled, groupVersion = IsVapAPIEnabled() + isAPIEnabled, groupVersion = transform.IsVapAPIEnabled(&log) } if generateVAPB { if !isAPIEnabled { @@ -348,7 +347,7 @@ func (r *ReconcileConstraint) Reconcile(ctx context.Context, request reconcile.R r.log.Info("constraint controller", "generateVAPB", generateVAPB) // generate vapbinding resources if generateVAPB && groupVersion != nil { - currentVapBinding, err := vapBindingForVersion(*groupVersion) + currentVapBinding, err := transform.VapForVersion(groupVersion) if err != nil { return reconcile.Result{}, r.reportErrorOnConstraintStatus(ctx, status, err, "could not get ValidatingAdmissionPolicyBinding API version") } @@ -389,7 +388,7 @@ func (r *ReconcileConstraint) Reconcile(ctx context.Context, request reconcile.R // do not generate vapbinding resources // remove if exists if !generateVAPB && groupVersion != nil { - currentVapBinding, err := vapBindingForVersion(*groupVersion) + currentVapBinding, err := transform.VapForVersion(groupVersion) if err != nil { return reconcile.Result{}, r.reportErrorOnConstraintStatus(ctx, status, err, "could not get ValidatingAdmissionPolicyBinding API version") } @@ -620,78 +619,6 @@ func (c *ConstraintsCache) reportTotalConstraints(ctx context.Context, reporter } } -func IsVapAPIEnabled() (bool, *schema.GroupVersion) { - vapMux.RLock() - if VapAPIEnabled != nil { - apiEnabled, gvk := *VapAPIEnabled, GroupVersion - vapMux.RUnlock() - return apiEnabled, gvk - } - - vapMux.RUnlock() - vapMux.Lock() - defer vapMux.Unlock() - - if VapAPIEnabled != nil { - return *VapAPIEnabled, GroupVersion - } - config, err := rest.InClusterConfig() - if err != nil { - log.Info("IsVapAPIEnabled InClusterConfig", "error", err) - VapAPIEnabled = new(bool) - *VapAPIEnabled = false - return false, nil - } - clientset, err := kubernetes.NewForConfig(config) - if err != nil { - log.Info("IsVapAPIEnabled NewForConfig", "error", err) - *VapAPIEnabled = false - return false, nil - } - - groupVersion := admissionregistrationv1.SchemeGroupVersion - resList, err := clientset.Discovery().ServerResourcesForGroupVersion(groupVersion.String()) - if err == nil { - for i := 0; i < len(resList.APIResources); i++ { - if resList.APIResources[i].Name == "validatingadmissionpolicies" { - VapAPIEnabled = new(bool) - *VapAPIEnabled = true - GroupVersion = &groupVersion - return true, GroupVersion - } - } - } - - groupVersion = admissionregistrationv1beta1.SchemeGroupVersion - resList, err = clientset.Discovery().ServerResourcesForGroupVersion(groupVersion.String()) - if err == nil { - for i := 0; i < len(resList.APIResources); i++ { - if resList.APIResources[i].Name == "validatingadmissionpolicies" { - VapAPIEnabled = new(bool) - *VapAPIEnabled = true - GroupVersion = &groupVersion - return true, GroupVersion - } - } - } - - log.Error(err, "error checking VAP API availability", "IsVapAPIEnabled", "false") - VapAPIEnabled = new(bool) - *VapAPIEnabled = false - return false, nil -} - -func vapBindingForVersion(gvk schema.GroupVersion) (client.Object, error) { - switch gvk.Version { - case "v1": - return &admissionregistrationv1.ValidatingAdmissionPolicyBinding{}, nil - case "v1beta1": - return &admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding{}, nil - default: - return nil, errors.New("unrecognized version") - } -} - func getRunTimeVAPBinding(gvk *schema.GroupVersion, transformedVapBinding *admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding, currentVapBinding client.Object) (client.Object, error) { if currentVapBinding == nil { if gvk.Version == "v1" { diff --git a/pkg/controller/constrainttemplate/constrainttemplate_controller.go b/pkg/controller/constrainttemplate/constrainttemplate_controller.go index 6af47e58c0c..45a530cf66b 100644 --- a/pkg/controller/constrainttemplate/constrainttemplate_controller.go +++ b/pkg/controller/constrainttemplate/constrainttemplate_controller.go @@ -22,6 +22,7 @@ import ( "reflect" "time" + "github.com/go-logr/logr" "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" @@ -69,6 +70,7 @@ var ( discoveryErr *apiutil.ErrResourceDiscoveryFailed ) +var g *logr.Logger var gvkConstraintTemplate = schema.GroupVersionKind{ Group: v1beta1.SchemeGroupVersion.Group, Version: v1beta1.SchemeGroupVersion.Version, @@ -479,7 +481,7 @@ func (r *ReconcileConstraintTemplate) handleUpdate( isVapAPIEnabled := false var groupVersion *schema.GroupVersion if generateVap { - isVapAPIEnabled, groupVersion = constraint.IsVapAPIEnabled() + isVapAPIEnabled, groupVersion = transform.IsVapAPIEnabled(&logger) } logger.Info("isVapAPIEnabled", "isVapAPIEnabled", isVapAPIEnabled) logger.Info("groupVersion", "groupVersion", groupVersion) @@ -490,7 +492,7 @@ func (r *ReconcileConstraintTemplate) handleUpdate( } // generating vap resources if generateVap && isVapAPIEnabled && groupVersion != nil { - currentVap, err := vapForVersion(groupVersion) + currentVap, err := transform.VapForVersion(groupVersion) if err != nil { logger.Error(err, "error getting vap object with respective groupVersion") err := r.reportErrorOnCTStatus(ctx, ErrCreateCode, "Could not get VAP with runtime group version", status, err) @@ -545,7 +547,7 @@ func (r *ReconcileConstraintTemplate) handleUpdate( // do not generate vap resources // remove if exists if !generateVap && isVapAPIEnabled && groupVersion != nil { - currentVap, err := vapForVersion(groupVersion) + currentVap, err := transform.VapForVersion(groupVersion) if err != nil { logger.Error(err, "error getting vap object with respective groupVersion") err := r.reportErrorOnCTStatus(ctx, ErrCreateCode, "Could not get VAP with correct group version", status, err) @@ -747,17 +749,6 @@ func makeGvk(kind string) schema.GroupVersionKind { } } -func vapForVersion(gvk *schema.GroupVersion) (client.Object, error) { - switch gvk.Version { - case "v1": - return &admissionregistrationv1.ValidatingAdmissionPolicy{}, nil - case "v1beta1": - return &admissionregistrationv1beta1.ValidatingAdmissionPolicy{}, nil - default: - return nil, errors.New("unrecognized version") - } -} - func getRunTimeVAP(gvk *schema.GroupVersion, transformedVap *admissionregistrationv1beta1.ValidatingAdmissionPolicy, currentVap client.Object) (client.Object, error) { if currentVap == nil { if gvk.Version == "v1" { diff --git a/pkg/drivers/k8scel/transform/vap_util.go b/pkg/drivers/k8scel/transform/vap_util.go new file mode 100644 index 00000000000..2f9a088c659 --- /dev/null +++ b/pkg/drivers/k8scel/transform/vap_util.go @@ -0,0 +1,93 @@ +package transform + +import ( + "errors" + "sync" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/kubernetes" + "sigs.k8s.io/controller-runtime/pkg/client" + + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" + rest "k8s.io/client-go/rest" +) + +var vapMux sync.RWMutex + +var VapAPIEnabled *bool + +var GroupVersion *schema.GroupVersion + +func IsVapAPIEnabled(log *logr.Logger) (bool, *schema.GroupVersion) { + vapMux.RLock() + if VapAPIEnabled != nil { + apiEnabled, gvk := *VapAPIEnabled, GroupVersion + vapMux.RUnlock() + return apiEnabled, gvk + } + + vapMux.RUnlock() + vapMux.Lock() + defer vapMux.Unlock() + + if VapAPIEnabled != nil { + return *VapAPIEnabled, GroupVersion + } + config, err := rest.InClusterConfig() + if err != nil { + log.Info("IsVapAPIEnabled InClusterConfig", "error", err) + VapAPIEnabled = new(bool) + *VapAPIEnabled = false + return false, nil + } + clientset, err := kubernetes.NewForConfig(config) + if err != nil { + log.Info("IsVapAPIEnabled NewForConfig", "error", err) + *VapAPIEnabled = false + return false, nil + } + + groupVersion := admissionregistrationv1.SchemeGroupVersion + resList, err := clientset.Discovery().ServerResourcesForGroupVersion(groupVersion.String()) + if err == nil { + for i := 0; i < len(resList.APIResources); i++ { + if resList.APIResources[i].Name == "validatingadmissionpolicies" { + VapAPIEnabled = new(bool) + *VapAPIEnabled = true + GroupVersion = &groupVersion + return true, GroupVersion + } + } + } + + groupVersion = admissionregistrationv1beta1.SchemeGroupVersion + resList, err = clientset.Discovery().ServerResourcesForGroupVersion(groupVersion.String()) + if err == nil { + for i := 0; i < len(resList.APIResources); i++ { + if resList.APIResources[i].Name == "validatingadmissionpolicies" { + VapAPIEnabled = new(bool) + *VapAPIEnabled = true + GroupVersion = &groupVersion + return true, GroupVersion + } + } + } + + log.Error(err, "error checking VAP API availability", "IsVapAPIEnabled", "false") + VapAPIEnabled = new(bool) + *VapAPIEnabled = false + return false, nil +} + +func VapForVersion(gvk *schema.GroupVersion) (client.Object, error) { + switch gvk.Version { + case "v1": + return &admissionregistrationv1.ValidatingAdmissionPolicy{}, nil + case "v1beta1": + return &admissionregistrationv1beta1.ValidatingAdmissionPolicy{}, nil + default: + return nil, errors.New("unrecognized version") + } +}