Skip to content

Commit 8c6c9d5

Browse files
committed
feat(services): add networkPolicy service
1 parent 92577c4 commit 8c6c9d5

File tree

10 files changed

+230
-0
lines changed

10 files changed

+230
-0
lines changed

src/enums/schemasMap.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import services from './services'
33
export default {
44
[services.node]: 'k8sNode',
55
[services.namespace]: 'k8sNamespace',
6+
[services.networkPolicy]: 'k8sNetworkPolicy',
67
[services.pod]: 'k8sPod',
78
[services.deployment]: 'k8sDeployment',
89
[services.secret]: 'k8sSecret',

src/enums/serviceMap.ts

+2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ import Secret from '../services/secret'
1313
import Role from '../services/role'
1414
import Job from '../services/job'
1515
import CronJob from '../services/cronJob'
16+
import NetworkPolicy from '../services/networkPolicy'
1617

1718
export default {
1819
[services.node]: Node,
1920
[services.namespace]: Namespace,
21+
[services.networkPolicy]: NetworkPolicy,
2022
[services.pod]: Pod,
2123
[services.deployment]: Deployment,
2224
[services.secret]: Secret,

src/enums/services.ts

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export default {
44
ingress: 'ingress',
55
job: 'job',
66
namespace: 'namespace',
7+
networkPolicy: 'networkPolicy',
78
node: 'node',
89
persistentVolume: 'persistentVolume',
910
persistentVolumeClaim: 'persistentVolumeClaim',

src/services/namespace/schema.graphql

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ type k8sNamespace {
66
metadata: k8sMetadata
77
spec: k8sNamespaceSpec
88
status: k8sNamespaceStatus
9+
networkPolicy: [k8sNetworkPolicy] @hasInverse(field: namespace)
910
node: [k8sNode] @hasInverse(field: namespace)
1011
pod: [k8sPod] @hasInverse(field: namespace)
1112
deployment: [k8sDeployment] @hasInverse(field: namespace)

src/services/networkPolicy/data.ts

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import CloudGraph from '@cloudgraph/sdk'
2+
import { V1NetworkPolicy } from '@kubernetes/client-node'
3+
import { k8sClient } from '../../types'
4+
5+
const { logger } = CloudGraph
6+
7+
export default async ({
8+
config,
9+
}: { config: { client: k8sClient } }): Promise<V1NetworkPolicy[]> => {
10+
const { client, } = config
11+
12+
try {
13+
const response = await client.networking.listNetworkPolicyForAllNamespaces()
14+
const { body: { items = []} = {}} = response ?? {}
15+
logger.debug(`Found ${items.length} k8s network policies`)
16+
17+
return items
18+
} catch (e) {
19+
logger.debug(e)
20+
return []
21+
}
22+
}

src/services/networkPolicy/format.ts

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import cuid from 'cuid'
2+
import { V1NetworkPolicy, V1NetworkPolicyPeer, V1NetworkPolicyPort } from '@kubernetes/client-node'
3+
import { K8sNetworkPolicy } from '../../types/generated'
4+
import { convertObjToArrayWithId } from '../../util'
5+
import formatMetadata from '../../util/metadata'
6+
import { formatMatchedExpressionsAndFields } from '../pod/util'
7+
8+
const formatPort = (port: V1NetworkPolicyPort) => {
9+
return {
10+
id: cuid(),
11+
endPort: port?.endPort,
12+
port: String(port?.port ?? ''),
13+
protocol: port?.protocol
14+
}
15+
}
16+
17+
const formatPolicyPeer = (peer: V1NetworkPolicyPeer) => {
18+
return {
19+
id: cuid(),
20+
ipBlock: {
21+
cidr: peer?.ipBlock?.cidr,
22+
except: peer?.ipBlock?.except
23+
},
24+
namespaceSelector: {
25+
matchExpressions: formatMatchedExpressionsAndFields(peer?.namespaceSelector?.matchExpressions ?? []),
26+
matchLabels: convertObjToArrayWithId(peer?.namespaceSelector?.matchLabels ?? {})
27+
},
28+
podSelector: {
29+
matchExpressions: formatMatchedExpressionsAndFields(peer?.podSelector?.matchExpressions ?? []),
30+
matchLabels: convertObjToArrayWithId(peer?.podSelector?.matchLabels ?? {})
31+
}
32+
}
33+
}
34+
export default ({
35+
entity,
36+
context,
37+
}: {
38+
entity: V1NetworkPolicy
39+
context: string
40+
}): K8sNetworkPolicy => {
41+
const {
42+
apiVersion,
43+
kind,
44+
metadata,
45+
spec: {
46+
egress,
47+
ingress,
48+
podSelector,
49+
policyTypes
50+
} = {}
51+
} = entity
52+
53+
54+
const formattedMetadata = formatMetadata(metadata)
55+
const mappedEgress = egress?.map(({ ports, to })=> ({
56+
id: cuid(),
57+
ports: ports?.map(formatPort) ?? [],
58+
to: to?.map(formatPolicyPeer) ?? []
59+
})) ?? []
60+
61+
const mappedIngress = ingress?.map(({ ports, from })=> ({
62+
id: cuid(),
63+
ports: ports?.map(formatPort) ?? [],
64+
from: from?.map(formatPolicyPeer) ?? []
65+
})) ?? []
66+
67+
const formattedPodSelector = {
68+
matchExpressions: formatMatchedExpressionsAndFields(podSelector?.matchExpressions ?? []),
69+
matchLabels: convertObjToArrayWithId(podSelector?.matchLabels ?? {})
70+
}
71+
72+
return {
73+
id: formattedMetadata.id,
74+
apiVersion,
75+
kind,
76+
context,
77+
metadata: formattedMetadata.metadata,
78+
spec: {
79+
egress: mappedEgress,
80+
ingress: mappedIngress,
81+
podSelector: formattedPodSelector,
82+
policyTypes
83+
}
84+
}
85+
}

src/services/networkPolicy/index.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import getData from './data'
2+
import format from './format'
3+
import mutation from './mutation'
4+
5+
6+
export default class NetworkPolicy {
7+
format = format.bind(this)
8+
9+
getData = getData.bind(this)
10+
11+
mutation = mutation
12+
}
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default `mutation($input: [Addk8sNetworkPolicyInput!]!) {
2+
addk8sNetworkPolicy(input: $input, upsert: true) {
3+
numUids
4+
}
5+
}`;
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
type k8sNetworkPolicy {
2+
id: String! @id @search(by: [hash, regexp])
3+
context: String! @search(by: [hash, regexp])
4+
apiVersion: String @search(by: [hash, regexp])
5+
kind: String @search(by: [hash, regexp])
6+
metadata: k8sMetadata
7+
spec: k8sNetworkPolicySpec
8+
namespace: [k8sNamespace] @hasInverse(field: networkPolicy)
9+
}
10+
11+
type k8sNetworkPolicySpec {
12+
egress: [k8sNetworkPolicyEgress]
13+
ingress: [k8sNetworkPolicyIngress]
14+
podSelector: k8sDeploymentSelector
15+
policyTypes: [String] @search(by: [hash, regexp])
16+
}
17+
18+
type k8sDeploymentSelector {
19+
matchExpressions: [k8sDeploymentExpressions]
20+
matchLabels: [k8sKeyValueArray]
21+
}
22+
23+
type k8sNetworkPolicyEgress {
24+
id: String! @id @search(by: [hash, regexp])
25+
ports: [k8sNetworkPolicyPort]
26+
to: [k8sNetworkPolicyPeer]
27+
}
28+
29+
type k8sNetworkPolicyIngress {
30+
id: String! @id @search(by: [hash, regexp])
31+
ports: [k8sNetworkPolicyPort]
32+
from: [k8sNetworkPolicyPeer]
33+
}
34+
35+
type k8sNetworkPolicyPort {
36+
id: String! @id @search(by: [hash, regexp])
37+
endPort: Int @search
38+
port: String @search(by: [hash, regexp])
39+
protocol: String @search(by: [hash, regexp])
40+
}
41+
42+
type k8sNetworkPolicyPeer {
43+
id: String! @id @search(by: [hash, regexp])
44+
ipBlock: k8sNetworkPolicyPeerIpBlock
45+
namespaceSelector: k8sDeploymentSelector
46+
podSelector: k8sDeploymentSelector
47+
}
48+
49+
type k8sNetworkPolicyPeerIpBlock {
50+
cidr: String @search(by: [hash, regexp])
51+
except: [String] @search(by: [hash, regexp])
52+
}

src/types/generated.ts

+49
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ export type K8sNamespace = {
341341
metadata?: Maybe<K8sMetadata>;
342342
spec?: Maybe<K8sNamespaceSpec>;
343343
status?: Maybe<K8sNamespaceStatus>;
344+
networkPolicy?: Maybe<Array<Maybe<K8sNetworkPolicy>>>;
344345
node?: Maybe<Array<Maybe<K8sNode>>>;
345346
pod?: Maybe<Array<Maybe<K8sPod>>>;
346347
deployment?: Maybe<Array<Maybe<K8sDeployment>>>;
@@ -365,6 +366,54 @@ export type K8sNamespaceStatus = {
365366
conditions?: Maybe<Array<Maybe<K8sConditions>>>;
366367
};
367368

369+
export type K8sNetworkPolicy = {
370+
id: Scalars['String'];
371+
context: Scalars['String'];
372+
apiVersion?: Maybe<Scalars['String']>;
373+
kind?: Maybe<Scalars['String']>;
374+
metadata?: Maybe<K8sMetadata>;
375+
spec?: Maybe<K8sNetworkPolicySpec>;
376+
namespace?: Maybe<Array<Maybe<K8sNamespace>>>;
377+
};
378+
379+
export type K8sNetworkPolicyEgress = {
380+
id: Scalars['String'];
381+
ports?: Maybe<Array<Maybe<K8sNetworkPolicyPort>>>;
382+
to?: Maybe<Array<Maybe<K8sNetworkPolicyPeer>>>;
383+
};
384+
385+
export type K8sNetworkPolicyIngress = {
386+
id: Scalars['String'];
387+
ports?: Maybe<Array<Maybe<K8sNetworkPolicyPort>>>;
388+
from?: Maybe<Array<Maybe<K8sNetworkPolicyPeer>>>;
389+
};
390+
391+
export type K8sNetworkPolicyPeer = {
392+
id: Scalars['String'];
393+
ipBlock?: Maybe<K8sNetworkPolicyPeerIpBlock>;
394+
namespaceSelector?: Maybe<K8sDeploymentSelector>;
395+
podSelector?: Maybe<K8sDeploymentSelector>;
396+
};
397+
398+
export type K8sNetworkPolicyPeerIpBlock = {
399+
cidr?: Maybe<Scalars['String']>;
400+
except?: Maybe<Array<Maybe<Scalars['String']>>>;
401+
};
402+
403+
export type K8sNetworkPolicyPort = {
404+
id: Scalars['String'];
405+
endPort?: Maybe<Scalars['Int']>;
406+
port?: Maybe<Scalars['String']>;
407+
protocol?: Maybe<Scalars['String']>;
408+
};
409+
410+
export type K8sNetworkPolicySpec = {
411+
egress?: Maybe<Array<Maybe<K8sNetworkPolicyEgress>>>;
412+
ingress?: Maybe<Array<Maybe<K8sNetworkPolicyIngress>>>;
413+
podSelector?: Maybe<K8sDeploymentSelector>;
414+
policyTypes?: Maybe<Array<Maybe<Scalars['String']>>>;
415+
};
416+
368417
export type K8sNode = {
369418
id: Scalars['String'];
370419
context: Scalars['String'];

0 commit comments

Comments
 (0)