Extend NamespaceNetworkConfiguration to support VPC#48
Draft
ihgann wants to merge 4 commits into
Draft
Conversation
…etworking
Adds the public Net Operator API through which an administrator declares the
network configuration that Net Operator applies to one or more Namespaces,
starting with vSphere Distributed (VDS) networking. Support for nsx-tier1
and vpc will follow in subsequent branches.
## New files
**api/v1alpha1/common_types.go**
Introduces NetworkProvider, the shared enum used by both
NamespaceNetworkConfiguration (to declare the desired provider) and
NetworkSettings (to reflect the realized provider in a namespace). All
three provider values are defined here so that NetworkSettings can
continue to reflect the full set; NamespaceNetworkConfiguration will grow
support for nsx-tier1 and vpc in follow-up branches.
NetworkProviderVSphereDistributed = "vsphere-distributed"
NetworkProviderNSXTier1 = "nsx-tier1"
NetworkProviderVPC = "vpc"
**api/v1alpha1/namespacenetworkconfiguration_types.go**
Introduces NamespaceNetworkConfiguration, a cluster-scoped CRD (shortName:
nnc) that declares the network configuration Net Operator applies to one or
more Namespaces.
Association: a Namespace is associated by setting the annotation
netoperator.vmware.com/network-configuration: <name> on the Namespace
(cluster-admin only). Net Operator blocks deletion of the resource while
any Namespace holds this annotation, via the protection finalizer.
Well-known keys (all prefixed NNC for brevity):
NNCAnnotationKey netoperator.vmware.com/network-configuration
NNCDefaultLabelKey netoperator.vmware.com/default
NNCProtectionFinalizer netoperator.vmware.com/namespace-network-configuration-protection
NNCConditionReady "Ready"
NNCSpec selects the provider via a required type field and carries a
provider-specific config section. A CEL rule on NNCSpec restricts type to
vsphere-distributed for this iteration (removed when nsx-tier1 and vpc are
introduced in follow-up branches).
For vsphere-distributed, the section is VSphereDistributedConfig, which
holds two required fields:
networks — one or more VSphereDistributedNetworkRef entries
(MinItems=1, MaxItems=32, listType=map). Net Operator
creates a Network CR in each Namespace for every entry
and deletes it when the entry is removed.
defaultNetwork — name of one of the entries in networks. The corresponding
Network CR is labeled netoperator.vmware.com/is-default:
"true". Unlike the VMODL (where this field is optional,
defaulting to the first entry), this field is required to
make intent unambiguous in a declarative API. The referenced
VSphereDistributedNetwork must not use IP assignment mode
None (enforced at admission/controller time; CEL cannot
dereference external resources).
CEL rules on VSphereDistributedConfig:
- defaultNetwork must name an entry in networks.
- defaultNetwork is immutable once set (aligned with the VMODL constraint
"this field does not allow update once applied").
CEL rules on NNCSpec:
- type must be vsphere-distributed (temporary; relaxed in follow-up branches).
- networks must be non-empty when type is vsphere-distributed.
NNCStatus carries a standard metav1.Condition list (Ready condition) and an
appliedToNamespaces list (NNCAppliedNamespace entries with name, status, and
optional message) that Net Operator updates as Namespaces are associated or
disassociated via the annotation. GetConditions/SetConditions helpers are
provided on the root type.
## Modified files
**api/v1alpha1/vspheredistributednetwork_types.go**
Adds VSphereDistributedNetworkRef, a by-name reference to a
VSphereDistributedNetwork resource used by VSphereDistributedConfig.networks.
**api/v1alpha1/networksettings_types.go**
Removes the now-redundant NetworkSettingsProvider type and its constants.
NetworkSettings.provider is re-typed to NetworkProvider (from common_types.go),
which carries the same enum values. The duplicate inline kubebuilder:validation:Enum
marker on the field is also removed since the type-level marker is sufficient;
the enum constraint is still emitted in the generated CRD schema.
Co-authored-by: Cursor <cursoragent@cursor.com>
…nstead of subdomain length
Adds VPCConfig as the second provider-specific config block alongside
VSphereDistributedConfig. VPC networking is activated by setting
spec.type to "vpc" and populating spec.vpcConfig.
VPCConfig supports two mutually exclusive VPC provisioning modes,
enforced by CEL mutual-exclusion guards on the type:
- vpc: associates a pre-existing NSX VPC by its Manager API path.
- managedVPCConfig: directs Net Operator to auto-provision a new VPC.
ManagedVPCConfig.project and ManagedVPCConfig.connectivityProfile
correspond to nsxProject and vpcConnectivityProfile in the nsx-operator
VPCNetworkConfiguration CRD [1]. Both fields are required when
managedVPCConfig is set; since all fields carry omitempty (KAL
convention), enforcement is via CEL rules on the type itself rather
than the OpenAPI required array — an absent field is seen as "" in CEL,
so self.project != '' catches the omitted case.
Both modes additionally accept:
- sharedSubnets: list-map of pre-existing NSX Subnets (keyed by path)
to inject into each associated Namespace, with optional podDefault
and vmDefault markers to designate workload-class defaults.
VPCSharedSubnet.name is immutable once set (CEL oldSelf guard).
- defaultSubnetSize: number of IP addresses for auto-created subnets
(maximum 65536, consistent with VPCNetworkConfiguration upstream [1]).
The temporary CEL restriction that limited spec.type to
"vsphere-distributed" is removed. A parallel CEL guard is added for
vpc: self.type == 'vpc' ? has(self.vpcConfig) : true.
All new types conform to kube-api-linter without suppressions or
exclusions. VPCConfig is embedded as *VPCConfig (pointer) because all
its fields are optional, meaning the zero value {} is only ruled out by
CEL, not by schema alone; the pointer satisfies KAL's optionalfields
linter which requires a pointer when schema validation is incomplete.
[1] https://github.com/vmware-tanzu/nsx-operator/blob/main/pkg/apis/vpc/v1alpha1/vpcnetworkconfiguration_types.go
Co-authored-by: Cursor <cursoragent@cursor.com>
8643cc0 to
11b44ef
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds VPCConfig as the second provider-specific config block alongside
VSphereDistributedConfig. VPC networking is activated by setting
spec.type to "vpc" and populating spec.vpcConfig.
VPCConfig supports two mutually exclusive VPC provisioning modes,
enforced by CEL mutual-exclusion guards on the type:
ManagedVPCConfig.project and ManagedVPCConfig.connectivityProfile
correspond to nsxProject and vpcConnectivityProfile in the nsx-operator
VPCNetworkConfiguration CRD [1]. Both fields are required when
managedVPCConfig is set; since all fields carry omitempty (KAL
convention), enforcement is via CEL rules on the type itself rather
than the OpenAPI required array — an absent field is seen as "" in CEL,
so self.project != '' catches the omitted case.
Both modes additionally accept:
to inject into each associated Namespace, with optional podDefault
and vmDefault markers to designate workload-class defaults.
VPCSharedSubnet.name is immutable once set (CEL oldSelf guard).
(maximum 65536, consistent with VPCNetworkConfiguration upstream [1]).
The temporary CEL restriction that limited spec.type to
"vsphere-distributed" is removed. A parallel CEL guard is added for
vpc: self.type == 'vpc' ? has(self.vpcConfig) : true.
All new types conform to kube-api-linter without suppressions or
exclusions. VPCConfig is embedded as *VPCConfig (pointer) because all
its fields are optional, meaning the zero value {} is only ruled out by
CEL, not by schema alone; the pointer satisfies KAL's optionalfields
linter which requires a pointer when schema validation is incomplete.
[1] https://github.com/vmware-tanzu/nsx-operator/blob/main/pkg/apis/vpc/v1alpha1/vpcnetworkconfiguration_types.go
Testing Done: