From 69f27c1e4657bdf4be19acb1f0e7f7b9cbd881d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Thu, 16 May 2024 15:43:43 +0200 Subject: [PATCH 1/2] feat(operator): support test pull secret MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Mészáros --- internal/common/constants.go | 1 + internal/controller/insights.go | 11 ++++++++++- internal/controller/insights_controller.go | 10 +++++++--- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/internal/common/constants.go b/internal/common/constants.go index 1c0f485..9e8e678 100644 --- a/internal/common/constants.go +++ b/internal/common/constants.go @@ -23,6 +23,7 @@ const ( EnvInsightsBackendDomain = "INSIGHTS_BACKEND_DOMAIN" EnvInsightsProxyDomain = "INSIGHTS_PROXY_DOMAIN" EnvInsightsEnabled = "INSIGHTS_ENABLED" + EnvTestPullSecretName = "INSIGHTS_TEST_PULL_SECRET_NAME" // Environment variable to override the Insights proxy image EnvInsightsProxyImageTag = "RELATED_IMAGE_INSIGHTS_PROXY" ) diff --git a/internal/controller/insights.go b/internal/controller/insights.go index 3551094..f72aa14 100644 --- a/internal/controller/insights.go +++ b/internal/controller/insights.go @@ -120,7 +120,16 @@ func (r *InsightsReconciler) reconcileProxyService(ctx context.Context) error { func (r *InsightsReconciler) getTokenFromPullSecret(ctx context.Context) (*string, error) { // Get the global pull secret pullSecret := &corev1.Secret{} - err := r.Client.Get(ctx, types.NamespacedName{Namespace: "openshift-config", Name: "pull-secret"}, pullSecret) + + var pullSecretName = "pull-secret" + var pullSecretNamespace = "openshift-config" + + if len(r.testPullSecretName) > 0 { + pullSecretName = r.testPullSecretName + pullSecretNamespace = r.Namespace + } + + err := r.Client.Get(ctx, types.NamespacedName{Namespace: pullSecretNamespace, Name: pullSecretName}, pullSecret) if err != nil { return nil, err } diff --git a/internal/controller/insights_controller.go b/internal/controller/insights_controller.go index bba3c1f..b6501df 100644 --- a/internal/controller/insights_controller.go +++ b/internal/controller/insights_controller.go @@ -35,9 +35,10 @@ import ( // InsightsReconciler reconciles the Insights proxy for Cryostat agents type InsightsReconciler struct { *InsightsReconcilerConfig - backendDomain string - proxyDomain string - proxyImageTag string + backendDomain string + proxyDomain string + proxyImageTag string + testPullSecretName string } // InsightsReconcilerConfig contains configuration to create an InsightsReconciler @@ -61,12 +62,15 @@ func NewInsightsReconciler(config *InsightsReconcilerConfig) (*InsightsReconcile return nil, errors.New("no proxy image tag provided for Insights") } proxyDomain := config.GetEnv(common.EnvInsightsProxyDomain) + // the pull secret might be empty + testPullSecret := config.GetEnv(common.EnvTestPullSecretName) return &InsightsReconciler{ InsightsReconcilerConfig: config, backendDomain: backendDomain, proxyDomain: proxyDomain, proxyImageTag: imageTag, + testPullSecretName: testPullSecret, }, nil } From a0028205697d5b05cbeab9c08745c0ec00653745 Mon Sep 17 00:00:00 2001 From: Elliott Baron Date: Tue, 12 Nov 2024 15:07:38 -0500 Subject: [PATCH 2/2] Refactor and add tests --- cmd/main.go | 5 +- internal/common/constants.go | 2 + internal/controller/insights.go | 11 +-- internal/controller/insights_controller.go | 26 ++++-- .../controller/insights_controller_test.go | 28 +++++++ .../insights_controller_unit_test.go | 13 +++ internal/controller/test/resources.go | 80 +++++++++++++++++++ internal/controller/test/utils.go | 4 + 8 files changed, 150 insertions(+), 19 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 5d5f93c..d41bfae 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -23,6 +23,7 @@ import ( // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) // to ensure that exec-entrypoint and run can make use of them. + "github.com/RedHatInsights/runtimes-inventory-operator/internal/common" "github.com/RedHatInsights/runtimes-inventory-operator/pkg/insights" _ "k8s.io/client-go/plugin/pkg/client/auth" @@ -111,8 +112,8 @@ func main() { // in addition to any secret in the operator's namespace &corev1.Secret{}: { Namespaces: map[string]cache.Config{ - "openshift-config": { - FieldSelector: fields.OneTermEqualSelector("metadata.name", "pull-secret"), + common.PullSecretNamespace: { + FieldSelector: fields.OneTermEqualSelector("metadata.name", common.PullSecretName), }, operatorNamespace: {}, }, diff --git a/internal/common/constants.go b/internal/common/constants.go index 9e8e678..0284327 100644 --- a/internal/common/constants.go +++ b/internal/common/constants.go @@ -20,6 +20,8 @@ const ( ProxyServiceName = ProxyDeploymentName ProxyServicePort = 8080 ProxySecretName = "apicastconf" + PullSecretName = "pull-secret" + PullSecretNamespace = "openshift-config" EnvInsightsBackendDomain = "INSIGHTS_BACKEND_DOMAIN" EnvInsightsProxyDomain = "INSIGHTS_PROXY_DOMAIN" EnvInsightsEnabled = "INSIGHTS_ENABLED" diff --git a/internal/controller/insights.go b/internal/controller/insights.go index f72aa14..03c4926 100644 --- a/internal/controller/insights.go +++ b/internal/controller/insights.go @@ -120,16 +120,7 @@ func (r *InsightsReconciler) reconcileProxyService(ctx context.Context) error { func (r *InsightsReconciler) getTokenFromPullSecret(ctx context.Context) (*string, error) { // Get the global pull secret pullSecret := &corev1.Secret{} - - var pullSecretName = "pull-secret" - var pullSecretNamespace = "openshift-config" - - if len(r.testPullSecretName) > 0 { - pullSecretName = r.testPullSecretName - pullSecretNamespace = r.Namespace - } - - err := r.Client.Get(ctx, types.NamespacedName{Namespace: pullSecretNamespace, Name: pullSecretName}, pullSecret) + err := r.Client.Get(ctx, types.NamespacedName{Namespace: r.pullSecretObj.Namespace, Name: r.pullSecretObj.Name}, pullSecret) if err != nil { return nil, err } diff --git a/internal/controller/insights_controller.go b/internal/controller/insights_controller.go index b6501df..42c2e6c 100644 --- a/internal/controller/insights_controller.go +++ b/internal/controller/insights_controller.go @@ -35,10 +35,10 @@ import ( // InsightsReconciler reconciles the Insights proxy for Cryostat agents type InsightsReconciler struct { *InsightsReconcilerConfig - backendDomain string - proxyDomain string - proxyImageTag string - testPullSecretName string + backendDomain string + proxyDomain string + proxyImageTag string + pullSecretObj types.NamespacedName } // InsightsReconcilerConfig contains configuration to create an InsightsReconciler @@ -62,15 +62,27 @@ func NewInsightsReconciler(config *InsightsReconcilerConfig) (*InsightsReconcile return nil, errors.New("no proxy image tag provided for Insights") } proxyDomain := config.GetEnv(common.EnvInsightsProxyDomain) - // the pull secret might be empty + // Check if a substitute pull secret for testing has been provided testPullSecret := config.GetEnv(common.EnvTestPullSecretName) + var pullSecretObj types.NamespacedName + if len(testPullSecret) > 0 { + pullSecretObj = types.NamespacedName{ + Name: testPullSecret, + Namespace: config.Namespace, + } + } else { + pullSecretObj = types.NamespacedName{ + Name: common.PullSecretName, + Namespace: common.PullSecretNamespace, + } + } return &InsightsReconciler{ InsightsReconcilerConfig: config, backendDomain: backendDomain, proxyDomain: proxyDomain, proxyImageTag: imageTag, - testPullSecretName: testPullSecret, + pullSecretObj: pullSecretObj, }, nil } @@ -109,7 +121,7 @@ func (r *InsightsReconciler) SetupWithManager(mgr ctrl.Manager) error { } func (r *InsightsReconciler) isPullSecretOrProxyConfig(ctx context.Context, secret client.Object) []reconcile.Request { - if !(secret.GetNamespace() == "openshift-config" && secret.GetName() == "pull-secret") && + if !(secret.GetNamespace() == r.pullSecretObj.Namespace && secret.GetName() == r.pullSecretObj.Name) && !(secret.GetNamespace() == r.Namespace && secret.GetName() == common.ProxySecretName) { return nil } diff --git a/internal/controller/insights_controller_test.go b/internal/controller/insights_controller_test.go index 29342b4..d426052 100644 --- a/internal/controller/insights_controller_test.go +++ b/internal/controller/insights_controller_test.go @@ -179,6 +179,34 @@ var _ = Describe("InsightsController", func() { }, actual) Expect(err).ToNot(HaveOccurred()) + Expect(actual.Labels).To(Equal(expected.Labels)) + Expect(actual.Annotations).To(Equal(expected.Annotations)) + Expect(metav1.IsControlledBy(actual, t.getProxyConfigMap())).To(BeTrue()) + Expect(actual.Data).To(HaveLen(1)) + Expect(actual.Data).To(HaveKey("config.json")) + Expect(actual.Data["config.json"]).To(MatchJSON(expected.StringData["config.json"])) + }) + }) + Context("with a test pull secret", func() { + BeforeEach(func() { + pullSecret := t.NewTestPullSecret() + t.EnvTestPullSecret = &pullSecret.Name + t.objs = append(t.objs, pullSecret) + }) + JustBeforeEach(func() { + result, err := t.reconcile() + Expect(err).ToNot(HaveOccurred()) + Expect(result).To(Equal(reconcile.Result{})) + }) + It("should create the APICast config secret", func() { + expected := t.NewInsightsProxySecretWithTestPullSecret() + actual := &corev1.Secret{} + err := t.client.Get(context.Background(), types.NamespacedName{ + Name: expected.Name, + Namespace: expected.Namespace, + }, actual) + Expect(err).ToNot(HaveOccurred()) + Expect(actual.Labels).To(Equal(expected.Labels)) Expect(actual.Annotations).To(Equal(expected.Annotations)) Expect(metav1.IsControlledBy(actual, t.getProxyConfigMap())).To(BeTrue()) diff --git a/internal/controller/insights_controller_unit_test.go b/internal/controller/insights_controller_unit_test.go index 227af08..c27bdbc 100644 --- a/internal/controller/insights_controller_unit_test.go +++ b/internal/controller/insights_controller_unit_test.go @@ -102,6 +102,19 @@ var _ = Describe("InsightsController", func() { result := t.controller.isPullSecretOrProxyConfig(context.Background(), secret) Expect(result).To(BeEmpty()) }) + Context("with a test pull secret", func() { + BeforeEach(func() { + t.EnvTestPullSecret = &t.NewTestPullSecret().Name + }) + It("should reconcile test pull secret", func() { + result := t.controller.isPullSecretOrProxyConfig(context.Background(), t.NewTestPullSecret()) + Expect(result).To(ConsistOf(t.deploymentReconcileRequest())) + }) + It("should not reconcile global pull secret", func() { + result := t.controller.isPullSecretOrProxyConfig(context.Background(), t.NewGlobalPullSecret()) + Expect(result).To(BeEmpty()) + }) + }) }) Context("for deployments", func() { diff --git a/internal/controller/test/resources.go b/internal/controller/test/resources.go index 960a179..0211ae3 100644 --- a/internal/controller/test/resources.go +++ b/internal/controller/test/resources.go @@ -233,6 +233,73 @@ func (r *InsightsTestResources) NewInsightsProxySecretWithProxyDomain() *corev1. } } +func (r *InsightsTestResources) NewInsightsProxySecretWithTestPullSecret() *corev1.Secret { + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "apicastconf", + Namespace: r.Namespace, + }, + StringData: map[string]string{ + "config.json": fmt.Sprintf(`{ + "services": [ + { + "id": "1", + "backend_version": "1", + "proxy": { + "hosts": ["insights-proxy","insights-proxy.%s.svc.cluster.local"], + "api_backend": "https://insights.example.com:443/", + "backend": { "endpoint": "http://127.0.0.1:8081", "host": "backend" }, + "policy_chain": [ + { + "name": "default_credentials", + "version": "builtin", + "configuration": { + "auth_type": "user_key", + "user_key": "dummy_key" + } + }, + { + "name": "headers", + "version": "builtin", + "configuration": { + "request": [ + { + "op": "set", + "header": "Authorization", + "value_type": "plain", + "value": "Bearer test" + }, + { + "op": "set", + "header": "User-Agent", + "value_type": "plain", + "value": "%s cluster/abcde" + } + ] + } + }, + { + "name": "apicast.policy.apicast" + } + ], + "proxy_rules": [ + { + "http_method": "POST", + "pattern": "/", + "metric_system_name": "hits", + "delta": 1, + "parameters": [], + "querystring_parameters": {} + } + ] + } + } + ] + }`, r.Namespace, r.UserAgentPrefix), + }, + } +} + func (r *InsightsTestResources) NewInsightsProxyDeployment() *appsv1.Deployment { var resources *corev1.ResourceRequirements if r.Resources != nil { @@ -410,3 +477,16 @@ func (r *InsightsTestResources) NewClusterVersion() *configv1.ClusterVersion { }, } } + +func (r *InsightsTestResources) NewTestPullSecret() *corev1.Secret { + config := `{"auths":{"example.com":{"auth":"world"},"cloud.openshift.com":{"auth":"test"}}}` + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pull-secret", + Namespace: r.Namespace, + }, + Data: map[string][]byte{ + corev1.DockerConfigJsonKey: []byte(config), + }, + } +} diff --git a/internal/controller/test/utils.go b/internal/controller/test/utils.go index 85942b1..f589152 100644 --- a/internal/controller/test/utils.go +++ b/internal/controller/test/utils.go @@ -24,6 +24,7 @@ type TestUtilsConfig struct { EnvInsightsProxyImageTag *string EnvInsightsBackendDomain *string EnvInsightsProxyDomain *string + EnvTestPullSecret *string } type testOSUtils struct { @@ -44,6 +45,9 @@ func NewTestOSUtils(config *TestUtilsConfig) *testOSUtils { if config.EnvInsightsProxyDomain != nil { envs["INSIGHTS_PROXY_DOMAIN"] = *config.EnvInsightsProxyDomain } + if config.EnvTestPullSecret != nil { + envs["INSIGHTS_TEST_PULL_SECRET_NAME"] = *config.EnvTestPullSecret + } return &testOSUtils{envs: envs} }