Skip to content

Commit 06bae2c

Browse files
committed
Use codegen to produce CRDs
I tried to keep the difference in descriptions of fields to the minimum. I advise to review the change to CRD file with (-w, ignore whitespace) option enabled. Signed-off-by: Ihar Hrachyshka <ihrachyshka@nvidia.com> Assisted-By: Claude Code; opus (claude-opus-4-5-20251101)
1 parent a6d2c54 commit 06bae2c

File tree

9 files changed

+1255
-913
lines changed

9 files changed

+1255
-913
lines changed

.github/workflows/build.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,27 @@ jobs:
5050
# with:
5151
# path-to-profile: coverage.out
5252

53+
verify-crd:
54+
name: Verify CRD is up-to-date
55+
runs-on: ubuntu-latest
56+
if: >
57+
(( github.event.pull_request.head.repo.owner.login != github.event.pull_request.base.repo.owner.login ) &&
58+
github.event_name == 'pull_request' ) || (github.event_name == 'push' && github.event.commits != '[]' )
59+
steps:
60+
- name: Set up Go 1.21
61+
uses: actions/setup-go@v5
62+
with:
63+
go-version: 1.21
64+
65+
- name: Check out code
66+
uses: actions/checkout@v4
67+
68+
- name: Verify CRD is up-to-date
69+
run: |
70+
./hack/update-crdgen.sh
71+
if ! git diff --quiet scheme.yml; then
72+
echo "ERROR: CRD scheme.yml is out of date. Please run './hack/update-crdgen.sh' and commit the changes."
73+
git diff scheme.yml
74+
exit 1
75+
fi
76+

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,26 @@ It provides new CRD for Network Policy, MultiNetworkPolicy, to prevent it from c
4040
(TBD)
4141

4242

43+
## Development
44+
45+
### Regenerating CRD Schema
46+
47+
The CRD schema (`scheme.yml`) is generated from Go type definitions in `pkg/apis/k8s.cni.cncf.io/`. To regenerate the CRD after modifying the types:
48+
49+
```bash
50+
./hack/update-crdgen.sh
51+
```
52+
53+
This script uses [controller-gen](https://book.kubebuilder.io/reference/controller-gen.html) to generate the CRD manifest from kubebuilder markers in the Go source files.
54+
55+
### Regenerating Go Code
56+
57+
To regenerate deepcopy functions and client code:
58+
59+
```bash
60+
./hack/update-codegen.sh
61+
```
62+
4363
## TODO
4464

4565
* Alternative packet processing other than iptables (e.g. xdp)

hack/update-crdgen.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/usr/bin/env bash
2+
3+
set -o errexit
4+
set -o nounset
5+
set -o pipefail
6+
7+
SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
8+
9+
# Determine GOBIN
10+
GOBIN="${GOBIN:-$(go env GOPATH)/bin}"
11+
12+
# Install controller-gen if not present
13+
if ! command -v controller-gen &> /dev/null && [ ! -f "${GOBIN}/controller-gen" ]; then
14+
echo "Installing controller-gen..."
15+
go install sigs.k8s.io/controller-tools/cmd/controller-gen@latest
16+
fi
17+
18+
# Use controller-gen from GOBIN if not in PATH
19+
CONTROLLER_GEN="${GOBIN}/controller-gen"
20+
if command -v controller-gen &> /dev/null; then
21+
CONTROLLER_GEN="controller-gen"
22+
fi
23+
24+
cd "${SCRIPT_ROOT}"
25+
26+
# Generate CRD manifests
27+
echo "Generating CRD manifests..."
28+
"${CONTROLLER_GEN}" crd \
29+
paths="./pkg/apis/k8s.cni.cncf.io/..." \
30+
output:crd:artifacts:config=.
31+
32+
# Rename the generated file to scheme.yml
33+
mv k8s.cni.cncf.io_multi-networkpolicies.yaml scheme.yml
34+
35+
echo "Done."
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// +k8s:deepcopy-gen=package,register
22
// +groupName=k8s.cni.cncf.io
33
// +groupGoName=K8sCniCncfIo
4+
// +kubebuilder:object:generate=true
45

6+
// Package v1beta1 contains API Schema definitions for the k8s.cni.cncf.io v1beta1 API group.
57
package v1beta1

pkg/apis/k8s.cni.cncf.io/v1beta1/types.go

Lines changed: 110 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,14 @@ import (
2626
// +genclient:noStatus
2727
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
2828
// +resourceName=multi-networkpolicies
29-
30-
// MultiNetworkPolicy ...
29+
// +kubebuilder:object:root=true
30+
// +kubebuilder:storageversion
31+
// +kubebuilder:resource:path=multi-networkpolicies,singular=multi-networkpolicy,shortName=multi-policy,scope=Namespaced
32+
33+
// MultiNetworkPolicy is a CRD schema to provide NetworkPolicy mechanism for
34+
// net-attach-def which is specified by the Network Plumbing Working Group.
35+
// MultiNetworkPolicy is identical to Kubernetes NetworkPolicy,
36+
// See: https://kubernetes.io/docs/concepts/services-networking/network-policies/ .
3137
type MultiNetworkPolicy struct {
3238
metav1.TypeMeta `json:",inline"`
3339
// Standard object's metadata.
@@ -39,8 +45,9 @@ type MultiNetworkPolicy struct {
3945
}
4046

4147
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
48+
// +kubebuilder:object:root=true
4249

43-
// MultiNetworkPolicyList ...
50+
// MultiNetworkPolicyList contains a list of MultiNetworkPolicy.
4451
type MultiNetworkPolicyList struct {
4552
metav1.TypeMeta `json:",inline"`
4653
// Standard object's metadata.
@@ -50,74 +57,165 @@ type MultiNetworkPolicyList struct {
5057
Items []MultiNetworkPolicy `json:"items"`
5158
}
5259

53-
// MultiPolicyType ...
60+
// Policy Type string describes the NetworkPolicy type This type is beta-level
61+
// in 1.8
62+
// +kubebuilder:validation:Enum=Ingress;Egress
5463
type MultiPolicyType string
5564

5665
const (
57-
// PolicyTypeIngress ...
66+
// PolicyTypeIngress is a NetworkPolicy that affects ingress traffic on selected pods.
5867
PolicyTypeIngress MultiPolicyType = "Ingress"
59-
// PolicyTypeEgress ...
68+
// PolicyTypeEgress is a NetworkPolicy that affects egress traffic on selected pods.
6069
PolicyTypeEgress MultiPolicyType = "Egress"
6170
)
6271

63-
// MultiNetworkPolicySpec ...
72+
// Specification of the desired behavior for this MultiNetworkPolicy.
6473
type MultiNetworkPolicySpec struct {
74+
// podSelector selects the pods to which this MultiNetworkPolicy object applies.
6575
PodSelector metav1.LabelSelector `json:"podSelector"`
6676

77+
// List of ingress rules to be applied to the selected pods. Traffic is
78+
// allowed to a pod if there are no NetworkPolicies selecting the pod
79+
// (and cluster policy otherwise allows the traffic), OR if the traffic
80+
// source is the pod's local node, OR if the traffic matches at least one
81+
// ingress rule across all of the NetworkPolicy objects whose podSelector
82+
// matches the pod. If this field is empty then this NetworkPolicy does not
83+
// allow any traffic (and serves solely to ensure that the pods it selects
84+
// are isolated by default)
6785
// +optional
6886
Ingress []MultiNetworkPolicyIngressRule `json:"ingress,omitempty"`
6987

88+
// List of egress rules to be applied to the selected pods. Outgoing traffic
89+
// is allowed if there are no NetworkPolicies selecting the pod (and cluster
90+
// policy otherwise allows the traffic), OR if the traffic matches at least
91+
// one egress rule across all of the NetworkPolicy objects whose podSelector
92+
// matches the pod. If this field is empty then this NetworkPolicy limits
93+
// all outgoing traffic (and serves solely to ensure that the pods it selects
94+
// are isolated by default). This field is beta-level in 1.8
7095
// +optional
7196
Egress []MultiNetworkPolicyEgressRule `json:"egress,omitempty"`
97+
98+
// List of rule types that the NetworkPolicy relates to. Valid options are
99+
// 'Ingress', 'Egress', or 'Ingress,Egress'. If this field is not specified,
100+
// it will default based on the existence of Ingress or Egress rules;
101+
// policies that contain an Egress section are assumed to affect Egress,
102+
// and all policies (whether or not they contain an Ingress section) are
103+
// assumed to affect Ingress. If you want to write an egress-only policy,
104+
// you must explicitly specify policyTypes [ 'Egress' ]. Likewise, if you
105+
// want to write a policy that specifies that no egress is allowed, you must
106+
// specify a policyTypes value that include 'Egress' (since such a policy
107+
// would not include an Egress section and would otherwise default to just
108+
// [ 'Ingress' ]). This field is beta-level in 1.8
72109
// +optional
73110
PolicyTypes []MultiPolicyType `json:"policyTypes,omitempty"`
74111
}
75112

76-
// MultiNetworkPolicyIngressRule ...
113+
// NetworkPolicyIngressRule describes a particular set of traffic that is
114+
// allowed to the pods matched by a NetworkPolicySpec's podSelector. The traffic
115+
// must match both ports and from.
77116
type MultiNetworkPolicyIngressRule struct {
117+
// List of ports which should be made accessible on the pods selected for
118+
// this rule. Each item in this list is combined using a logical OR. If this
119+
// field is empty or missing, this rule matches all ports (traffic not
120+
// restricted by port). If this field is present and contains at least one
121+
// item, then this rule allows traffic only if the traffic matches at least
122+
// one port in the list.
78123
// +optional
79124
Ports []MultiNetworkPolicyPort `json:"ports,omitempty"`
80125

126+
// List of sources which should be able to access the pods selected for this
127+
// rule. Items in this list are combined using a logical OR operation. If
128+
// this field is empty or missing, this rule matches all sources (traffic
129+
// not restricted by source). If this field is present and contains at least
130+
// one item, this rule allows traffic only if the traffic matches at least
131+
// one item in the from list.
81132
// +optional
82133
From []MultiNetworkPolicyPeer `json:"from,omitempty"`
83134
}
84135

85-
// MultiNetworkPolicyEgressRule ...
136+
// NetworkPolicyEgressRule describes a particular set of traffic that is allowed
137+
// out of pods matched by a NetworkPolicySpec's podSelector. The traffic must
138+
// match both ports and to. This type is beta-level in 1.8
86139
type MultiNetworkPolicyEgressRule struct {
140+
// List of destination ports for outgoing traffic. Each item in this list is
141+
// combined using a logical OR. If this field is empty or missing, this rule
142+
// matches all ports (traffic not restricted by port). If this field is
143+
// present and contains at least one item, then this rule allows traffic
144+
// only if the traffic matches at least one port in the list.
87145
// +optional
88146
Ports []MultiNetworkPolicyPort `json:"ports,omitempty"`
89147

148+
// List of destinations for outgoing traffic of pods selected for this rule.
149+
// Items in this list are combined using a logical OR operation. If this
150+
// field is empty or missing, this rule matches all destinations (traffic
151+
// not restricted by destination). If this field is present and contains at
152+
// least one item, this rule allows traffic only if the traffic matches at
153+
// least one item in the to list.
90154
// +optional
91155
To []MultiNetworkPolicyPeer `json:"to,omitempty"`
92156
}
93157

94-
// MultiNetworkPolicyPort ...
158+
// NetworkPolicyPort describes a port to allow traffic on.
95159
type MultiNetworkPolicyPort struct {
160+
// The protocol (TCP, UDP, or SCTP) which traffic must match.
161+
// If not specified, this field defaults to TCP.
96162
// +optional
97163
Protocol *v1.Protocol `json:"protocol,omitempty"`
98164

165+
// The port on the given protocol. This can either be a numerical or named
166+
// port on a pod. If this field is not provided, this matches all port names
167+
// and numbers.
99168
// +optional
100169
Port *intstr.IntOrString `json:"port,omitempty"`
101170

171+
// If set, indicates that the range of ports from port to endPort, inclusive,
172+
// should be allowed by the policy. This field cannot be defined if the port
173+
// field is not defined or if the port field is defined as a named (string)
174+
// port. The endPort must be equal or greater than port.
102175
// +optional
103176
EndPort *int32 `json:"endPort,omitempty"`
104177
}
105178

106-
// IPBlock ...
179+
// IPBlock defines policy on a particular IPBlock. If this field is set then
180+
// neither of the other fields can be.
107181
type IPBlock struct {
182+
// CIDR is a string representing the IP Block.
183+
// Valid examples are '192.168.1.1/24'.
108184
CIDR string `json:"cidr"`
185+
186+
// Except is a slice of CIDRs that should not be included within an IP Block.
187+
// Valid examples are '192.168.1.1/24'.
188+
// Except values will be rejected if they are outside the CIDR range.
109189
// +optional
110190
Except []string `json:"except,omitempty"`
111191
}
112192

113-
// MultiNetworkPolicyPeer ...
193+
// NetworkPolicyPeer describes a peer to allow traffic to/from. Only certain
194+
// combinations of fields are allowed.
114195
type MultiNetworkPolicyPeer struct {
196+
// This is a label selector which selects Pods. This field follows standard
197+
// label selector semantics; if present but empty, it selects all pods.
198+
//
199+
// If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole
200+
// selects the Pods matching PodSelector in the Namespaces selected by
201+
// NamespaceSelector. Otherwise it selects the Pods matching PodSelector
202+
// in the policy's own Namespace.
115203
// +optional
116204
PodSelector *metav1.LabelSelector `json:"podSelector,omitempty"`
117205

206+
// Selects Namespaces using cluster-scoped labels. This field follows
207+
// standard label selector semantics; if present but empty, it selects all
208+
// namespaces.
209+
//
210+
// If PodSelector is also set, then the NetworkPolicyPeer as a whole selects
211+
// the Pods matching PodSelector in the Namespaces selected by
212+
// NamespaceSelector. Otherwise it selects all Pods in the Namespaces
213+
// selected by NamespaceSelector.
118214
// +optional
119215
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty"`
120216

217+
// IPBlock defines policy on a particular IPBlock. If this field is set then
218+
// neither of the other fields can be.
121219
// +optional
122220
IPBlock *IPBlock `json:"ipBlock,omitempty"`
123221
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// +k8s:deepcopy-gen=package,register
22
// +groupName=k8s.cni.cncf.io
33
// +groupGoName=K8sCniCncfIo
4+
// +kubebuilder:object:generate=true
45

6+
// Package v1beta2 contains API Schema definitions for the k8s.cni.cncf.io v1beta2 API group.
57
package v1beta2

0 commit comments

Comments
 (0)