Skip to content

Commit

Permalink
Add support for nav bundles to frontend config
Browse files Browse the repository at this point in the history
  • Loading branch information
florkbr committed Nov 20, 2024
1 parent 6d2c77e commit e6f6e33
Show file tree
Hide file tree
Showing 10 changed files with 339 additions and 0 deletions.
16 changes: 16 additions & 0 deletions api/v1alpha1/frontendenvironment_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,20 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
)

// FrontendBundles defines the bundles specific to an environment that will be used to
// construct navigation
type FrontendBundles struct {
ID string `json:"id" yaml:"id"`
Title string `json:"title" yaml:"title"`
}

// The frontend bundles but with the nav items filled with chrome nav items
type FrontendBundlesGenerated struct {
ID string `json:"id" yaml:"id"`
Title string `json:"title" yaml:"title"`
NavItems *[]ChromeNavItem `json:"navItems" yaml:"navItems"`
}

type FrontendServiceCategoryGroup struct {
ID string `json:"id" yaml:"id"`
Title string `json:"title" yaml:"title"`
Expand Down Expand Up @@ -97,6 +111,8 @@ type FrontendEnvironmentSpec struct {
TargetNamespaces []string `json:"targetNamespaces,omitempty" yaml:"targetNamespaces,omitempty"`
// For the ChromeUI to render additional global components
ServiceCategories *[]FrontendServiceCategory `json:"serviceCategories,omitempty" yaml:"serviceCategories,omitempty"`
// For the ChromeUI to render navigation bundles
Bundles *[]FrontendBundles `json:"bundles,omitempty" yaml:"bundles,omitempty"`
}

type MonitoringConfig struct {
Expand Down
50 changes: 50 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions config/crd/bases/cloud.redhat.com_frontendenvironments.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,22 @@ spec:
description: The name of the secret we will use to get the akamai
credentials
type: string
bundles:
description: For the ChromeUI to render navigation bundles
items:
description: |-
FrontendBundles defines the bundles specific to an environment that will be used to
construct navigation
properties:
id:
type: string
title:
type: string
required:
- id
- title
type: object
type: array
enableAkamaiCacheBust:
description: Enable Akamai Cache Bust
type: boolean
Expand Down
63 changes: 63 additions & 0 deletions controllers/reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,54 @@ func setupServiceTilesData(feList *crd.FrontendList, feEnvironment crd.FrontendE
return categories, skippedTiles
}

func getNavItemPath(feName string, bundleID string, sectionID string) string {
return fmt.Sprintf("%s-%s-%s", feName, bundleID, sectionID)
}

func setupBundlesData(feList *crd.FrontendList, feEnvironment crd.FrontendEnvironment) ([]crd.FrontendBundlesGenerated, []string) {
bundles := []crd.FrontendBundlesGenerated{}
if feEnvironment.Spec.Bundles == nil {
// skip if we do not have bundles in fe environment
return bundles, []string{}
}

skippedNavItemsMap := make(map[string][]string)
bundleNavSegmentMap := make(map[string][]crd.NavigationSegment)
for _, frontend := range feList.Items {
if frontend.Spec.FeoConfigEnabled && frontend.Spec.NavigationSegments != nil {
for _, navSegment := range frontend.Spec.NavigationSegments {
bundleNavSegmentMap[navSegment.BundleID] = append(bundleNavSegmentMap[navSegment.BundleID], *navSegment)
skippedNavItemsMap[navSegment.BundleID] = append(skippedNavItemsMap[navSegment.BundleID], getNavItemPath(frontend.Name, navSegment.BundleID, navSegment.SectionID))
}
}
}

for _, bundle := range *feEnvironment.Spec.Bundles {
delete(skippedNavItemsMap, bundle.ID)
// TODO sort alphabetically if position collision
sort.Slice(bundleNavSegmentMap[bundle.ID], func(i, j int) bool {
return (bundleNavSegmentMap[bundle.ID])[i].Position < (bundleNavSegmentMap[bundle.ID])[j].Position
})
navItems := []crd.ChromeNavItem{}
for _, navSegment := range bundleNavSegmentMap[bundle.ID] {
navItems = append(navItems, *navSegment.NavItems...)
}
newBundle := crd.FrontendBundlesGenerated{
ID: bundle.ID,
Title: bundle.Title,
NavItems: &navItems,
}
bundles = append(bundles, newBundle)
}

skippedNavItems := []string{}
for _, skipped := range skippedNavItemsMap {
skippedNavItems = append(skippedNavItems, skipped...)
}

return bundles, skippedNavItems
}

func (r *FrontendReconciliation) setupBundleData(_ *v1.ConfigMap, _ map[string]crd.Frontend) error {
bundleList := &crd.BundleList{}

Expand Down Expand Up @@ -1058,6 +1106,8 @@ func (r *FrontendReconciliation) populateConfigMap(cfgMap *v1.ConfigMap, cacheMa

serviceCategories, skippedTiles := setupServiceTilesData(feList, *r.FrontendEnvironment)

bundles, skippedBundles := setupBundlesData(feList, *r.FrontendEnvironment)

fedModulesJSONData, err := json.Marshal(fedModules)
if err != nil {
return err
Expand All @@ -1080,10 +1130,19 @@ func (r *FrontendReconciliation) populateConfigMap(cfgMap *v1.ConfigMap, cacheMa
return err
}

bundlesJSONData, err := json.Marshal(bundles)
if err != nil {
return err
}

if len(skippedTiles) > 0 {
r.Log.Info("Unable to find service categories for tiles:", strings.Join(skippedTiles, ","))
}

if len(skippedBundles) > 0 {
r.Log.Info("Unable to find bundle for nav items:", "skippedBundles", strings.Join(skippedBundles, ","))
}

cfgMap.Data["fed-modules.json"] = string(fedModulesJSONData)
if len(searchIndex) > 0 {
cfgMap.Data["search-index.json"] = string(searchIndexJSONData)
Expand All @@ -1097,6 +1156,10 @@ func (r *FrontendReconciliation) populateConfigMap(cfgMap *v1.ConfigMap, cacheMa
cfgMap.Data["service-tiles.json"] = string(serviceCategoriesJSONData)
}

if len(bundles) > 0 {
cfgMap.Data["bundles.json"] = string(bundlesJSONData)
}

return nil
}

Expand Down
17 changes: 17 additions & 0 deletions deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,23 @@ objects:
description: The name of the secret we will use to get the akamai
credentials
type: string
bundles:
description: For the ChromeUI to render navigation bundles
items:
description: 'FrontendBundles defines the bundles specific to
an environment that will be used to
construct navigation'
properties:
id:
type: string
title:
type: string
required:
- id
- title
type: object
type: array
enableAkamaiCacheBust:
description: Enable Akamai Cache Bust
type: boolean
Expand Down
7 changes: 7 additions & 0 deletions examples/feenvironment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,10 @@ spec:
groups:
- id: iam
title: IAM
bundles:
- id: rhel
title: Red Hat Enterprise Linux
- id: ansible
title: Ansible
- id: settings
title: Settings
18 changes: 18 additions & 0 deletions examples/landing.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,21 @@ spec:
description: Some Iam thing
icon: IAMIcon
isExternal: false
navigationSegments:
- sectionId: inventory-partial
bundleId: insights
position: 100
navItems:
- id: landing
title: Landing section
href: /apps/landing
- id: bar
title: Some new link
expandable: true
routes:
- id: foo
title: Foo
href: /nested/bar
- id: baz
title: Some new link
href: /baz
8 changes: 8 additions & 0 deletions tests/e2e/generate-bundles/00-create-namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: test-generate-bundles
spec:
finalizers:
- kubernetes
88 changes: 88 additions & 0 deletions tests/e2e/generate-bundles/01-create-resources.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
apiVersion: cloud.redhat.com/v1alpha1
kind: FrontendEnvironment
metadata:
name: test-generate-bundles-environment
spec:
generateNavJSON: false
ssl: false
hostname: foo.redhat.com
sso: https://sso.foo.redhat.com
bundles:
- id: rhel
title: Red Hat Enterprise Linux
- id: ansible
title: Ansible
- id: settings
title: Settings
---
apiVersion: cloud.redhat.com/v1alpha1
kind: Frontend
metadata:
name: landing-page
namespace: test-generate-bundles
spec:
envName: test-generate-bundles-environment
title: landing-page
deploymentRepo: https://github.com/RedHatInsights/landing-page-frontend
frontend:
paths:
- /apps/landing-page
image: "quay.io/cloudservices/landing-page-frontend:3244a17"
module:
manifestLocation: /apps/landing-page/fed-mods.json
modules: []
moduleID: landing-page
navigationSegments:
- sectionId: inventory-partial-2
bundleId: rhel
position: 200
navItems:
- id: landing2
title: Landing section
href: /apps/landing
- id: bar2
title: Some new link
expandable: true
routes:
- id: foo
title: Foo
href: /nested/bar
- id: baz2
title: Some new link
href: /baz
- sectionId: inventory-partial
bundleId: rhel
position: 100
navItems:
- id: landing
title: Landing section
href: /apps/landing
- id: bar
title: Some new link
expandable: true
routes:
- id: foo
title: Foo
href: /nested/bar
- id: baz
title: Some new link
href: /baz
- sectionId: skipped-partial
bundleId: skipped
position: 100
navItems:
- id: landing
title: Landing section
href: /apps/landing
- id: bar
title: Some new link
expandable: true
routes:
- id: foo
title: Foo
href: /nested/bar
- id: baz
title: Some new link
href: /baz
feoConfigEnabled: true
Loading

0 comments on commit e6f6e33

Please sign in to comment.