Skip to content

Commit 7e8ae9e

Browse files
authored
Merge pull request #3685 from userAdityaa/gateway
frontend: BackendTrafficPolicy: Add Model, List, Details and Storybook
2 parents a0c5b1e + 64d88a2 commit 7e8ae9e

37 files changed

+1787
-0
lines changed

frontend/src/components/Sidebar/__snapshots__/Sidebar.InClusterSidebarClosed.stories.storyshot

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,29 @@
804804
/>
805805
</a>
806806
</li>
807+
<li
808+
class="css-1gktw5r"
809+
>
810+
<a
811+
class="MuiButtonBase-root MuiListItemButton-root MuiListItemButton-gutters MuiListItemButton-root MuiListItemButton-gutters css-1op30le-MuiButtonBase-root-MuiListItemButton-root"
812+
href="/"
813+
role="button"
814+
tabindex="0"
815+
>
816+
<div
817+
class="MuiListItemText-root css-tlelie-MuiListItemText-root"
818+
>
819+
<span
820+
class="MuiTypography-root MuiTypography-body1 MuiListItemText-primary css-nqgwvn-MuiTypography-root"
821+
>
822+
BackendTrafficPolicies
823+
</span>
824+
</div>
825+
<span
826+
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
827+
/>
828+
</a>
829+
</li>
807830
</ul>
808831
</div>
809832
</div>

frontend/src/components/Sidebar/__snapshots__/Sidebar.InClusterSidebarOpen.stories.storyshot

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,29 @@
853853
/>
854854
</a>
855855
</li>
856+
<li
857+
class="css-1gktw5r"
858+
>
859+
<a
860+
class="MuiButtonBase-root MuiListItemButton-root MuiListItemButton-gutters MuiListItemButton-root MuiListItemButton-gutters css-1op30le-MuiButtonBase-root-MuiListItemButton-root"
861+
href="/"
862+
role="button"
863+
tabindex="0"
864+
>
865+
<div
866+
class="MuiListItemText-root css-tlelie-MuiListItemText-root"
867+
>
868+
<span
869+
class="MuiTypography-root MuiTypography-body1 MuiListItemText-primary css-nqgwvn-MuiTypography-root"
870+
>
871+
BackendTrafficPolicies
872+
</span>
873+
</div>
874+
<span
875+
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
876+
/>
877+
</a>
878+
</li>
856879
</ul>
857880
</div>
858881
</div>

frontend/src/components/Sidebar/__snapshots__/Sidebar.SelectedItemWithSidebarOmitted.stories.storyshot

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,29 @@
853853
/>
854854
</a>
855855
</li>
856+
<li
857+
class="css-1gktw5r"
858+
>
859+
<a
860+
class="MuiButtonBase-root MuiListItemButton-root MuiListItemButton-gutters MuiListItemButton-root MuiListItemButton-gutters css-1op30le-MuiButtonBase-root-MuiListItemButton-root"
861+
href="/"
862+
role="button"
863+
tabindex="0"
864+
>
865+
<div
866+
class="MuiListItemText-root css-tlelie-MuiListItemText-root"
867+
>
868+
<span
869+
class="MuiTypography-root MuiTypography-body1 MuiListItemText-primary css-nqgwvn-MuiTypography-root"
870+
>
871+
BackendTrafficPolicies
872+
</span>
873+
</div>
874+
<span
875+
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
876+
/>
877+
</a>
878+
</li>
856879
</ul>
857880
</div>
858881
</div>

frontend/src/components/Sidebar/useSidebarItems.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,10 @@ export const useSidebarItems = (sidebarName: string = DefaultSidebars.IN_CLUSTER
247247
name: 'backendtlspolicies',
248248
label: t('glossary|BackendTLSPolicies'),
249249
},
250+
{
251+
name: 'backendtrafficpolicies',
252+
label: t('glossary|BackendTrafficPolicies'),
253+
},
250254
],
251255
},
252256
{
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2025 The Kubernetes Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { Meta, StoryFn } from '@storybook/react';
18+
import { http, HttpResponse } from 'msw';
19+
import { TestContext } from '../../test';
20+
import BackendTrafficPolicyDetails from './BackendTrafficPolicyDetails';
21+
import { DEFAULT_BACKEND_TRAFFIC_POLICY } from './storyHelper';
22+
23+
export default {
24+
title: 'BackendTrafficPolicy/DetailsView',
25+
component: BackendTrafficPolicyDetails,
26+
decorators: [
27+
Story => (
28+
<TestContext routerMap={{ name: 'example-traffic-policy', namespace: 'default' }}>
29+
<Story />
30+
</TestContext>
31+
),
32+
],
33+
parameters: {
34+
msw: {
35+
handlers: {
36+
story: [],
37+
storyBase: [
38+
http.get(
39+
'http://localhost:4466/apis/gateway.networking.x-k8s.io/v1alpha1/namespaces/default/xbackendtrafficpolicies/example-traffic-policy',
40+
() => HttpResponse.json(DEFAULT_BACKEND_TRAFFIC_POLICY)
41+
),
42+
http.get('http://localhost:4466/api/v1/namespaces/default/events', () =>
43+
HttpResponse.json({
44+
kind: 'EventList',
45+
items: [],
46+
metadata: {},
47+
})
48+
),
49+
http.post(
50+
'http://localhost:4466/apis/authorization.k8s.io/v1/selfsubjectaccessreviews',
51+
() =>
52+
HttpResponse.json({
53+
status: { allowed: true, reason: '', code: 200 },
54+
})
55+
),
56+
],
57+
},
58+
},
59+
},
60+
} as Meta;
61+
62+
const Template: StoryFn = () => {
63+
return <BackendTrafficPolicyDetails />;
64+
};
65+
66+
export const Basic = Template.bind({});
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Copyright 2025 The Kubernetes Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { useTranslation } from 'react-i18next';
18+
import { useParams } from 'react-router-dom';
19+
import BackendTrafficPolicy from '../../lib/k8s/backendTrafficPolicy';
20+
import EmptyContent from '../common/EmptyContent';
21+
import LabelListItem from '../common/LabelListItem';
22+
import { DetailsGrid } from '../common/Resource';
23+
import SectionBox from '../common/SectionBox';
24+
import { NameValueTable } from '../common/SimpleTable';
25+
26+
interface RetryConstraint {
27+
budget?: {
28+
percent?: number;
29+
interval?: string;
30+
};
31+
minRetryRate?: {
32+
count?: number;
33+
interval?: string;
34+
};
35+
}
36+
37+
function RetryConstraintTable(props: { retry: RetryConstraint }) {
38+
const { retry } = props;
39+
const { t } = useTranslation(['glossary', 'translation']);
40+
41+
const mainRows = [
42+
{
43+
name: t('translation|Retry Budget'),
44+
value: retry.budget
45+
? `${retry.budget.percent ?? 20}% over ${retry.budget.interval ?? '10s'}`
46+
: t('translation|Not specified'),
47+
},
48+
{
49+
name: t('translation|Min Retry Rate'),
50+
value: retry.minRetryRate
51+
? `${retry.minRetryRate.count ?? 10} reqs/${retry.minRetryRate.interval ?? '1s'}`
52+
: t('translation|Not specified'),
53+
},
54+
];
55+
56+
return <NameValueTable rows={mainRows} />;
57+
}
58+
59+
export default function BackendTrafficPolicyDetails(props: { name?: string; namespace?: string }) {
60+
const params = useParams<{ namespace: string; name: string }>();
61+
const { name = params.name, namespace = params.namespace } = props;
62+
const { t } = useTranslation(['glossary', 'translation']);
63+
64+
return (
65+
<DetailsGrid
66+
resourceType={BackendTrafficPolicy}
67+
name={name}
68+
namespace={namespace}
69+
withEvents
70+
extraSections={(item: BackendTrafficPolicy) =>
71+
item && [
72+
{
73+
id: 'backendtrafficpolicy.targets',
74+
section: (
75+
<SectionBox title={t('Targets')}>
76+
{item.targetRefs?.length > 0 ? (
77+
<LabelListItem
78+
labels={item.targetRefs.map(ref =>
79+
ref.sectionName
80+
? `${ref.kind} (${ref.name}:${ref.sectionName})`
81+
: `${ref.kind} (${ref.name})`
82+
)}
83+
/>
84+
) : (
85+
<EmptyContent>{t('No targets defined')}</EmptyContent>
86+
)}
87+
</SectionBox>
88+
),
89+
},
90+
{
91+
id: 'backendtrafficpolicy.retryconstraint',
92+
section: (
93+
<SectionBox title={t('Retry Constraint')}>
94+
{item.retryConstraint ? (
95+
<RetryConstraintTable retry={item.retryConstraint} />
96+
) : (
97+
<EmptyContent>{t('No retry constraint configured')}</EmptyContent>
98+
)}
99+
</SectionBox>
100+
),
101+
},
102+
{
103+
id: 'backendtrafficpolicy.sessionpersistence',
104+
section: (
105+
<SectionBox title={t('Session Persistence')}>
106+
{item.sessionPersistence ? (
107+
<LabelListItem
108+
labels={Object.entries(item.sessionPersistence).map(
109+
([key, value]) => `${key}: ${String(value)}`
110+
)}
111+
/>
112+
) : (
113+
<EmptyContent>{t('No session persistence configured')}</EmptyContent>
114+
)}
115+
</SectionBox>
116+
),
117+
},
118+
]
119+
}
120+
/>
121+
);
122+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2025 The Kubernetes Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { Meta, StoryFn } from '@storybook/react';
18+
import { http, HttpResponse } from 'msw';
19+
import { TestContext } from '../../test';
20+
import BackendTrafficPolicyList from './BackendTrafficPolicyList';
21+
import { DEFAULT_BACKEND_TRAFFIC_POLICY } from './storyHelper';
22+
23+
export default {
24+
title: 'BackendTrafficPolicy/ListView',
25+
component: BackendTrafficPolicyList,
26+
decorators: [
27+
Story => (
28+
<TestContext>
29+
<Story />
30+
</TestContext>
31+
),
32+
],
33+
parameters: {
34+
msw: {
35+
handlers: {
36+
storyBase: [],
37+
story: [
38+
http.get(
39+
'http://localhost:4466/apis/gateway.networking.x-k8s.io/v1alpha1/xbackendtrafficpolicies',
40+
() =>
41+
HttpResponse.json({
42+
kind: 'XBackendTrafficPolicyList',
43+
apiVersion: 'gateway.networking.x-k8s.io/v1alpha1',
44+
metadata: {},
45+
items: [DEFAULT_BACKEND_TRAFFIC_POLICY],
46+
})
47+
),
48+
],
49+
},
50+
},
51+
},
52+
} as Meta;
53+
54+
const Template: StoryFn = () => {
55+
return <BackendTrafficPolicyList />;
56+
};
57+
58+
export const Items = Template.bind({});

0 commit comments

Comments
 (0)