Skip to content

Commit

Permalink
d2-AI prompt:
Browse files Browse the repository at this point in the history
{
  "prompt": "开发 K8s 中 NetworkPolicy 资源的 UI,它在菜单中的名字为“Network Policies”,父级菜单是网络。\n在列表中,增加一列展示 ingress 和 egress rules 的总量,以及一列用于展示出 pod selector 规则。\n\r\n\r\n\r\n在详情区域,增加对 ingress 和 egress 的展示。\r\n\r\n在 ingress 详情中,每个 ingress 用一个 tab 展示。渲染每个 ingress 时,根据 ingress.from 中各条规则的类型分别渲染:\r\n- IP block 类型,展示 CIDR 和 exceptions 字段;\r\n- Namespace Selector 类型,展示 key、operator、value,并统计选中了多少个 namespace;\r\n- Pod selector 类型,展示 key、operator、value,并统计选中了多少个 pod。\r\n将 ingress.ports 展示出来,包含 port 和 protocol 信息。\r\n\r\n在 egress 详情中,每个 egress 用一个 tab 展示。渲染每个 egress 时,根据 egress.to 中各条规则的类型分别渲染:\r\n- IP block 类型,展示 CIDR 和 exceptions 字段;\r\n将 egress.ports 展示出来,包含 port 和 protocol 信息。\r\n\r\nnetwork policy spec 部分的数据示例如下:\r\n```yaml\r\nspec:\r\n  podSelector:\r\n    matchLabels:\r\n      role: db\r\n  ingress:\r\n    - ports:\r\n        - protocol: TCP\r\n          port: 6379\r\n      from:\r\n        - ipBlock:\r\n            cidr: 172.17.0.0/16\r\n            except:\r\n              - 172.17.1.0/24\r\n        - namespaceSelector:\r\n            matchLabels:\r\n              project: myproject\r\n        - podSelector:\r\n            matchLabels:\r\n              role: frontend\r\n  egress:\r\n    - ports:\r\n        - protocol: TCP\r\n          port: 5978\r\n      to:\r\n        - ipBlock:\r\n            cidr: 10.0.0.0/24\r\n  policyTypes:\r\n    - Ingress\r\n    - Egress\r\n```\n> \r\n> 在详情区域,增加对 ingress 和 egress 的展示。\r\n> \r\n> 在 ingress 详情中,每个 ingress 用一个 tab 展示。渲染每个 ingress 时,根据 ingress.from 中各条规则的类型分别渲染:\r\n> \r\n> * IP block 类型,展示 CIDR 和 exceptions 字段;\r\n> * Namespace Selector 类型,展示 key、operator、value,并统计选中了多少个 namespace;\r\n> * Pod selector 类型,展示 key、operator、value,并统计选中了多少个 pod。\r\n>   最后再将 ingress.ports 展示出来,包含 port 和 protocol 信息。\r\n> \r\n> 详情中 ingress.from 的数据示例如下:\r\n> \r\n> ```yaml\r\n> from:\r\n>   - ipBlock:\r\n>       cidr: 172.17.0.0/16\r\n>       except:\r\n>         - 172.17.1.0/24\r\n>   - namespaceSelector:\r\n>       matchLabels:\r\n>         project: myproject\r\n>   - podSelector:\r\n>       matchLabels:\r\n>         role: frontend\r\n> ```\r\n> \r\n> 在 egress 详情中,每个 egress 用一个 tab 展示。渲染每个 egress 时,根据 egress.to 中各条规则的类型分别渲染:\r\n> \r\n> * IP block 类型,展示 CIDR 和 exceptions 字段;\r\n>   将 egress.ports 展示出来,包含 port 和 protocol 信息。\r\n> \r\n> 详情中 egress.to 的数据示例如下:\r\n> \r\n> ```yaml\r\n>       to:\r\n>         - ipBlock:\r\n>             cidr: 10.0.0.0/24\r\n> ```\r\n\r\n这个是给 AI 的指令,还是关于PR的描述?",
  "images": [
    "https://github.com/webzard-io/dovetail-v2/assets/13651389/a4976e91-fd81-4560-8fc9-fa7695b25a92",
    "https://private-user-images.githubusercontent.com/13651389/290609115-a4976e91-fd81-4560-8fc9-fa7695b25a92.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTEiLCJleHAiOjE3MDI2MDgzODEsIm5iZiI6MTcwMjYwODA4MSwicGF0aCI6Ii8xMzY1MTM4OS8yOTA2MDkxMTUtYTQ5NzZlOTEtZmQ4MS00NTYwLThmYzktZmE3Njk1YjI1YTkyLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFJV05KWUFYNENTVkVINTNBJTJGMjAyMzEyMTUlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjMxMjE1VDAyNDEyMVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTE2ODQ1Y2Q0MDg0OTAwYzUwYTE1NTUxNzI1YzEzMDM3Njg1ZjI3ZGZkNDE5MmUwZjY5Mjc3OTVlNmRkMzI3MjYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.mft9n4H2B91YJQGrhcKaVA-QKv_LBcuJHnrwuSR1B2c"
  ]
}
  • Loading branch information
Yuyz0112 committed Dec 15, 2023
1 parent db50e60 commit d1d183b
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 0 deletions.
2 changes: 2 additions & 0 deletions packages/refine/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Route, Router } from 'react-router-dom';
import { Layout } from './components';
import { Dovetail } from './Dovetail';
import { ConfigMapConfig } from './pages/configmaps';
import { NetworkPolicyConfig } from './pages/networkpolicies';
import { CronJobForm, CronJobList, CronJobShow } from './pages/cronjobs';
import { DaemonSetForm, DaemonSetList, DaemonSetShow } from './pages/daemonsets';
import { DeploymentForm, DeploymentList, DeploymentShow } from './pages/deployments';
Expand Down Expand Up @@ -66,6 +67,7 @@ function App() {
ConfigMapConfig,
SecretsConfig,
ServicesConfig,
NetworkPolicyConfig,
];
}, []);

Expand Down
97 changes: 97 additions & 0 deletions packages/refine/src/components/ShowContent/fields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,100 @@ export const ServicePodsField = (_: i18n): ShowField<ResourceModel> => {
},
};
};
import { Tabs, List, Tag } from 'antd';
import {
NetworkPolicy,
NetworkPolicyEgressRule,
NetworkPolicyIngressRule,
NetworkPolicyPeer,
} from 'kubernetes-types/networking/v1';
import { get } from 'lodash';

const { TabPane } = Tabs;

const NetworkPolicyPeerList: React.FC<{
peers: NetworkPolicyPeer[];
peerType: 'ingress' | 'egress';
}> = ({ peers, peerType }) => {
return (
<List
dataSource={peers}
renderItem={(peer, index) => {
const ipBlock = get(peer, 'ipBlock');
const nsSelector = get(peer, 'namespaceSelector');
const podSelector = get(peer, 'podSelector');

return (
<List.Item key={index}>
{ipBlock && (
<React.Fragment>
<div>CIDR: {ipBlock.cidr}</div>
{ipBlock._except && <div>Exceptions: {ipBlock._except.join(', ')}</div>}
</React.Fragment>
)}
{nsSelector && (
<React.Fragment>
<div>Namespace Selector:</div>
{/* The count of selected namespaces based on the selector needs to be implement, currently placeholder text is used */}
<Tag>{`Selected namespaces: N`}</Tag>
</React.Fragment>
)}
{podSelector && (
<React.Fragment>
<div>Pod Selector:</div>
{/* The count of selected pods based on the selector needs to be implement, currently placeholder text is used */}
<Tag>{`Selected pods: N`}</Tag>
</React.Fragment>
)}
</List.Item>
);
}}
/>
);
};

const PortsList: React.FC<{ ports: any[] }> = ({ ports }) => {
return (
<List
dataSource={ports}
renderItem={(port, index) => (
<List.Item key={index}>
<div>Port: {port.port}</div>
<div>Protocol: {port.protocol ? port.protocol.toUpperCase() : 'TCP'}</div>
</List.Item>
)}
/>
);
};

export const IngressListField = (i18n: i18n): ShowField<ResourceModel> => ({
key: 'ingressList',
title: i18n.t('Ingress'),
path: ['rawYaml', 'spec', 'ingress'],
render: (ingressRules: NetworkPolicyIngressRule[]) => (
<Tabs defaultActiveKey="1">
{ingressRules.map((ingress, index) => (
<TabPane tab={`Ingress ${index + 1}`} key={index}>
<NetworkPolicyPeerList peers={ingress.from} peerType="ingress" />
{ingress.ports && <PortsList ports={ingress.ports} />}
</TabPane>
))}
</Tabs>
),
});

export const EgressListField = (i18n: i18n): ShowField<ResourceModel> => ({
key: 'egressList',
title: i18n.t('Egress'),
path: ['rawYaml', 'spec', 'egress'],
render: (egressRules: NetworkPolicyEgressRule[]) => (
<Tabs defaultActiveKey="1">
{egressRules.map((egress, index) => (
<TabPane tab={`Egress ${index + 1}`} key={index}>
<NetworkPolicyPeerList peers={egress.to} peerType="egress" />
{egress.ports && <PortsList ports={egress.ports} />}
</TabPane>
))}
</Tabs>
),
});
56 changes: 56 additions & 0 deletions packages/refine/src/hooks/useEagleTable/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -219,3 +219,59 @@ export const ServiceTypeColumnRenderer = <Model extends ResourceModel>(
sorter: CommonSorter(dataIndex),
};
};
import { NetworkPolicy } from 'kubernetes-types/networking/v1';

const RulesCount: React.FC<{ ingress?: any[]; egress?: any[] }> = ({
ingress,
egress,
}) => {
const ingressCount = ingress ? ingress.length : 0;
const egressCount = egress ? egress.length : 0;
return <span>{`Ingress: ${ingressCount}, Egress: ${egressCount}`}</span>;
};

export const RulesColumnRenderer = (i18n: i18n): Column<ResourceModel> => {
return {
key: 'rulesCount',
display: true,
dataIndex: ['rawYaml'],
title: i18n.t('rules_count'),
sortable: true,
sorter: (a, b) => {
const ingressA = get(a, ['rawYaml', 'spec', 'ingress'], []).length;
const egressA = get(a, ['rawYaml', 'spec', 'egress'], []).length;
const ingressB = get(b, ['rawYaml', 'spec', 'ingress'], []).length;
const egressB = get(b, ['rawYaml', 'spec', 'egress'], []).length;
return ingressA + egressA - (ingressB + egressB);
},
render: ({ spec }) => {
const ingress = get(spec, 'ingress', []);
const egress = get(spec, 'egress', []);
return <RulesCount ingress={ingress} egress={egress} />;
},
};
};

const PodSelector: React.FC<{ matchLabels?: { [key: string]: string } }> = ({
matchLabels,
}) => {
const labels = matchLabels
? Object.entries(matchLabels)
.map(([key, value]) => `${key}=${value}`)
.join(', ')
: 'None';
return <span>{labels}</span>;
};

export const PodSelectorColumnRenderer = (i18n: i18n): Column<ResourceModel> => {
return {
key: 'podSelector',
display: true,
dataIndex: ['rawYaml'],
title: i18n.t('pod_selector'),
render: ({ spec }) => {
const matchLabels = get(spec, 'podSelector.matchLabels', {});
return <PodSelector matchLabels={matchLabels} />;
},
};
};
35 changes: 35 additions & 0 deletions packages/refine/src/pages/networkpolicies/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { RulesColumnRenderer } from '../../hooks/useEagleTable/columns';
import { PodSelectorColumnRenderer } from '../../hooks/useEagleTable/columns';
import { IngressListField } from '../../components/ShowContent/fields';
import { EgressListField } from '../../components/ShowContent/fields';
import { i18n } from 'i18next';
import { RESOURCE_GROUP, ResourceConfig, WithId } from '../../types';
import { ResourceModel } from '../../model';
import { NetworkPolicy } from 'kubernetes-types/networking/v1';

const NETWORKPOLICY_INIT_VALUE = {
apiVersion: 'networking.k8s.io/v1',
kind: 'NetworkPolicy',
metadata: {
name: '',
namespace: 'default',
annotations: {},
labels: {},
},
spec: {
podSelector: {},
policyTypes: [],
},
};

export const NetworkPolicyConfig: ResourceConfig<WithId<NetworkPolicy>, ResourceModel> = {
name: 'networkpolicies',
kind: 'NetworkPolicy',
basePath: '/apis/networking.k8s.io/v1',
apiVersion: 'v1',
parent: RESOURCE_GROUP.NETWORK,
label: 'Network Policies',
columns: (i18n: i18n) => [RulesColumnRenderer(i18n), PodSelectorColumnRenderer(i18n)],
showFields: (i18n: i18n) => [[], [], [IngressListField(i18n), EgressListField(i18n)]],
initValue: NETWORKPOLICY_INIT_VALUE,
};

0 comments on commit d1d183b

Please sign in to comment.