From 175523df892bbf8ac21df7c97e97c8749676ffbb Mon Sep 17 00:00:00 2001 From: Adam Drew Date: Tue, 29 Oct 2024 11:41:09 -0400 Subject: [PATCH 01/10] Allow multiple cache bust URLs --- api/v1alpha1/frontendenvironment_types.go | 2 +- controllers/reconcile.go | 43 ++++++++++++++--------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/api/v1alpha1/frontendenvironment_types.go b/api/v1alpha1/frontendenvironment_types.go index ed1e79e6..bbe1728d 100644 --- a/api/v1alpha1/frontendenvironment_types.go +++ b/api/v1alpha1/frontendenvironment_types.go @@ -86,7 +86,7 @@ type FrontendEnvironmentSpec struct { // Set Akamai Cache Bust Image AkamaiCacheBustImage string `json:"akamaiCacheBustImage,omitempty"` // Set Akamai Cache Bust URL that the files will hang off of - AkamaiCacheBustURL string `json:"akamaiCacheBustURL,omitempty"` + AkamaiCacheBustURLs []string `json:"akamaiCacheBustURLs,omitempty"` // The name of the secret we will use to get the akamai credentials AkamaiSecretName string `json:"akamaiSecretName,omitempty"` // List of namespaces that should receive a copy of the frontend configuration as a config map diff --git a/controllers/reconcile.go b/controllers/reconcile.go index 124a0a22..e21ed527 100644 --- a/controllers/reconcile.go +++ b/controllers/reconcile.go @@ -216,28 +216,37 @@ func makeAkamaiEdgercFileFromSecret(secret *v1.Secret) string { } func createCachePurgePathList(frontend *crd.Frontend, frontendEnvironment *crd.FrontendEnvironment) []string { - // Set purgeHost by ensuring the URL begins with https:// and has no trailing / - purgeHost := strings.TrimSuffix(fmt.Sprintf("https://%s", strings.TrimPrefix(frontendEnvironment.Spec.AkamaiCacheBustURL, "https://")), "/") + var purgePaths []string - // Initialize with a default path if AkamaiCacheBustPaths is nil - purgePaths := []string{fmt.Sprintf("%s/apps/%s/fed-mods.json", purgeHost, frontend.Name)} - - if frontend.Spec.AkamaiCacheBustPaths == nil { + if frontendEnvironment.Spec.AkamaiCacheBustURLs == nil { return purgePaths } - purgePaths = make([]string, 0, len(frontend.Spec.AkamaiCacheBustPaths)) - for _, path := range frontend.Spec.AkamaiCacheBustPaths { - // Check if path is a full URL (starts with "http://" or "https://") - if strings.HasPrefix(path, "http://") || strings.HasPrefix(path, "https://") { - // Add full URL path directly - purgePaths = append(purgePaths, path) - } else { - // Ensure each path has a leading slash but no double slashes - if !strings.HasPrefix(path, "/") { - path = "/" + path + for _, cacheBustURL := range frontendEnvironment.Spec.AkamaiCacheBustURLs { + + // Set purgeHost by ensuring the URL begins with https:// and has no trailing / + purgeHost := strings.TrimSuffix(fmt.Sprintf("https://%s", strings.TrimPrefix(cacheBustURL, "https://")), "/") + + // Initialize with a default path if AkamaiCacheBustPaths is nil + purgePaths = []string{fmt.Sprintf("%s/apps/%s/fed-mods.json", purgeHost, frontend.Name)} + + if frontend.Spec.AkamaiCacheBustPaths == nil { + continue + } + + purgePaths = make([]string, 0, len(frontend.Spec.AkamaiCacheBustPaths)) + for _, path := range frontend.Spec.AkamaiCacheBustPaths { + // Check if path is a full URL (starts with "http://" or "https://") + if strings.HasPrefix(path, "http://") || strings.HasPrefix(path, "https://") { + // Add full URL path directly + purgePaths = append(purgePaths, path) + } else { + // Ensure each path has a leading slash but no double slashes + if !strings.HasPrefix(path, "/") { + path = "/" + path + } + purgePaths = append(purgePaths, purgeHost+path) } - purgePaths = append(purgePaths, purgeHost+path) } } return purgePaths From d854e878d5fa6d435a4f18329a5463fd5e675282 Mon Sep 17 00:00:00 2001 From: Adam Drew Date: Wed, 30 Oct 2024 13:33:07 -0400 Subject: [PATCH 02/10] Pre-push stuff --- api/v1alpha1/zz_generated.deepcopy.go | 5 + ...cloud.redhat.com_frontendenvironments.yaml | 6 +- deploy.yml | 6 +- .../modules/ROOT/pages/api_reference.adoc | 161 ++++++++++++++++-- 4 files changed, 160 insertions(+), 18 deletions(-) diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 60014a8b..5cb4a4ef 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -473,6 +473,11 @@ func (in *FrontendEnvironmentSpec) DeepCopyInto(out *FrontendEnvironmentSpec) { *out = new(MonitoringConfig) **out = **in } + if in.AkamaiCacheBustURLs != nil { + in, out := &in.AkamaiCacheBustURLs, &out.AkamaiCacheBustURLs + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.TargetNamespaces != nil { in, out := &in.TargetNamespaces, &out.TargetNamespaces *out = make([]string, len(*in)) diff --git a/config/crd/bases/cloud.redhat.com_frontendenvironments.yaml b/config/crd/bases/cloud.redhat.com_frontendenvironments.yaml index 821c57a4..491d572f 100644 --- a/config/crd/bases/cloud.redhat.com_frontendenvironments.yaml +++ b/config/crd/bases/cloud.redhat.com_frontendenvironments.yaml @@ -52,10 +52,12 @@ spec: akamaiCacheBustImage: description: Set Akamai Cache Bust Image type: string - akamaiCacheBustURL: + akamaiCacheBustURLs: description: Set Akamai Cache Bust URL that the files will hang off of - type: string + items: + type: string + type: array akamaiSecretName: description: The name of the secret we will use to get the akamai credentials diff --git a/deploy.yml b/deploy.yml index 5dcaa2ed..406578fc 100644 --- a/deploy.yml +++ b/deploy.yml @@ -255,10 +255,12 @@ objects: akamaiCacheBustImage: description: Set Akamai Cache Bust Image type: string - akamaiCacheBustURL: + akamaiCacheBustURLs: description: Set Akamai Cache Bust URL that the files will hang off of - type: string + items: + type: string + type: array akamaiSecretName: description: The name of the secret we will use to get the akamai credentials diff --git a/docs/antora/modules/ROOT/pages/api_reference.adoc b/docs/antora/modules/ROOT/pages/api_reference.adoc index 2324ed75..1c10cf2c 100644 --- a/docs/antora/modules/ROOT/pages/api_reference.adoc +++ b/docs/antora/modules/ROOT/pages/api_reference.adoc @@ -117,15 +117,12 @@ BundleList contains a list of Bundle - +Deprecated: Use ChromeNavItem instead, has to be switched for the updated reconciliation, needs to exist to prevent breaking changes for the Fronted resources and legacy NavItems attribute .Appears In: **** -- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-bundlespec[$$BundleSpec$$] -- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-computedbundle[$$ComputedBundle$$] -- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-extranavitem[$$ExtraNavItem$$] - xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-frontendspec[$$FrontendSpec$$] **** @@ -209,10 +206,51 @@ BundleSpec defines the desired state of Bundle | *`appList`* __string array__ | | | | *`envName`* __string__ | | | | *`extraNavItems`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-extranavitem[$$ExtraNavItem$$] array__ | | | -| *`customNav`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-bundlenavitem[$$BundleNavItem$$] array__ | | | +| *`customNav`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-chromenavitem[$$ChromeNavItem$$] array__ | | | +|=== + + + + +[id="{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-chromenavitem"] +==== ChromeNavItem + + + + + + + +.Appears In: +**** +- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-bundlespec[$$BundleSpec$$] +- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-chromenavitem[$$ChromeNavItem$$] +- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-computedbundle[$$ComputedBundle$$] +- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-extranavitem[$$ExtraNavItem$$] +- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-navigationsegment[$$NavigationSegment$$] +**** + +[cols="20a,50a,15a,15a", options="header"] |=== +| Field | Description | Default | Validation +| *`isHidden`* __boolean__ | | | +| *`expandable`* __boolean__ | | | +| *`href`* __string__ | | | +| *`appId`* __string__ | | | +| *`isExternal`* __boolean__ | | | +| *`title`* __string__ | | | +| *`groupId`* __string__ | | | +| *`id`* __string__ | | | +| *`product`* __string__ | | | +| *`notifier`* __string__ | | | +| *`icon`* __string__ | | | +| *`isBeta`* __boolean__ | | | +| *`navItems`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-chromenavitem[$$ChromeNavItem$$] array__ | kubebuilder struggles validating recursive fields, it has to be helped a bit + | | Schemaless: {} + +| *`routes`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-chromenavitem[$$ChromeNavItem$$] array__ | | | Schemaless: {} + +| *`permissions`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-permission[$$Permission$$] array__ | | | +|=== @@ -260,7 +298,7 @@ EmbeddedRoutes allow deeply nested navs to have support for routes |=== | Field | Description | Default | Validation | *`name`* __string__ | | | -| *`navItem`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-bundlenavitem[$$BundleNavItem$$]__ | | | +| *`navItem`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-chromenavitem[$$ChromeNavItem$$]__ | | | |=== @@ -418,10 +456,11 @@ parts should be generated for the bundles. We want to do + do this in epehemeral environments but not in production + | | | *`enableAkamaiCacheBust`* __boolean__ | Enable Akamai Cache Bust + | | | *`akamaiCacheBustImage`* __string__ | Set Akamai Cache Bust Image + | | -| *`akamaiCacheBustURL`* __string__ | Set Akamai Cache Bust URL that the files will hang off of + | | +| *`akamaiCacheBustURLs`* __string array__ | Set Akamai Cache Bust URL that the files will hang off of + | | | *`akamaiSecretName`* __string__ | The name of the secret we will use to get the akamai credentials + | | | *`targetNamespaces`* __string array__ | List of namespaces that should receive a copy of the frontend configuration as a config map + By configurations we mean the fed-modules.json, navigation files, etc. + | | +| *`serviceCategories`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-frontendservicecategory[$$FrontendServiceCategory$$]__ | For the ChromeUI to render additional global components + | | |=== @@ -470,6 +509,77 @@ FrontendList contains a list of Frontend |=== +[id="{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-frontendservicecategory"] +==== FrontendServiceCategory + + + +FrontendServiceCategory defines the category to which service can inject ServiceTiles +Chroming UI will use this to render the service dropdown component + + + +.Appears In: +**** +- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-frontendenvironmentspec[$$FrontendEnvironmentSpec$$] +**** + +[cols="20a,50a,15a,15a", options="header"] +|=== +| Field | Description | Default | Validation +| *`id`* __string__ | | | +| *`title`* __string__ | | | +| *`groups`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-frontendservicecategorygroup[$$FrontendServiceCategoryGroup$$] array__ | | | +|=== + + + + +[id="{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-frontendservicecategorygroup"] +==== FrontendServiceCategoryGroup + + + + + + + +.Appears In: +**** +- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-frontendservicecategory[$$FrontendServiceCategory$$] +**** + +[cols="20a,50a,15a,15a", options="header"] +|=== +| Field | Description | Default | Validation +| *`id`* __string__ | | | +| *`title`* __string__ | | | +|=== + + +[id="{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-frontendservicecategorygroupgenerated"] +==== FrontendServiceCategoryGroupGenerated + + + + + + + +.Appears In: +**** +- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-frontendservicecategorygenerated[$$FrontendServiceCategoryGenerated$$] +**** + +[cols="20a,50a,15a,15a", options="header"] +|=== +| Field | Description | Default | Validation +| *`id`* __string__ | | | +| *`title`* __string__ | | | +| *`tiles`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-servicetile[$$ServiceTile$$]__ | | | +|=== + + [id="{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-frontendspec"] ==== FrontendSpec @@ -498,6 +608,7 @@ FrontendSpec defines the desired state of Frontend | *`serviceMonitor`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-servicemonitorconfig[$$ServiceMonitorConfig$$]__ | | | | *`module`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-fedmodule[$$FedModule$$]__ | | | | *`navItems`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-bundlenavitem[$$BundleNavItem$$] array__ | | | +| *`navigationSegments`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-navigationsegment[$$NavigationSegment$$] array__ | navigation segments for the frontend + | | | *`assetsPrefix`* __string__ | | | | *`akamaiCacheBustDisable`* __boolean__ | Akamai cache bust opt-out + | | | *`akamaiCacheBustPaths`* __string array__ | Files to cache bust + | | @@ -611,8 +722,8 @@ FrontendSpec defines the desired state of Frontend |=== -[id="{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-permission"] -==== Permission +[id="{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-navigationsegment"] +==== NavigationSegment @@ -622,19 +733,39 @@ FrontendSpec defines the desired state of Frontend .Appears In: **** -- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-route[$$Route$$] -- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-widgetconfig[$$WidgetConfig$$] +- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-frontendspec[$$FrontendSpec$$] **** [cols="20a,50a,15a,15a", options="header"] |=== | Field | Description | Default | Validation -| *`method`* __string__ | | | -| *`apps`* __string array__ | | | -| *`args`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#json-v1-apiextensions-k8s-io[$$JSON$$]__ | | | +| *`sectionId`* __string__ | | | +| *`bundleId`* __string__ | Id of the bundle to which the segment should be injected + | | +| *`position`* __integer__ | A position of the segment within the bundle + +0 is the first position + +The position "steps" should be at least 100 to make sure there is enough space in case some segments should be injected between existing ones + | | +| *`navItems`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-chromenavitem[$$ChromeNavItem$$]__ | | | |=== +[id="{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-permission"] +==== Permission + +_Underlying type:_ _xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-struct-method string -json-method- yaml-method- apps -string -json-apps-omitempty- yaml-apps-omitempty- args -k8s-io-apiextensions-apiserver-pkg-apis-apiextensions-v1-json -json-args-omitempty- yaml-args-omitempty-[$$struct{Method string "json:\"method\" yaml:\"method\""; Apps []string "json:\"apps,omitempty\" yaml:\"apps,omitempty\""; Args *k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON "json:\"args,omitempty\" yaml:\"args,omitempty\""}$$]_ + + + + + +.Appears In: +**** +- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-chromenavitem[$$ChromeNavItem$$] +- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-route[$$Route$$] +- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-widgetconfig[$$WidgetConfig$$] +**** + + + [id="{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-route"] ==== Route @@ -721,6 +852,7 @@ FrontendSpec defines the desired state of Frontend .Appears In: **** +- xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-frontendservicecategorygroupgenerated[$$FrontendServiceCategoryGroupGenerated$$] - xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-frontendspec[$$FrontendSpec$$] **** @@ -732,6 +864,7 @@ FrontendSpec defines the desired state of Frontend | *`id`* __string__ | | | | *`href`* __string__ | | | | *`title`* __string__ | | | +| *`description`* __string__ | | | | *`icon`* __string__ | | | | *`isExternal`* __boolean__ | | | |=== From 70267219d2f8442bc1c9d3bb0215fdc8c6598832 Mon Sep 17 00:00:00 2001 From: Adam Drew Date: Thu, 31 Oct 2024 08:49:15 -0400 Subject: [PATCH 03/10] Update test for new property --- tests/e2e/cachebust/03-update-resources.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/e2e/cachebust/03-update-resources.yaml b/tests/e2e/cachebust/03-update-resources.yaml index e2ac0d0a..b08f5025 100644 --- a/tests/e2e/cachebust/03-update-resources.yaml +++ b/tests/e2e/cachebust/03-update-resources.yaml @@ -10,7 +10,8 @@ spec: sso: https://sso.foo.redhat.com enableAkamaiCacheBust: true akamaiCacheBustImage: "quay.io/rh_ee_addrew/hi_true_bye:add_alias" - akamaiCacheBustURL: "console.doesntexist.redhat.com" + akamaiCacheBustURLs: + - "console.doesntexist.redhat.com" --- apiVersion: cloud.redhat.com/v1alpha1 kind: Frontend From d860bdfd509ec02ad755c33e3526c664519bc110 Mon Sep 17 00:00:00 2001 From: Adam Drew Date: Thu, 31 Oct 2024 08:56:04 -0400 Subject: [PATCH 04/10] Add new multiple URLs test. --- .../00-create-namespace.yaml | 21 ++ .../01-create-resources.yaml | 83 ++++++++ .../cachebust-multiple-urls/02-assert.yaml | 198 ++++++++++++++++++ tests/e2e/cachebust/01-create-resources.yaml | 3 +- 4 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 tests/e2e/cachebust-multiple-urls/00-create-namespace.yaml create mode 100644 tests/e2e/cachebust-multiple-urls/01-create-resources.yaml create mode 100644 tests/e2e/cachebust-multiple-urls/02-assert.yaml diff --git a/tests/e2e/cachebust-multiple-urls/00-create-namespace.yaml b/tests/e2e/cachebust-multiple-urls/00-create-namespace.yaml new file mode 100644 index 00000000..b2ce11ca --- /dev/null +++ b/tests/e2e/cachebust-multiple-urls/00-create-namespace.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: test-cachebust-multiple-urls +spec: + finalizers: + - kubernetes +--- +kind: Secret +apiVersion: v1 +metadata: + name: akamai + namespace: test-cachebust-multiple-urls +data: + access_token: "YWNjZXNzX3Rva2Vu" + client_secret: "Y2xpZW50X3NlY3JldA==" + client_token: "Y2xpZW50X3Rva2Vu" + host: "aG9zdA==" +type: Opaque + diff --git a/tests/e2e/cachebust-multiple-urls/01-create-resources.yaml b/tests/e2e/cachebust-multiple-urls/01-create-resources.yaml new file mode 100644 index 00000000..b641b187 --- /dev/null +++ b/tests/e2e/cachebust-multiple-urls/01-create-resources.yaml @@ -0,0 +1,83 @@ +--- +apiVersion: cloud.redhat.com/v1alpha1 +kind: FrontendEnvironment +metadata: + name: test-cachebust-multiple-urls-environment +spec: + generateNavJSON: false + ssl: false + hostname: foo.redhat.com + sso: https://sso.foo.redhat.com + enableAkamaiCacheBust: true + akamaiCacheBustImage: "quay.io/rh_ee_addrew/hi_true_bye:add_alias" + akamaiCacheBustURLs: + - "console.doesntexist.redhat.com" + - "us.console.doesntexist.redhat.com" +--- +apiVersion: cloud.redhat.com/v1alpha1 +kind: Frontend +metadata: + name: chrome-test-filelist + namespace: test-cachebust-multiple-urls +spec: + API: + versions: + - v1 + frontend: + paths: + - / + akamaiCacheBustPaths: + - /config/chrome/fed-modules.json + - apps/chrome/index.html + - https://app.company.com + deploymentRepo: https://github.com/RedHatInsights/insights-chrome + envName: test-cachebust-multiple-urls-environment + image: quay.io/cloudservices/insights-chrome-frontend:720317c + module: + config: + ssoUrl: 'https://' + manifestLocation: /apps/chrome/js/fed-mods.json + title: Chrome +--- +apiVersion: cloud.redhat.com/v1alpha1 +kind: Frontend +metadata: + name: chrome-test-defaults + namespace: test-cachebust-multiple-urls +spec: + API: + versions: + - v1 + frontend: + paths: + - /chrome/defaults + deploymentRepo: https://github.com/RedHatInsights/insights-chrome + envName: test-cachebust-multiple-urls-environment + image: quay.io/cloudservices/insights-chrome-frontend:720317c + module: + config: + ssoUrl: 'https://' + manifestLocation: /apps/chrome/js/fed-mods.json + title: Chrome +--- +apiVersion: cloud.redhat.com/v1alpha1 +kind: Frontend +metadata: + name: chrome-test-optout + namespace: test-cachebust-multiple-urls +spec: + akamaiCacheBustDisable: true + API: + versions: + - v1 + frontend: + paths: + - /chrome2 + deploymentRepo: https://github.com/RedHatInsights/insights-chrome + envName: test-cachebust-multiple-urls-environment + image: quay.io/cloudservices/insights-chrome-frontend:720317c + module: + config: + ssoUrl: 'https://' + manifestLocation: /apps/chrome/js/fed-mods.json + title: Chrome diff --git a/tests/e2e/cachebust-multiple-urls/02-assert.yaml b/tests/e2e/cachebust-multiple-urls/02-assert.yaml new file mode 100644 index 00000000..aeb7ea39 --- /dev/null +++ b/tests/e2e/cachebust-multiple-urls/02-assert.yaml @@ -0,0 +1,198 @@ +kind: Deployment +apiVersion: apps/v1 +metadata: + name: chrome-test-filelist-frontend + namespace: test-cachebust-multiple-urls + labels: + frontend: chrome-test-filelist + ownerReferences: + - apiVersion: cloud.redhat.com/v1alpha1 + kind: Frontend + name: chrome-test-filelist +spec: + selector: + matchLabels: + frontend: chrome-test-filelist + template: + metadata: + labels: + frontend: chrome-test-filelist + spec: + volumes: + - name: config + configMap: + name: test-cachebust-multiple-urls-environment + defaultMode: 420 + containers: + - name: fe-image + image: quay.io/cloudservices/insights-chrome-frontend:720317c + ports: + - name: web + containerPort: 80 + protocol: TCP + - name: metrics + containerPort: 9000 + protocol: TCP + resources: {} + volumeMounts: + - name: config + mountPath: /opt/app-root/src/build/stable/operator-generated + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: chrome-test-filelist-frontend-cachebust + namespace: test-cachebust-multiple-urls + labels: + frontend: chrome-test-filelist + ownerReferences: + - apiVersion: cloud.redhat.com/v1alpha1 + kind: Frontend + name: chrome-test-filelist +spec: + template: + metadata: + annotations: + frontend-image: quay.io/cloudservices/insights-chrome-frontend:720317c + spec: + volumes: + - name: akamai-edgerc + configMap: + name: akamai-edgerc + defaultMode: 420 + containers: + - name: akamai-cache-bust + image: quay.io/rh_ee_addrew/hi_true_bye:add_alias + command: + - /bin/bash + - '-c' + - 'sleep 120; /cli/.akamai-cli/src/cli-purge/bin/akamai-purge --edgerc /opt/app-root/edgerc delete https://console.doesntexist.redhat.com/config/chrome/fed-modules.json https://console.doesntexist.redhat.com/apps/chrome/index.html https://us.console.doesntexist.redhat.com/config/chrome/fed-modules.json https://us.console.doesntexist.redhat.com/apps/chrome/index.html https://app.company.com' + resources: {} + volumeMounts: + - name: akamai-edgerc + mountPath: /opt/app-root/edgerc + subPath: edgerc + restartPolicy: Never +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: chrome-test-defaults-frontend + namespace: test-cachebust-multiple-urls + labels: + frontend: chrome-test-defaults + ownerReferences: + - apiVersion: cloud.redhat.com/v1alpha1 + kind: Frontend + name: chrome-test-defaults +spec: + selector: + matchLabels: + frontend: chrome-test-defaults + template: + metadata: + labels: + frontend: chrome-test-defaults + spec: + volumes: + - name: config + configMap: + name: test-cachebust-multiple-urls-environment + defaultMode: 420 + containers: + - name: fe-image + image: quay.io/cloudservices/insights-chrome-frontend:720317c + ports: + - name: web + containerPort: 80 + protocol: TCP + - name: metrics + containerPort: 9000 + protocol: TCP + resources: {} + volumeMounts: + - name: config + mountPath: /opt/app-root/src/build/stable/operator-generated + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: chrome-test-defaults-frontend-cachebust + namespace: test-cachebust-multiple-urls + labels: + frontend: chrome-test-defaults + ownerReferences: + - apiVersion: cloud.redhat.com/v1alpha1 + kind: Frontend + name: chrome-test-defaults +spec: + template: + metadata: + annotations: + frontend-image: quay.io/cloudservices/insights-chrome-frontend:720317c + spec: + volumes: + - name: akamai-edgerc + configMap: + name: akamai-edgerc + defaultMode: 420 + containers: + - name: akamai-cache-bust + image: quay.io/rh_ee_addrew/hi_true_bye:add_alias + command: + - /bin/bash + - '-c' + - 'sleep 120; /cli/.akamai-cli/src/cli-purge/bin/akamai-purge --edgerc /opt/app-root/edgerc delete https://console.doesntexist.redhat.com/apps/chrome-test-defaults/fed-mods.json https://us.console.doesntexist.redhat.com/apps/chrome-test-defaults/fed-mods.json' + resources: {} + volumeMounts: + - name: akamai-edgerc + mountPath: /opt/app-root/edgerc + subPath: edgerc + restartPolicy: Never +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: chrome-test-optout-frontend + namespace: test-cachebust-multiple-urls + labels: + frontend: chrome-test-optout + ownerReferences: + - apiVersion: cloud.redhat.com/v1alpha1 + kind: Frontend + name: chrome-test-optout +spec: + replicas: 1 + selector: + matchLabels: + frontend: chrome-test-optout + template: + metadata: + labels: + frontend: chrome-test-optout + spec: + volumes: + - name: config + configMap: + name: test-cachebust-multiple-urls-environment + defaultMode: 420 + containers: + - name: fe-image + image: quay.io/cloudservices/insights-chrome-frontend:720317c + ports: + - name: web + containerPort: 80 + protocol: TCP + - name: metrics + containerPort: 9000 + protocol: TCP + resources: {} + volumeMounts: + - name: config + mountPath: /opt/app-root/src/build/stable/operator-generated diff --git a/tests/e2e/cachebust/01-create-resources.yaml b/tests/e2e/cachebust/01-create-resources.yaml index 58520b83..eccd3ef5 100644 --- a/tests/e2e/cachebust/01-create-resources.yaml +++ b/tests/e2e/cachebust/01-create-resources.yaml @@ -10,7 +10,8 @@ spec: sso: https://sso.foo.redhat.com enableAkamaiCacheBust: true akamaiCacheBustImage: "quay.io/rh_ee_addrew/hi_true_bye:add_alias" - akamaiCacheBustURL: "console.doesntexist.redhat.com" + akamaiCacheBustURLs: + - "console.doesntexist.redhat.com" --- apiVersion: cloud.redhat.com/v1alpha1 kind: Frontend From ea79c739da235d9a571ecf3a1414076cee4029d8 Mon Sep 17 00:00:00 2001 From: Adam Drew Date: Mon, 18 Nov 2024 09:36:09 -0500 Subject: [PATCH 05/10] Don't stomp over purgePaths when building path list --- controllers/reconcile.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/controllers/reconcile.go b/controllers/reconcile.go index fdf9ce28..9a9522ce 100644 --- a/controllers/reconcile.go +++ b/controllers/reconcile.go @@ -218,25 +218,23 @@ func makeAkamaiEdgercFileFromSecret(secret *v1.Secret) string { func createCachePurgePathList(frontend *crd.Frontend, frontendEnvironment *crd.FrontendEnvironment) []string { var purgePaths []string + // Return early if there are no AkamaiCacheBustURLs if frontendEnvironment.Spec.AkamaiCacheBustURLs == nil { return purgePaths } for _, cacheBustURL := range frontendEnvironment.Spec.AkamaiCacheBustURLs { - - // Set purgeHost by ensuring the URL begins with https:// and has no trailing / + // Ensure the URL begins with https:// and has no trailing / purgeHost := strings.TrimSuffix(fmt.Sprintf("https://%s", strings.TrimPrefix(cacheBustURL, "https://")), "/") - // Initialize with a default path if AkamaiCacheBustPaths is nil - purgePaths = []string{fmt.Sprintf("%s/apps/%s/fed-mods.json", purgeHost, frontend.Name)} - + // Add default path if AkamaiCacheBustPaths is nil if frontend.Spec.AkamaiCacheBustPaths == nil { + purgePaths = append(purgePaths, fmt.Sprintf("%s/apps/%s/fed-mods.json", purgeHost, frontend.Name)) continue } - purgePaths = make([]string, 0, len(frontend.Spec.AkamaiCacheBustPaths)) + // Append paths based on AkamaiCacheBustPaths for _, path := range frontend.Spec.AkamaiCacheBustPaths { - // Check if path is a full URL (starts with "http://" or "https://") if strings.HasPrefix(path, "http://") || strings.HasPrefix(path, "https://") { // Add full URL path directly purgePaths = append(purgePaths, path) @@ -249,6 +247,7 @@ func createCachePurgePathList(frontend *crd.Frontend, frontendEnvironment *crd.F } } } + return purgePaths } From e9dff379ac40e5ffd71f45c44168165d369e203b Mon Sep 17 00:00:00 2001 From: Adam Drew Date: Mon, 18 Nov 2024 11:11:31 -0500 Subject: [PATCH 06/10] Prevent duplicates --- controllers/reconcile.go | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/controllers/reconcile.go b/controllers/reconcile.go index 9a9522ce..a7df3e45 100644 --- a/controllers/reconcile.go +++ b/controllers/reconcile.go @@ -218,6 +218,16 @@ func makeAkamaiEdgercFileFromSecret(secret *v1.Secret) string { func createCachePurgePathList(frontend *crd.Frontend, frontendEnvironment *crd.FrontendEnvironment) []string { var purgePaths []string + // Helper function to check if a path is already in the list + contains := func(slice []string, item string) bool { + for _, existing := range slice { + if existing == item { + return true + } + } + return false + } + // Return early if there are no AkamaiCacheBustURLs if frontendEnvironment.Spec.AkamaiCacheBustURLs == nil { return purgePaths @@ -229,21 +239,31 @@ func createCachePurgePathList(frontend *crd.Frontend, frontendEnvironment *crd.F // Add default path if AkamaiCacheBustPaths is nil if frontend.Spec.AkamaiCacheBustPaths == nil { - purgePaths = append(purgePaths, fmt.Sprintf("%s/apps/%s/fed-mods.json", purgeHost, frontend.Name)) + defaultPath := fmt.Sprintf("%s/apps/%s/fed-mods.json", purgeHost, frontend.Name) + if !contains(purgePaths, defaultPath) { + purgePaths = append(purgePaths, defaultPath) + } continue } // Append paths based on AkamaiCacheBustPaths for _, path := range frontend.Spec.AkamaiCacheBustPaths { + var fullPath string + if strings.HasPrefix(path, "http://") || strings.HasPrefix(path, "https://") { // Add full URL path directly - purgePaths = append(purgePaths, path) + fullPath = path } else { // Ensure each path has a leading slash but no double slashes if !strings.HasPrefix(path, "/") { path = "/" + path } - purgePaths = append(purgePaths, purgeHost+path) + fullPath = purgeHost + path + } + + // Append the fullPath only if it doesn't already exist in purgePaths + if !contains(purgePaths, fullPath) { + purgePaths = append(purgePaths, fullPath) } } } From cc1642447f48e3977697c4caad7ee2faf960c23b Mon Sep 17 00:00:00 2001 From: Adam Drew Date: Mon, 18 Nov 2024 11:39:14 -0500 Subject: [PATCH 07/10] Fix the order in the test assert --- tests/e2e/cachebust-multiple-urls/02-assert.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/cachebust-multiple-urls/02-assert.yaml b/tests/e2e/cachebust-multiple-urls/02-assert.yaml index aeb7ea39..9b0fc179 100644 --- a/tests/e2e/cachebust-multiple-urls/02-assert.yaml +++ b/tests/e2e/cachebust-multiple-urls/02-assert.yaml @@ -69,7 +69,7 @@ spec: command: - /bin/bash - '-c' - - 'sleep 120; /cli/.akamai-cli/src/cli-purge/bin/akamai-purge --edgerc /opt/app-root/edgerc delete https://console.doesntexist.redhat.com/config/chrome/fed-modules.json https://console.doesntexist.redhat.com/apps/chrome/index.html https://us.console.doesntexist.redhat.com/config/chrome/fed-modules.json https://us.console.doesntexist.redhat.com/apps/chrome/index.html https://app.company.com' + - 'sleep 120; /cli/.akamai-cli/src/cli-purge/bin/akamai-purge --edgerc /opt/app-root/edgerc delete https://console.doesntexist.redhat.com/config/chrome/fed-modules.json https://console.doesntexist.redhat.com/apps/chrome/index.html https://app.company.com https://us.console.doesntexist.redhat.com/config/chrome/fed-modules.json https://us.console.doesntexist.redhat.com/apps/chrome/index.html ' resources: {} volumeMounts: - name: akamai-edgerc From f5eb86148860af310518927d6f70f74a27d45b3b Mon Sep 17 00:00:00 2001 From: Adam Drew Date: Mon, 18 Nov 2024 14:03:29 -0500 Subject: [PATCH 08/10] Adoc change --- docs/antora/modules/ROOT/pages/api_reference.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/antora/modules/ROOT/pages/api_reference.adoc b/docs/antora/modules/ROOT/pages/api_reference.adoc index 3720115d..a3f15e4d 100644 --- a/docs/antora/modules/ROOT/pages/api_reference.adoc +++ b/docs/antora/modules/ROOT/pages/api_reference.adoc @@ -618,6 +618,7 @@ FrontendSpec defines the desired state of Frontend | *`serviceTiles`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-servicetile[$$ServiceTile$$] array__ | Data for the all services dropdown + | | | *`widgetRegistry`* __xref:{anchor_prefix}-github-com-redhatinsights-frontend-operator-api-v1alpha1-widgetentry[$$WidgetEntry$$] array__ | Data for the available widgets for the resource + | | | *`replicas`* __integer__ | | | +| *`feoConfigEnabled`* __boolean__ | Injects configuration from application when enabled + | | |=== From e975608d5e69afe04827292894e759f89f976b77 Mon Sep 17 00:00:00 2001 From: Adam Drew Date: Wed, 20 Nov 2024 14:35:33 -0500 Subject: [PATCH 09/10] Test fixed --- tests/e2e/cachebust-multiple-urls/02-assert.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/cachebust-multiple-urls/02-assert.yaml b/tests/e2e/cachebust-multiple-urls/02-assert.yaml index 9b0fc179..d74c5d04 100644 --- a/tests/e2e/cachebust-multiple-urls/02-assert.yaml +++ b/tests/e2e/cachebust-multiple-urls/02-assert.yaml @@ -69,7 +69,7 @@ spec: command: - /bin/bash - '-c' - - 'sleep 120; /cli/.akamai-cli/src/cli-purge/bin/akamai-purge --edgerc /opt/app-root/edgerc delete https://console.doesntexist.redhat.com/config/chrome/fed-modules.json https://console.doesntexist.redhat.com/apps/chrome/index.html https://app.company.com https://us.console.doesntexist.redhat.com/config/chrome/fed-modules.json https://us.console.doesntexist.redhat.com/apps/chrome/index.html ' + - 'sleep 120; /cli/.akamai-cli/src/cli-purge/bin/akamai-purge --edgerc /opt/app-root/edgerc delete https://console.doesntexist.redhat.com/config/chrome/fed-modules.json https://console.doesntexist.redhat.com/apps/chrome/index.html https://app.company.com https://us.console.doesntexist.redhat.com/config/chrome/fed-modules.json https://us.console.doesntexist.redhat.com/apps/chrome/index.html' resources: {} volumeMounts: - name: akamai-edgerc From e966a51609076d8471d14e018c6612da428c3f9d Mon Sep 17 00:00:00 2001 From: Adam Drew Date: Fri, 22 Nov 2024 14:07:43 -0500 Subject: [PATCH 10/10] Preserve AkamaiCacheBustURL for back compat --- api/v1alpha1/frontendenvironment_types.go | 3 +++ .../bases/cloud.redhat.com_frontendenvironments.yaml | 5 +++++ controllers/reconcile.go | 12 +++++++++--- deploy.yml | 5 +++++ docs/antora/modules/ROOT/pages/api_reference.adoc | 2 ++ tests/e2e/cachebust/01-create-resources.yaml | 3 +-- 6 files changed, 25 insertions(+), 5 deletions(-) diff --git a/api/v1alpha1/frontendenvironment_types.go b/api/v1alpha1/frontendenvironment_types.go index a6080574..ba476c96 100644 --- a/api/v1alpha1/frontendenvironment_types.go +++ b/api/v1alpha1/frontendenvironment_types.go @@ -88,6 +88,9 @@ type FrontendEnvironmentSpec struct { EnableAkamaiCacheBust bool `json:"enableAkamaiCacheBust,omitempty"` // Set Akamai Cache Bust Image AkamaiCacheBustImage string `json:"akamaiCacheBustImage,omitempty"` + // Deprecated: Users should move to AkamaiCacheBustURLs + // Preserving for backwards compatibility + AkamaiCacheBustURL string `json:"akamaiCacheBustURL,omitempty"` // Set Akamai Cache Bust URL that the files will hang off of AkamaiCacheBustURLs []string `json:"akamaiCacheBustURLs,omitempty"` // The name of the secret we will use to get the akamai credentials diff --git a/config/crd/bases/cloud.redhat.com_frontendenvironments.yaml b/config/crd/bases/cloud.redhat.com_frontendenvironments.yaml index fda58459..cb70d4e2 100644 --- a/config/crd/bases/cloud.redhat.com_frontendenvironments.yaml +++ b/config/crd/bases/cloud.redhat.com_frontendenvironments.yaml @@ -52,6 +52,11 @@ spec: akamaiCacheBustImage: description: Set Akamai Cache Bust Image type: string + akamaiCacheBustURL: + description: |- + Deprecated: Users should move to AkamaiCacheBustURLs + Preserving for backwards compatibility + type: string akamaiCacheBustURLs: description: Set Akamai Cache Bust URL that the files will hang off of diff --git a/controllers/reconcile.go b/controllers/reconcile.go index a7df3e45..d4b800d6 100644 --- a/controllers/reconcile.go +++ b/controllers/reconcile.go @@ -228,12 +228,18 @@ func createCachePurgePathList(frontend *crd.Frontend, frontendEnvironment *crd.F return false } - // Return early if there are no AkamaiCacheBustURLs - if frontendEnvironment.Spec.AkamaiCacheBustURLs == nil { + cacheBustUrls := frontendEnvironment.Spec.AkamaiCacheBustURLs + + if frontendEnvironment.Spec.AkamaiCacheBustURL != "" { + cacheBustUrls = append(cacheBustUrls, frontendEnvironment.Spec.AkamaiCacheBustURL) + } + + // Return early if we have no cache bust URLs of any kind to process + if len(cacheBustUrls) == 0 { return purgePaths } - for _, cacheBustURL := range frontendEnvironment.Spec.AkamaiCacheBustURLs { + for _, cacheBustURL := range cacheBustUrls { // Ensure the URL begins with https:// and has no trailing / purgeHost := strings.TrimSuffix(fmt.Sprintf("https://%s", strings.TrimPrefix(cacheBustURL, "https://")), "/") diff --git a/deploy.yml b/deploy.yml index 92976216..478d3d39 100644 --- a/deploy.yml +++ b/deploy.yml @@ -255,6 +255,11 @@ objects: akamaiCacheBustImage: description: Set Akamai Cache Bust Image type: string + akamaiCacheBustURL: + description: 'Deprecated: Users should move to AkamaiCacheBustURLs + + Preserving for backwards compatibility' + type: string akamaiCacheBustURLs: description: Set Akamai Cache Bust URL that the files will hang off of diff --git a/docs/antora/modules/ROOT/pages/api_reference.adoc b/docs/antora/modules/ROOT/pages/api_reference.adoc index a3f15e4d..1145558c 100644 --- a/docs/antora/modules/ROOT/pages/api_reference.adoc +++ b/docs/antora/modules/ROOT/pages/api_reference.adoc @@ -458,6 +458,8 @@ parts should be generated for the bundles. We want to do + do this in epehemeral environments but not in production + | | | *`enableAkamaiCacheBust`* __boolean__ | Enable Akamai Cache Bust + | | | *`akamaiCacheBustImage`* __string__ | Set Akamai Cache Bust Image + | | +| *`akamaiCacheBustURL`* __string__ | Deprecated: Users should move to AkamaiCacheBustURLs + +Preserving for backwards compatibility + | | | *`akamaiCacheBustURLs`* __string array__ | Set Akamai Cache Bust URL that the files will hang off of + | | | *`akamaiSecretName`* __string__ | The name of the secret we will use to get the akamai credentials + | | | *`targetNamespaces`* __string array__ | List of namespaces that should receive a copy of the frontend configuration as a config map + diff --git a/tests/e2e/cachebust/01-create-resources.yaml b/tests/e2e/cachebust/01-create-resources.yaml index eccd3ef5..58520b83 100644 --- a/tests/e2e/cachebust/01-create-resources.yaml +++ b/tests/e2e/cachebust/01-create-resources.yaml @@ -10,8 +10,7 @@ spec: sso: https://sso.foo.redhat.com enableAkamaiCacheBust: true akamaiCacheBustImage: "quay.io/rh_ee_addrew/hi_true_bye:add_alias" - akamaiCacheBustURLs: - - "console.doesntexist.redhat.com" + akamaiCacheBustURL: "console.doesntexist.redhat.com" --- apiVersion: cloud.redhat.com/v1alpha1 kind: Frontend