Skip to content

Commit 62faf61

Browse files
authored
Merge pull request #229 from florkbr/add-nav-bundles
Add support for nav bundles to frontend config
2 parents fe43079 + e7bafcf commit 62faf61

12 files changed

+368
-5
lines changed

api/v1alpha1/frontend_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ type WidgetEntry struct {
9393
}
9494

9595
type NavigationSegment struct {
96-
SectionID string `json:"sectionId" yaml:"sectionId"`
96+
SegmentID string `json:"segmentId" yaml:"segmentId"`
9797
// Id of the bundle to which the segment should be injected
9898
BundleID string `json:"bundleId" yaml:"bundleId"`
9999
// A position of the segment within the bundle

api/v1alpha1/frontendenvironment_types.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,20 @@ import (
2424
"sigs.k8s.io/controller-runtime/pkg/client"
2525
)
2626

27+
// FrontendBundles defines the bundles specific to an environment that will be used to
28+
// construct navigation
29+
type FrontendBundles struct {
30+
ID string `json:"id" yaml:"id"`
31+
Title string `json:"title" yaml:"title"`
32+
}
33+
34+
// The frontend bundles but with the nav items filled with chrome nav items
35+
type FrontendBundlesGenerated struct {
36+
ID string `json:"id" yaml:"id"`
37+
Title string `json:"title" yaml:"title"`
38+
NavItems *[]ChromeNavItem `json:"navItems" yaml:"navItems"`
39+
}
40+
2741
type FrontendServiceCategoryGroup struct {
2842
ID string `json:"id" yaml:"id"`
2943
Title string `json:"title" yaml:"title"`
@@ -105,6 +119,8 @@ type FrontendEnvironmentSpec struct {
105119
HTTPHeaders map[string]string `json:"httpHeaders,omitempty"`
106120

107121
DefaultReplicas *int32 `json:"defaultReplicas,omitempty" yaml:"defaultReplicas,omitempty"`
122+
// For the ChromeUI to render navigation bundles
123+
Bundles *[]FrontendBundles `json:"bundles,omitempty" yaml:"bundles,omitempty"`
108124
}
109125

110126
type MonitoringConfig struct {

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 50 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/cloud.redhat.com_frontendenvironments.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,22 @@ spec:
6767
description: The name of the secret we will use to get the akamai
6868
credentials
6969
type: string
70+
bundles:
71+
description: For the ChromeUI to render navigation bundles
72+
items:
73+
description: |-
74+
FrontendBundles defines the bundles specific to an environment that will be used to
75+
construct navigation
76+
properties:
77+
id:
78+
type: string
79+
title:
80+
type: string
81+
required:
82+
- id
83+
- title
84+
type: object
85+
type: array
7086
defaultReplicas:
7187
format: int32
7288
type: integer

config/crd/bases/cloud.redhat.com_frontends.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,13 +376,13 @@ spec:
376376
0 is the first position
377377
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
378378
type: integer
379-
sectionId:
379+
segmentId:
380380
type: string
381381
required:
382382
- bundleId
383383
- navItems
384384
- position
385-
- sectionId
385+
- segmentId
386386
type: object
387387
type: array
388388
replicas:

controllers/reconcile.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,56 @@ func setupServiceTilesData(feList *crd.FrontendList, feEnvironment crd.FrontendE
988988
return categories, skippedTiles
989989
}
990990

991+
func getNavItemPath(feName string, bundleID string, segmentID string) string {
992+
return fmt.Sprintf("%s-%s-%s", feName, bundleID, segmentID)
993+
}
994+
995+
func setupBundlesData(feList *crd.FrontendList, feEnvironment crd.FrontendEnvironment) ([]crd.FrontendBundlesGenerated, []string) {
996+
bundles := []crd.FrontendBundlesGenerated{}
997+
if feEnvironment.Spec.Bundles == nil {
998+
// skip if we do not have bundles in fe environment
999+
return bundles, []string{}
1000+
}
1001+
1002+
skippedNavItemsMap := make(map[string][]string)
1003+
bundleNavSegmentMap := make(map[string][]crd.NavigationSegment)
1004+
for _, frontend := range feList.Items {
1005+
if frontend.Spec.FeoConfigEnabled && frontend.Spec.NavigationSegments != nil {
1006+
for _, navSegment := range frontend.Spec.NavigationSegments {
1007+
bundleNavSegmentMap[navSegment.BundleID] = append(bundleNavSegmentMap[navSegment.BundleID], *navSegment)
1008+
skippedNavItemsMap[navSegment.BundleID] = append(skippedNavItemsMap[navSegment.BundleID], getNavItemPath(frontend.Name, navSegment.BundleID, navSegment.SegmentID))
1009+
}
1010+
}
1011+
}
1012+
1013+
for _, bundle := range *feEnvironment.Spec.Bundles {
1014+
delete(skippedNavItemsMap, bundle.ID)
1015+
sort.Slice(bundleNavSegmentMap[bundle.ID], func(i, j int) bool {
1016+
if (bundleNavSegmentMap[bundle.ID])[i].Position == (bundleNavSegmentMap[bundle.ID])[j].Position {
1017+
return (bundleNavSegmentMap[bundle.ID])[i].SegmentID[0] < (bundleNavSegmentMap[bundle.ID])[j].SegmentID[0]
1018+
}
1019+
return (bundleNavSegmentMap[bundle.ID])[i].Position < (bundleNavSegmentMap[bundle.ID])[j].Position
1020+
})
1021+
navItems := []crd.ChromeNavItem{}
1022+
for _, navSegment := range bundleNavSegmentMap[bundle.ID] {
1023+
navItems = append(navItems, *navSegment.NavItems...)
1024+
}
1025+
newBundle := crd.FrontendBundlesGenerated{
1026+
ID: bundle.ID,
1027+
Title: bundle.Title,
1028+
NavItems: &navItems,
1029+
}
1030+
bundles = append(bundles, newBundle)
1031+
}
1032+
1033+
skippedNavItems := []string{}
1034+
for _, skipped := range skippedNavItemsMap {
1035+
skippedNavItems = append(skippedNavItems, skipped...)
1036+
}
1037+
1038+
return bundles, skippedNavItems
1039+
}
1040+
9911041
func (r *FrontendReconciliation) setupBundleData(_ *v1.ConfigMap, _ map[string]crd.Frontend) error {
9921042
bundleList := &crd.BundleList{}
9931043

@@ -1127,6 +1177,8 @@ func (r *FrontendReconciliation) populateConfigMap(cfgMap *v1.ConfigMap, cacheMa
11271177

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

1180+
bundles, skippedBundles := setupBundlesData(feList, *r.FrontendEnvironment)
1181+
11301182
fedModulesJSONData, err := json.Marshal(fedModules)
11311183
if err != nil {
11321184
return err
@@ -1149,10 +1201,19 @@ func (r *FrontendReconciliation) populateConfigMap(cfgMap *v1.ConfigMap, cacheMa
11491201
return err
11501202
}
11511203

1204+
bundlesJSONData, err := json.Marshal(bundles)
1205+
if err != nil {
1206+
return err
1207+
}
1208+
11521209
if len(skippedTiles) > 0 {
11531210
r.Log.Info("Unable to find service categories for tiles:", strings.Join(skippedTiles, ","))
11541211
}
11551212

1213+
if len(skippedBundles) > 0 {
1214+
r.Log.Info("Unable to find bundle for nav items:", "skippedBundles", strings.Join(skippedBundles, ","))
1215+
}
1216+
11561217
cfgMap.Data["fed-modules.json"] = string(fedModulesJSONData)
11571218
if len(searchIndex) > 0 {
11581219
cfgMap.Data["search-index.json"] = string(searchIndexJSONData)
@@ -1166,6 +1227,10 @@ func (r *FrontendReconciliation) populateConfigMap(cfgMap *v1.ConfigMap, cacheMa
11661227
cfgMap.Data["service-tiles.json"] = string(serviceCategoriesJSONData)
11671228
}
11681229

1230+
if len(bundles) > 0 {
1231+
cfgMap.Data["bundles.json"] = string(bundlesJSONData)
1232+
}
1233+
11691234
return nil
11701235
}
11711236

deploy.yml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,23 @@ objects:
270270
description: The name of the secret we will use to get the akamai
271271
credentials
272272
type: string
273+
bundles:
274+
description: For the ChromeUI to render navigation bundles
275+
items:
276+
description: 'FrontendBundles defines the bundles specific to
277+
an environment that will be used to
278+
279+
construct navigation'
280+
properties:
281+
id:
282+
type: string
283+
title:
284+
type: string
285+
required:
286+
- id
287+
- title
288+
type: object
289+
type: array
273290
defaultReplicas:
274291
format: int32
275292
type: integer
@@ -780,13 +797,13 @@ objects:
780797
there is enough space in case some segments should be injected
781798
between existing ones'
782799
type: integer
783-
sectionId:
800+
segmentId:
784801
type: string
785802
required:
786803
- bundleId
787804
- navItems
788805
- position
789-
- sectionId
806+
- segmentId
790807
type: object
791808
type: array
792809
replicas:

examples/feenvironment.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,10 @@ spec:
2222
groups:
2323
- id: iam
2424
title: IAM
25+
bundles:
26+
- id: rhel
27+
title: Red Hat Enterprise Linux
28+
- id: ansible
29+
title: Ansible
30+
- id: settings
31+
title: Settings

examples/landing.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,21 @@ spec:
7777
description: Some Iam thing
7878
icon: IAMIcon
7979
isExternal: false
80+
navigationSegments:
81+
- segmentId: inventory-partial
82+
bundleId: insights
83+
position: 100
84+
navItems:
85+
- id: landing
86+
title: Landing section
87+
href: /apps/landing
88+
- id: bar
89+
title: Some new link
90+
expandable: true
91+
routes:
92+
- id: foo
93+
title: Foo
94+
href: /nested/bar
95+
- id: baz
96+
title: Some new link
97+
href: /baz
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
apiVersion: v1
3+
kind: Namespace
4+
metadata:
5+
name: test-generate-bundles
6+
spec:
7+
finalizers:
8+
- kubernetes

0 commit comments

Comments
 (0)