diff --git a/controllers/state_of_the_world.go b/controllers/state_of_the_world.go index 563db511d..3189ef545 100644 --- a/controllers/state_of_the_world.go +++ b/controllers/state_of_the_world.go @@ -5,10 +5,15 @@ import ( "fmt" "strings" + certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" + egv1alpha1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/go-logr/logr" "github.com/google/go-cmp/cmp" "github.com/kuadrant/policy-machinery/controller" "github.com/kuadrant/policy-machinery/machinery" + istioclientgoextensionv1alpha1 "istio.io/client-go/pkg/apis/extensions/v1alpha1" + istioclientnetworkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" + istioclientgosecurityv1beta1 "istio.io/client-go/pkg/apis/security/v1beta1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -20,6 +25,9 @@ import ( kuadrantv1alpha1 "github.com/kuadrant/kuadrant-operator/api/v1alpha1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" kuadrantv1beta2 "github.com/kuadrant/kuadrant-operator/api/v1beta2" + "github.com/kuadrant/kuadrant-operator/pkg/envoygateway" + "github.com/kuadrant/kuadrant-operator/pkg/istio" + kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" ) @@ -36,9 +44,6 @@ func NewPolicyMachineryController(manager ctrlruntime.Manager, client *dynamic.D controller.WithLogger(logger), controller.WithClient(client), controller.WithRunnable("kuadrant watcher", controller.Watch(&kuadrantv1beta1.Kuadrant{}, kuadrantv1beta1.KuadrantResource, metav1.NamespaceAll)), - controller.WithRunnable("gatewayclass watcher", controller.Watch(&gwapiv1.GatewayClass{}, controller.GatewayClassesResource, metav1.NamespaceAll)), - controller.WithRunnable("gateway watcher", controller.Watch(&gwapiv1.Gateway{}, controller.GatewaysResource, metav1.NamespaceAll)), - controller.WithRunnable("httproute watcher", controller.Watch(&gwapiv1.HTTPRoute{}, controller.HTTPRoutesResource, metav1.NamespaceAll)), controller.WithRunnable("dnspolicy watcher", controller.Watch(&kuadrantv1alpha1.DNSPolicy{}, kuadrantv1alpha1.DNSPoliciesResource, metav1.NamespaceAll)), controller.WithRunnable("tlspolicy watcher", controller.Watch(&kuadrantv1alpha1.TLSPolicy{}, kuadrantv1alpha1.TLSPoliciesResource, metav1.NamespaceAll)), controller.WithRunnable("authpolicy watcher", controller.Watch(&kuadrantv1beta2.AuthPolicy{}, kuadrantv1beta2.AuthPoliciesResource, metav1.NamespaceAll)), @@ -59,6 +64,71 @@ func NewPolicyMachineryController(manager ctrlruntime.Manager, client *dynamic.D controller.WithReconcile(buildReconciler(client)), } + ok, err := kuadrantgatewayapi.IsGatewayAPIInstalled(manager.GetRESTMapper()) + if err != nil || !ok { + logger.Info("gateway api is not installed, skipping watches and reconcilers", "err", err) + } else { + controllerOpts = append(controllerOpts, + controller.WithRunnable("gatewayclass watcher", controller.Watch(&gwapiv1.GatewayClass{}, controller.GatewayClassesResource, metav1.NamespaceAll)), + controller.WithRunnable("gateway watcher", controller.Watch(&gwapiv1.Gateway{}, controller.GatewaysResource, metav1.NamespaceAll)), + controller.WithRunnable("httproute watcher", controller.Watch(&gwapiv1.HTTPRoute{}, controller.HTTPRoutesResource, metav1.NamespaceAll)), + ) + } + + ok, err = envoygateway.IsEnvoyGatewayInstalled(manager.GetRESTMapper()) + if err != nil || !ok { + logger.Info("envoygateway is not installed, skipping related watches and reconcilers", "err", err) + } else { + controllerOpts = append(controllerOpts, + controller.WithRunnable("envoypatchpolicy watcher", controller.Watch(&egv1alpha1.EnvoyPatchPolicy{}, envoygateway.EnvoyPatchPoliciesResource, metav1.NamespaceAll)), + controller.WithRunnable("envoyextensionpolicy watcher", controller.Watch(&egv1alpha1.EnvoyExtensionPolicy{}, envoygateway.EnvoyExtensionPoliciesResource, metav1.NamespaceAll)), + controller.WithRunnable("envoysecuritypolicy watcher", controller.Watch(&egv1alpha1.SecurityPolicy{}, envoygateway.SecurityPoliciesResource, metav1.NamespaceAll)), + controller.WithObjectKinds( + envoygateway.EnvoyPatchPolicyGroupKind, + envoygateway.EnvoyExtensionPolicyGroupKind, + envoygateway.SecurityPolicyGroupKind, + ), + // TODO: add object links + ) + // TODO: add specific tasks to workflow + } + + ok, err = istio.IsIstioInstalled(manager.GetRESTMapper()) + if err != nil || !ok { + logger.Info("istio is not installed, skipping related watches and reconcilers", "err", err) + } else { + controllerOpts = append(controllerOpts, + controller.WithRunnable("envoyfilter watcher", controller.Watch(&istioclientnetworkingv1alpha3.EnvoyFilter{}, istio.EnvoyFiltersResource, metav1.NamespaceAll)), + controller.WithRunnable("wasmplugin watcher", controller.Watch(&istioclientgoextensionv1alpha1.WasmPlugin{}, istio.WasmPluginsResource, metav1.NamespaceAll)), + controller.WithRunnable("authorizationpolicy watcher", controller.Watch(&istioclientgosecurityv1beta1.AuthorizationPolicy{}, istio.AuthorizationPoliciesResource, metav1.NamespaceAll)), + controller.WithObjectKinds( + istio.EnvoyFilterGroupKind, + istio.WasmPluginGroupKind, + istio.AuthorizationPolicyGroupKind, + ), + // TODO: add object links + ) + // TODO: add istio specific tasks to workflow + } + + ok, err = kuadrantgatewayapi.IsCertManagerInstalled(manager.GetRESTMapper(), logger) + if err != nil || !ok { + logger.Info("cert manager is not installed, skipping related watches and reconcilers", "err", err) + } else { + controllerOpts = append(controllerOpts, + controller.WithRunnable("certificate watcher", controller.Watch(&certmanagerv1.Certificate{}, CertManagerCertificatesResource, metav1.NamespaceAll)), + controller.WithRunnable("issuers watcher", controller.Watch(&certmanagerv1.Issuer{}, CertManagerIssuersResource, metav1.NamespaceAll)), + controller.WithRunnable("clusterissuers watcher", controller.Watch(&certmanagerv1.Certificate{}, CertMangerClusterIssuersResource, metav1.NamespaceAll)), + controller.WithObjectKinds( + CertManagerCertificateKind, + CertManagerIssuerKind, + CertManagerClusterIssuerKind, + ), + // TODO: add object links + ) + // TODO: add tls policy specific tasks to workflow + } + return controller.NewController(controllerOpts...) } diff --git a/controllers/test_common.go b/controllers/test_common.go index 0819b2067..41bab5e64 100644 --- a/controllers/test_common.go +++ b/controllers/test_common.go @@ -34,6 +34,7 @@ import ( istiosecurityv1beta1 "istio.io/client-go/pkg/apis/security/v1beta1" istioapis "istio.io/istio/operator/pkg/apis" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" istiov1alpha1 "maistra.io/istio-operator/api/v1alpha1" @@ -256,9 +257,14 @@ func SetupKuadrantOperatorForTest(s *runtime.Scheme, cfg *rest.Config) { Expect(err).NotTo(HaveOccurred()) + dClient, err := dynamic.NewForConfig(mgr.GetConfig()) + Expect(err).NotTo(HaveOccurred()) + + stateOfTheWorld := NewPolicyMachineryController(mgr, dClient, log.Log) + go func() { defer GinkgoRecover() - err = mgr.Start(ctrl.SetupSignalHandler()) + err = stateOfTheWorld.Start(ctrl.SetupSignalHandler()) Expect(err).ToNot(HaveOccurred()) }() } diff --git a/controllers/tlspolicy_controller.go b/controllers/tlspolicy_controller.go index 0c6a62076..90ba0bc7d 100644 --- a/controllers/tlspolicy_controller.go +++ b/controllers/tlspolicy_controller.go @@ -21,9 +21,11 @@ import ( "fmt" "reflect" + "github.com/cert-manager/cert-manager/pkg/apis/certmanager" certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime/schema" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" @@ -44,6 +46,16 @@ import ( const TLSPolicyFinalizer = "kuadrant.io/tls-policy" +var ( + CertManagerCertificatesResource = certmanagerv1.SchemeGroupVersion.WithResource("certificates") + CertManagerIssuersResource = certmanagerv1.SchemeGroupVersion.WithResource("issuers") + CertMangerClusterIssuersResource = certmanagerv1.SchemeGroupVersion.WithResource("clusterissuers") + + CertManagerCertificateKind = schema.GroupKind{Group: certmanager.GroupName, Kind: certmanagerv1.CertificateKind} + CertManagerIssuerKind = schema.GroupKind{Group: certmanager.GroupName, Kind: certmanagerv1.IssuerKind} + CertManagerClusterIssuerKind = schema.GroupKind{Group: certmanager.GroupName, Kind: certmanagerv1.ClusterIssuerKind} +) + // TLSPolicyReconciler reconciles a TLSPolicy object type TLSPolicyReconciler struct { *reconcilers.BaseReconciler diff --git a/make/integration-tests.mk b/make/integration-tests.mk index 0fe4db81e..c28050d12 100644 --- a/make/integration-tests.mk +++ b/make/integration-tests.mk @@ -9,7 +9,7 @@ INTEGRATION_TEST_NUM_PROCESSES ?= 10 test-bare-k8s-integration: clean-cov generate fmt vet ginkgo ## Requires only bare kubernetes cluster. mkdir -p $(PROJECT_PATH)/coverage/bare-k8s-integration # Check `ginkgo help run` for command line options. For example to filtering tests. - $(GINKGO) \ + OPERATOR_NAMESPACE=kuadrant-system $(GINKGO) \ --coverpkg $(INTEGRATION_COVER_PKGS) \ --output-dir $(PROJECT_PATH)/coverage/bare-k8s-integration \ --coverprofile cover.out \ @@ -27,7 +27,7 @@ test-bare-k8s-integration: clean-cov generate fmt vet ginkgo ## Requires only ba test-gatewayapi-env-integration: clean-cov generate fmt vet ginkgo ## Requires kubernetes cluster with GatewayAPI installed. mkdir -p $(PROJECT_PATH)/coverage/gatewayapi-integration # Check `ginkgo help run` for command line options. For example to filtering tests. - $(GINKGO) \ + OPERATOR_NAMESPACE=kuadrant-system $(GINKGO) \ --coverpkg $(INTEGRATION_COVER_PKGS) \ --output-dir $(PROJECT_PATH)/coverage/gatewayapi-integration \ --coverprofile cover.out \ @@ -45,7 +45,7 @@ test-gatewayapi-env-integration: clean-cov generate fmt vet ginkgo ## Requires k test-istio-env-integration: clean-cov generate fmt vet ginkgo ## Requires kubernetes cluster with GatewayAPI and Istio installed. mkdir -p $(PROJECT_PATH)/coverage/istio-integration # Check `ginkgo help run` for command line options. For example to filtering tests. - GATEWAYAPI_PROVIDER=istio $(GINKGO) \ + GATEWAYAPI_PROVIDER=istio OPERATOR_NAMESPACE=kuadrant-system $(GINKGO) \ --coverpkg $(INTEGRATION_COVER_PKGS) \ --output-dir $(PROJECT_PATH)/coverage/istio-integration \ --coverprofile cover.out \ @@ -62,7 +62,7 @@ test-istio-env-integration: clean-cov generate fmt vet ginkgo ## Requires kubern test-envoygateway-env-integration: clean-cov generate fmt vet ginkgo ## Requires kubernetes cluster with GatewayAPI and EnvoyGateway installed. mkdir -p $(PROJECT_PATH)/coverage/envoygateway-integration # Check `ginkgo help run` for command line options. For example to filtering tests. - GATEWAYAPI_PROVIDER=envoygateway $(GINKGO) \ + GATEWAYAPI_PROVIDER=envoygateway OPERATOR_NAMESPACE=kuadrant-system $(GINKGO) \ --coverpkg $(INTEGRATION_COVER_PKGS) \ --output-dir $(PROJECT_PATH)/coverage/envoygateway-integration \ --coverprofile cover.out \ @@ -80,7 +80,7 @@ test-envoygateway-env-integration: clean-cov generate fmt vet ginkgo ## Requires test-integration: clean-cov generate fmt vet ginkgo ## Requires kubernetes cluster with at least one GatewayAPI provider installed. mkdir -p $(PROJECT_PATH)/coverage/integration # Check `ginkgo help run` for command line options. For example to filtering tests. - GATEWAYAPI_PROVIDER=$(GATEWAYAPI_PROVIDER) $(GINKGO) \ + GATEWAYAPI_PROVIDER=$(GATEWAYAPI_PROVIDER) OPERATOR_NAMESPACE=kuadrant-system $(GINKGO) \ --coverpkg $(INTEGRATION_COVER_PKGS) \ --output-dir $(PROJECT_PATH)/coverage/integration \ --coverprofile cover.out \ diff --git a/pkg/envoygateway/utils.go b/pkg/envoygateway/utils.go index e06d5fec8..3fb068395 100644 --- a/pkg/envoygateway/utils.go +++ b/pkg/envoygateway/utils.go @@ -3,10 +3,21 @@ package envoygateway import ( egv1alpha1 "github.com/envoyproxy/gateway/api/v1alpha1" "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime/schema" kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" ) +var ( + EnvoyPatchPoliciesResource = egv1alpha1.SchemeBuilder.GroupVersion.WithResource("envoypatchpolicies") + EnvoyExtensionPoliciesResource = egv1alpha1.SchemeBuilder.GroupVersion.WithResource("envoyextensionpolicies") + SecurityPoliciesResource = egv1alpha1.SchemeBuilder.GroupVersion.WithResource("securitypolicies") + + EnvoyPatchPolicyGroupKind = schema.GroupKind{Group: egv1alpha1.GroupName, Kind: egv1alpha1.KindEnvoyPatchPolicy} + EnvoyExtensionPolicyGroupKind = schema.GroupKind{Group: egv1alpha1.GroupName, Kind: egv1alpha1.KindEnvoyExtensionPolicy} + SecurityPolicyGroupKind = schema.GroupKind{Group: egv1alpha1.GroupName, Kind: egv1alpha1.KindSecurityPolicy} +) + func IsEnvoyPatchPolicyInstalled(restMapper meta.RESTMapper) (bool, error) { return kuadrantgatewayapi.IsCRDInstalled( restMapper, diff --git a/pkg/istio/utils.go b/pkg/istio/utils.go index 277b6af98..38fdd7378 100644 --- a/pkg/istio/utils.go +++ b/pkg/istio/utils.go @@ -9,12 +9,23 @@ import ( istioclientnetworkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" istioclientgosecurityv1beta1 "istio.io/client-go/pkg/apis/security/v1beta1" "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/controller-runtime/pkg/client" gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" ) +var ( + EnvoyFiltersResource = istioclientnetworkingv1alpha3.SchemeGroupVersion.WithResource("envoyfilters") + WasmPluginsResource = istioclientgoextensionv1alpha1.SchemeGroupVersion.WithResource("wasmplugins") + AuthorizationPoliciesResource = istioclientgosecurityv1beta1.SchemeGroupVersion.WithResource("authorizationpolicies") + + EnvoyFilterGroupKind = schema.GroupKind{Group: istioclientnetworkingv1alpha3.GroupName, Kind: "EnvoyFilter"} + WasmPluginGroupKind = schema.GroupKind{Group: istioclientgoextensionv1alpha1.GroupName, Kind: "WasmPlugin"} + AuthorizationPolicyGroupKind = schema.GroupKind{Group: istioclientgosecurityv1beta1.GroupName, Kind: "AuthorizationPolicy"} +) + func WorkloadSelectorFromGateway(ctx context.Context, k8sClient client.Client, gateway *gatewayapiv1.Gateway) *istiocommon.WorkloadSelector { logger, _ := logr.FromContext(ctx) gatewayWorkloadSelector, err := kuadrantgatewayapi.GetGatewayWorkloadSelector(ctx, k8sClient, gateway)