-
Notifications
You must be signed in to change notification settings - Fork 6
Add support and tests for converting CRD to Underlay configuration #1113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Manish Vachharajani <[email protected]>
kopium generates types from the openapi schema that is part of k8s CRD definitions. Unfortunately, JSON and openapi only have an integer type that is signed. As a result, the k8s tools for Go will take uint32 from a Go struct and generate a CRD where the openapi type for the field is integer and where format is int32, because openapi format hints also do not have unsigned types. Then, kopium looks at this CRD and generates an i32 in rust for that field. But this is a problem because the actual value in JSON can be larger than what will fit into an i32 despite the openapi format hint. kube-rs will then use serde_json to parse the json and the rust side will fail to parse json outputted by go if the uint32 in go will not fit in a rust i32. The cleanest fix from an API POV for this is to convert the generated types for known problem fields from i32 to u32 so that all values will be parsed correctly. Sadly, the implementation of this rewrite is simple but gross. See build.rs in this commit for the implementation. Signed-off-by: Manish Vachharajani <[email protected]>
Signed-off-by: Manish Vachharajani <[email protected]>
We cannot derive Eq becuase of f64 Signed-off-by: Manish Vachharajani <[email protected]>
Adds a bolero TypeGenerator for GatewayAgentGatewayInterfaces. Also adds a Normalize trait and implementation for the same. The support.rs file comes entirely (unmodified) from the soon to be deprecated gateway-proto repository. Signed-off-by: Manish Vachharajani <[email protected]>
Signed-off-by: Manish Vachharajani <[email protected]>
Signed-off-by: Manish Vachharajani <[email protected]>
kopium cannot generate correct types for integers because openapi v3 does not have support for unsigned integers. For a CRD generated from golang with type uint8, the default rust type is i64. This commit patches workers to be a u8 instead. Signed-off-by: Manish Vachharajani <[email protected]>
This implementation is incomplete and only generates the fields relevant to the Underlay configuration. Future commits can add the funcationality for other parts when we write the config converter for those parts. Signed-off-by: Manish Vachharajani <[email protected]>
This commit adds conversion for k8s_intf::gateway_agent_crd::GatewayAgentGateway into a proper Underlay configuration. Bi-directional conversion is provided for interfaces and neighbors where there is a good mapping between the Underlay types and the CRD types. For the default VRF, where there is no corresponding type for the CRD, the default VRF is generated explicitly. Signed-off-by: Manish Vachharajani <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds support for converting Kubernetes Custom Resource Definitions (CRDs) from the GatewayAgentGateway type into the internal Underlay configuration. The conversion includes interface configurations, BGP settings, and neighbor relationships. The PR also introduces a comprehensive testing framework using Bolero for property-based testing of the conversion logic.
Key changes:
- Implements
FromStrtrait forMacandSourceMactypes to support string parsing - Creates Bolero generators for generating valid CRD test data
- Adds bidirectional conversion logic between CRD types and internal configuration types
- Includes property-based tests that verify round-trip conversion correctness
Reviewed changes
Copilot reviewed 16 out of 18 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| net/src/eth/mac.rs | Added FromStr implementations for MAC address types |
| k8s-intf/src/lib.rs | Exposed bolero module for test support |
| k8s-intf/src/bolero/support.rs | Bolero generators for IP addresses, CIDRs, interface names, and other primitives |
| k8s-intf/src/bolero/mod.rs | Core bolero module with LegalValue and Normalize traits |
| k8s-intf/src/bolero/interface.rs | Bolero generator for interface configurations |
| k8s-intf/src/bolero/gateway.rs | Bolero generator for gateway configurations |
| k8s-intf/src/bolero/bgp.rs | Bolero generator for BGP neighbor configurations |
| k8s-intf/build.rs | Type fixups for OpenAPI-generated code (i32→u32, i64→u8) |
| k8s-intf/Cargo.toml | Added bolero feature and dependencies |
| config/src/converters/mod.rs | Added k8s converters module |
| config/src/converters/k8s/underlay.rs | Conversion from GatewayAgentGateway to Underlay |
| config/src/converters/k8s/mod.rs | K8s converters module definition |
| config/src/converters/k8s/interface.rs | Bidirectional conversion for interface configurations |
| config/src/converters/k8s/bgp.rs | Bidirectional conversion for BGP neighbors |
| config/Cargo.toml | Added k8s-intf dependency |
| Cargo.toml | Added k8s-intf workspace member |
|
|
||
| fn generate<D: Driver>(&self, d: &mut D) -> Option<Self::Output> { | ||
| if self.mask == 0 && self.count > 0 { | ||
| d.produce::<u32>(); // generate a value to satisfiy the bolero driver |
Copilot
AI
Dec 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected spelling of 'satisfiy' to 'satisfy'.
| d.produce::<u32>(); // generate a value to satisfiy the bolero driver | |
| d.produce::<u32>(); // generate a value to satisfy the bolero driver |
|
|
||
| fn generate<D: Driver>(&self, d: &mut D) -> Option<Self::Output> { | ||
| if self.mask == 0 && self.count > 0 { | ||
| d.produce::<u32>(); // generate a value to satisfiy the bolero driver |
Copilot
AI
Dec 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected spelling of 'satisfiy' to 'satisfy'.
| d.produce::<u32>(); // generate a value to satisfiy the bolero driver | |
| d.produce::<u32>(); // generate a value to satisfy the bolero driver |
| if self.count == 0 { | ||
| return Some(vec![]); | ||
| } | ||
| // Calculate a mask so that we get a unique prefixes for each address to get a unique prefix |
Copilot
AI
Dec 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The phrase 'unique prefixes for each address to get a unique prefix' is redundant. Consider simplifying to 'Calculate a mask to generate unique prefixes for each address'.
| // Calculate a mask so that we get a unique prefixes for each address to get a unique prefix | |
| // Calculate a mask to generate unique prefixes for each address |
| if self.count == 0 { | ||
| return Some(vec![]); | ||
| } | ||
| // Calculate a mask so that we get a unique prefixes for each address to get a unique prefix |
Copilot
AI
Dec 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The phrase 'unique prefixes for each address to get a unique prefix' is redundant. Consider simplifying to 'Calculate a mask to generate unique prefixes for each address'.
| // Calculate a mask so that we get a unique prefixes for each address to get a unique prefix | |
| // Calculate a mask to generate unique prefixes for each address |
This PR converts the
k8s_intf::gateway_agent_crd::GatewayAgentGatewaytype to theconfigUnderlayconfiguration.Future PRs will add the Overlay configuration, followed by the code to talk to Kubernetes and fetch the config, and finally code to update the status.