Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 77 additions & 19 deletions api/v1alpha1/vpcattachment_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,25 @@ import (

const VPCAttachmentAnnotation = "k8s.v1alpha1.cloud.datumapis.com/vpc-attachment"

const (
// ConditionTypeReady reports that identifiers are allocated and the
// NetworkAttachmentDefinition is written.
ConditionTypeReady = "Ready"

// ConditionTypeProgrammed reports that the data plane realized the attachment.
ConditionTypeProgrammed = "Programmed"
)

// VPCAttachmentSpec defines the desired state of VPCAttachment
//
// +kubebuilder:validation:XValidation:rule="has(self.vpc) && self.vpc.name != ”",message="vpc reference is required"
type VPCAttachmentSpec struct {
// VPC this attachment belongs to.
// +required
VPC VPCRef `json:"vpc"`

// NetworkInterface this attachment realizes.
// +optional
InterfaceRef *NetworkInterfaceRef `json:"interfaceRef,omitempty"`

// Interface defines the network interface configuration.
// +required
Interface VPCAttachmentInterface `json:"interface"`
Expand All @@ -43,27 +54,61 @@ type VPCRef struct {
Name string `json:"name"`
}

// NetworkInterfaceRef references a networking.datumapis.com NetworkInterface in
// the same namespace.
type NetworkInterfaceRef struct {
// Name of the NetworkInterface.
// +kubebuilder:validation:MinLength=1
// +required
Name string `json:"name"`
}

// IPAddress is an IPv4 or IPv6 address with CIDR notation.
// +kubebuilder:validation:MaxLength=64
type IPAddress string

// VPCAttachmentInterfaceMode is how the workload consumes the interface. It
// describes the guest, not the data plane, so a change of implementation on the
// data plane side does not move this API.
// +kubebuilder:validation:Enum=Netns;Hypervisor
type VPCAttachmentInterfaceMode string

const (
// VPCAttachmentInterfaceModeNetns moves the interface into the workload's
// network namespace, which is what a container consumes.
VPCAttachmentInterfaceModeNetns VPCAttachmentInterfaceMode = "Netns"

// VPCAttachmentInterfaceModeHypervisor hands the interface to a hypervisor as
// a device, which is what a virtual machine guest consumes.
VPCAttachmentInterfaceModeHypervisor VPCAttachmentInterfaceMode = "Hypervisor"
)

// VPCAttachmentInterface defines the network interface details.
//
// +kubebuilder:validation:XValidation:rule="self.addresses.all(a, isCIDR(a))",message="each address must be a valid IPv4 or IPv6 CIDR"
// +kubebuilder:validation:XValidation:rule="!has(self.addresses) || self.addresses.all(a, isCIDR(a))",message="each address must be a valid IPv4 or IPv6 CIDR"
type VPCAttachmentInterface struct {
// Name of the interface (e.g., eth0).
// +required
// +default:value="eth0"
Name string `json:"name"`

// A list of IPv4 or IPv6 addresses associated with the interface.
// +kubebuilder:validation:MinItems=1
// Mode is how the workload consumes the interface, resolved and written by
// the attachment controller rather than by whoever runs the workload.
// +kubebuilder:default=Netns
// +optional
Mode VPCAttachmentInterfaceMode `json:"mode,omitempty"`

// A list of IPv4 or IPv6 addresses associated with the interface. Empty when
// the guest manages its own addressing.
// +kubebuilder:validation:MaxItems=16
// +required
Addresses []IPAddress `json:"addresses"`
// +optional
Addresses []IPAddress `json:"addresses,omitempty"`
}

// VPCAttachmentStatus defines the observed state of VPCAttachment.
//
// Every field but Conditions is optional: an identifier is recorded before a pod
// attaches, and a guest managing its own addressing never reports a subnet.
type VPCAttachmentStatus struct {
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
Expand All @@ -76,44 +121,57 @@ type VPCAttachmentStatus struct {
// Base62-encoded VPC identifier.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=16
VPC string `json:"vpc"`
// +optional
VPC string `json:"vpc,omitempty"`

// Base62-encoded VPCAttachment identifier.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=16
VPCAttachment string `json:"vpcAttachment"`
// +optional
VPCAttachment string `json:"vpcAttachment,omitempty"`

// Kubernetes node name where the attachment lives.
// +kubebuilder:validation:MinLength=1
Node string `json:"node"`
// +optional
Node string `json:"node,omitempty"`

// Full container ID (46 hex characters).
// +kubebuilder:validation:MinLength=46
// +kubebuilder:validation:MaxLength=46
ContainerID string `json:"containerID"`
// +optional
ContainerID string `json:"containerID,omitempty"`

// Pod name.
// +kubebuilder:validation:MinLength=1
PodName string `json:"podName"`
// +optional
PodName string `json:"podName,omitempty"`

// Host-side veth device name (e.g., "G000000010010H").
// Host-side veth or tap device name (e.g., "G000000010013H").
// +kubebuilder:validation:MinLength=1
HostInterface string `json:"hostInterface"`
// +optional
HostInterface string `json:"hostInterface,omitempty"`

// VRF device name (e.g., "G000000010010V").
// VRF device name, which is per-VPC (e.g., "G000000010V").
// +kubebuilder:validation:MinLength=1
VRFInterface string `json:"vrfInterface"`
// +optional
VRFInterface string `json:"vrfInterface,omitempty"`

// Guest-side veth device name (e.g., "G000000010010G").
// Guest-side veth device name (e.g., "G000000010013G").
// +kubebuilder:validation:MinLength=1
// +optional
GuestInterface string `json:"guestInterface,omitempty"`

// Allocated /80 subnet in CIDR notation (e.g., "fd00:10:ff01:0:1::/80").
// Allocated subnet in CIDR notation (e.g., "fd00:10:ff01:0:1::/80").
// +kubebuilder:validation:MinLength=1
// +optional
//
// +kubebuilder:validation:XValidation:rule="isCIDR(self)",message="podSubnet must be a valid IPv6 CIDR"
PodSubnet string `json:"podSubnet"`
PodSubnet string `json:"podSubnet,omitempty"`

// NetworkAttachmentDefinition rendered for this attachment.
// +kubebuilder:validation:MinLength=1
// +optional
NetworkAttachmentDefinition string `json:"networkAttachmentDefinition,omitempty"`
}

// +kubebuilder:object:root=true
Expand Down
20 changes: 20 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 31 additions & 21 deletions config/crd/cloud.datumapis.com_vpcattachments.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,27 +43,45 @@ spec:
description: Interface defines the network interface configuration.
properties:
addresses:
description: A list of IPv4 or IPv6 addresses associated with
the interface.
description: |-
A list of IPv4 or IPv6 addresses associated with the interface. Empty when
the guest manages its own addressing.
items:
description: IPAddress is an IPv4 or IPv6 address with CIDR
notation.
maxLength: 64
type: string
maxItems: 16
minItems: 1
type: array
mode:
default: Netns
description: |-
Mode is how the workload consumes the interface, resolved and written by
the attachment controller rather than by whoever runs the workload.
enum:
- Netns
- Hypervisor
type: string
name:
default: eth0
description: Name of the interface (e.g., eth0).
type: string
required:
- addresses
- name
type: object
x-kubernetes-validations:
- message: each address must be a valid IPv4 or IPv6 CIDR
rule: self.addresses.all(a, isCIDR(a))
rule: '!has(self.addresses) || self.addresses.all(a, isCIDR(a))'
interfaceRef:
description: NetworkInterface this attachment realizes.
properties:
name:
description: Name of the NetworkInterface.
minLength: 1
type: string
required:
- name
type: object
vpc:
description: VPC this attachment belongs to.
properties:
Expand All @@ -78,9 +96,6 @@ spec:
- interface
- vpc
type: object
x-kubernetes-validations:
- message: vpc reference is required
rule: has(self.vpc) && self.vpc.name != ''
status:
description: status defines the observed state of VPCAttachment
properties:
Expand Down Expand Up @@ -149,11 +164,15 @@ spec:
minLength: 46
type: string
guestInterface:
description: Guest-side veth device name (e.g., "G000000010010G").
description: Guest-side veth device name (e.g., "G000000010013G").
minLength: 1
type: string
hostInterface:
description: Host-side veth device name (e.g., "G000000010010H").
description: Host-side veth or tap device name (e.g., "G000000010013H").
minLength: 1
type: string
networkAttachmentDefinition:
description: NetworkAttachmentDefinition rendered for this attachment.
minLength: 1
type: string
node:
Expand All @@ -168,7 +187,7 @@ spec:
minLength: 1
type: string
podSubnet:
description: Allocated /80 subnet in CIDR notation (e.g., "fd00:10:ff01:0:1::/80").
description: Allocated subnet in CIDR notation (e.g., "fd00:10:ff01:0:1::/80").
minLength: 1
type: string
x-kubernetes-validations:
Expand All @@ -185,18 +204,9 @@ spec:
minLength: 1
type: string
vrfInterface:
description: VRF device name (e.g., "G000000010010V").
description: VRF device name, which is per-VPC (e.g., "G000000010V").
minLength: 1
type: string
required:
- containerID
- hostInterface
- node
- podName
- podSubnet
- vpc
- vpcAttachment
- vrfInterface
type: object
required:
- spec
Expand Down
53 changes: 48 additions & 5 deletions docs/api/vpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,23 @@ _Appears in:_



#### NetworkInterfaceRef



NetworkInterfaceRef references a networking.datumapis.com NetworkInterface in
the same namespace.



_Appears in:_
- [VPCAttachmentSpec](#vpcattachmentspec)

| Field | Description | Default | Validation |
| --- | --- | --- | --- |
| `name` _string_ | Name of the NetworkInterface. | | MinLength: 1 <br /> |


#### VPC


Expand Down Expand Up @@ -99,7 +116,28 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
| `name` _string_ | Name of the interface (e.g., eth0). | | |
| `addresses` _[IPAddress](#ipaddress) array_ | A list of IPv4 or IPv6 addresses associated with the interface. | | MaxItems: 16 <br />MaxLength: 64 <br />MinItems: 1 <br /> |
| `mode` _[VPCAttachmentInterfaceMode](#vpcattachmentinterfacemode)_ | Mode is how the workload consumes the interface, resolved and written by<br />the attachment controller rather than by whoever runs the workload. | Netns | Enum: [Netns Hypervisor] <br /> |
| `addresses` _[IPAddress](#ipaddress) array_ | A list of IPv4 or IPv6 addresses associated with the interface. Empty when<br />the guest manages its own addressing. | | MaxItems: 16 <br />MaxLength: 64 <br /> |


#### VPCAttachmentInterfaceMode

_Underlying type:_ _string_

VPCAttachmentInterfaceMode is how the workload consumes the interface. It
describes the guest, not the data plane, so a change of implementation on the
data plane side does not move this API.

_Validation:_
- Enum: [Netns Hypervisor]

_Appears in:_
- [VPCAttachmentInterface](#vpcattachmentinterface)

| Field | Description |
| --- | --- |
| `Netns` | VPCAttachmentInterfaceModeNetns moves the interface into the workload's<br />network namespace, which is what a container consumes.<br /> |
| `Hypervisor` | VPCAttachmentInterfaceModeHypervisor hands the interface to a hypervisor as<br />a device, which is what a virtual machine guest consumes.<br /> |


#### VPCAttachmentSpec
Expand All @@ -116,6 +154,7 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
| `vpc` _[VPCRef](#vpcref)_ | VPC this attachment belongs to. | | |
| `interfaceRef` _[NetworkInterfaceRef](#networkinterfaceref)_ | NetworkInterface this attachment realizes. | | |
| `interface` _[VPCAttachmentInterface](#vpcattachmentinterface)_ | Interface defines the network interface configuration. | | |


Expand All @@ -125,6 +164,9 @@ _Appears in:_

VPCAttachmentStatus defines the observed state of VPCAttachment.

Every field but Conditions is optional: an identifier is recorded before a pod
attaches, and a guest managing its own addressing never reports a subnet.



_Appears in:_
Expand All @@ -139,10 +181,11 @@ _Appears in:_
| `node` _string_ | Kubernetes node name where the attachment lives. | | MinLength: 1 <br /> |
| `containerID` _string_ | Full container ID (46 hex characters). | | MaxLength: 46 <br />MinLength: 46 <br /> |
| `podName` _string_ | Pod name. | | MinLength: 1 <br /> |
| `hostInterface` _string_ | Host-side veth device name (e.g., "G000000010010H"). | | MinLength: 1 <br /> |
| `vrfInterface` _string_ | VRF device name (e.g., "G000000010010V"). | | MinLength: 1 <br /> |
| `guestInterface` _string_ | Guest-side veth device name (e.g., "G000000010010G"). | | MinLength: 1 <br /> |
| `podSubnet` _string_ | Allocated /80 subnet in CIDR notation (e.g., "fd00:10:ff01:0:1::/80"). | | MinLength: 1 <br /> |
| `hostInterface` _string_ | Host-side veth or tap device name (e.g., "G000000010013H"). | | MinLength: 1 <br /> |
| `vrfInterface` _string_ | VRF device name, which is per-VPC (e.g., "G000000010V"). | | MinLength: 1 <br /> |
| `guestInterface` _string_ | Guest-side veth device name (e.g., "G000000010013G"). | | MinLength: 1 <br /> |
| `podSubnet` _string_ | Allocated subnet in CIDR notation (e.g., "fd00:10:ff01:0:1::/80"). | | MinLength: 1 <br /> |
| `networkAttachmentDefinition` _string_ | NetworkAttachmentDefinition rendered for this attachment. | | MinLength: 1 <br /> |


#### VPCRef
Expand Down
Loading
Loading