Skip to content
Closed
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
50 changes: 50 additions & 0 deletions api/v1alpha/network_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,32 @@ const (
NetworkReasonRangeUnsupported = "RangeUnsupported"
)

const (
// NetworkFabricIdentityAllocated reports whether the network holds the
// identity the fabric knows it by. The type is bare because the fabric
// reads this condition as the answer to "does this network have an
// identity", not as one allocation among several.
NetworkFabricIdentityAllocated = "Allocated"

// NetworkFabricIdentityReasonAllocated means the network holds an identity.
NetworkFabricIdentityReasonAllocated = "Allocated"

// NetworkFabricIdentityReasonPending means nothing has been allocated yet
// and the reason is not yet one of the ones below.
NetworkFabricIdentityReasonPending = "Pending"

// NetworkFabricIdentityReasonIdentitySpaceUnavailable means the identity
// space did not answer, so the network has no identity to carry. It is
// retried.
NetworkFabricIdentityReasonIdentitySpaceUnavailable = "IdentitySpaceUnavailable"

// NetworkFabricIdentityReasonIdentityUnusable means the identity space
// answered with a block the identifier cannot be read out of. Handing out
// the zero block is the case an operator hits first: zero is what an
// unallocated network reads as, so it can never be an allocation.
NetworkFabricIdentityReasonIdentityUnusable = "IdentityUnusable"
)

// NetworkStatus defines the observed state of Network
type NetworkStatus struct {
// Represents the observations of a network's current state.
Expand All @@ -107,6 +133,29 @@ type NetworkStatus struct {
//
// +kubebuilder:validation:Optional
IPAM *NetworkIPAMStatus `json:"ipam,omitempty"`

// FabricIdentity is the identity the fabric knows this network by,
// allocated once, platform-wide, and the same in every location the network
// reaches. What consumes it derives the network's BGP Route Target from it,
// which is what makes two locations of one network import each other's
// routes rather than behave as two networks that share a name.
//
// It is an integer rather than an encoded string because the consumer
// builds `ASN:<identity>`, and it is 32 bits wide because that is what
// survives into the Route Target. A wider value would be uniqueness the
// platform believes it has and the fabric does not.
//
// Zero means unallocated, so an unset field and a real allocation never
// read alike. Once set it never changes: the fabric embeds it in import
// policy in every location the network reaches, so a network that changed
// identity would be a different network to everything already carrying its
// traffic.
//
// +kubebuilder:validation:Optional
// +kubebuilder:validation:Minimum=0
// +kubebuilder:validation:Maximum=4294967295
// +kubebuilder:validation:XValidation:rule="oldSelf == 0 || self == oldSelf",message="fabricIdentity is immutable once allocated"
FabricIdentity int64 `json:"fabricIdentity,omitempty"`
}

// NetworkIPAMStatus reports what IPAM holds for a network.
Expand Down Expand Up @@ -159,6 +208,7 @@ type NetworkPrefixRef struct {
// +kubebuilder:printcolumn:name="IPFamilies",type="string",JSONPath=".spec.ipFamilies",priority=1
// +kubebuilder:printcolumn:name="IPAM",type="string",JSONPath=".spec.ipam.mode",priority=1
// +kubebuilder:printcolumn:name="MTU",type="integer",JSONPath=".spec.mtu",priority=1
// +kubebuilder:printcolumn:name="FabricIdentity",type="integer",JSONPath=".status.fabricIdentity",priority=1

// Network is the Schema for the networks API
type Network struct {
Expand Down
21 changes: 21 additions & 0 deletions api/v1alpha/networkcontext_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,30 @@ type NetworkContextSpec struct {
// +kubebuilder:validation:Maximum=8856
MTU int32 `json:"mtu,omitempty"`

// FabricIdentity is the network's fabric identity, projected from the
// Network's status. This is where a location reads it: cells cannot reach
// project control planes, and propagation to them carries spec and not
// status.
//
// Zero means the identity has not been projected here yet, either because
// the network does not have one or because this location has not caught up
// with the allocation. A reader that finds it unset must wait rather than
// choose an identity of its own, which is what every location does today
// and is the reason one network is two on the fabric.
//
// +kubebuilder:validation:Optional
// +kubebuilder:validation:Minimum=0
// +kubebuilder:validation:Maximum=4294967295
FabricIdentity int64 `json:"fabricIdentity,omitempty"`

// The Network generation the projected fields were read from, so an operator
// comparing this to the Network can tell whether this location has caught up.
//
// The identity is allocated into the Network's status, so it lands without
// advancing that generation. This still answers whether the location has
// caught up with the network's spec; whether it has caught up with the
// allocation is answered by the identity being present.
//
// +kubebuilder:validation:Optional
NetworkGeneration int64 `json:"networkGeneration,omitempty"`
}
Expand Down
21 changes: 21 additions & 0 deletions config/crd/bases/networking.datumapis.com_networkcontexts.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,22 @@ spec:
spec:
description: NetworkContextSpec defines the desired state of NetworkContext
properties:
fabricIdentity:
description: |-
FabricIdentity is the network's fabric identity, projected from the
Network's status. This is where a location reads it: cells cannot reach
project control planes, and propagation to them carries spec and not
status.

Zero means the identity has not been projected here yet, either because
the network does not have one or because this location has not caught up
with the allocation. A reader that finds it unset must wait rather than
choose an identity of its own, which is what every location does today
and is the reason one network is two on the fabric.
format: int64
maximum: 4294967295
minimum: 0
type: integer
ipFamilies:
description: |-
IP families the network carries, projected from the Network.
Expand Down Expand Up @@ -96,6 +112,11 @@ spec:
description: |-
The Network generation the projected fields were read from, so an operator
comparing this to the Network can tell whether this location has caught up.

The identity is allocated into the Network's status, so it lands without
advancing that generation. This still answers whether the location has
caught up with the network's spec; whether it has caught up with the
allocation is answered by the identity being present.
format: int64
type: integer
required:
Expand Down
29 changes: 29 additions & 0 deletions config/crd/bases/networking.datumapis.com_networks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ spec:
name: MTU
priority: 1
type: integer
- jsonPath: .status.fabricIdentity
name: FabricIdentity
priority: 1
type: integer
name: v1alpha
schema:
openAPIV3Schema:
Expand Down Expand Up @@ -171,6 +175,31 @@ spec:
- type
type: object
type: array
fabricIdentity:
description: |-
FabricIdentity is the identity the fabric knows this network by,
allocated once, platform-wide, and the same in every location the network
reaches. What consumes it derives the network's BGP Route Target from it,
which is what makes two locations of one network import each other's
routes rather than behave as two networks that share a name.

It is an integer rather than an encoded string because the consumer
builds `ASN:<identity>`, and it is 32 bits wide because that is what
survives into the Route Target. A wider value would be uniqueness the
platform believes it has and the fabric does not.

Zero means unallocated, so an unset field and a real allocation never
read alike. Once set it never changes: the fabric embeds it in import
policy in every location the network reaches, so a network that changed
identity would be a different network to everything already carrying its
traffic.
format: int64
maximum: 4294967295
minimum: 0
type: integer
x-kubernetes-validations:
- message: fabricIdentity is immutable once allocated
rule: oldSelf == 0 || self == oldSelf
ipam:
description: IPAM reports the address space IPAM holds for this network.
properties:
Expand Down
27 changes: 26 additions & 1 deletion docs/api/networkcontexts.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,26 @@ NetworkContextSpec defines the desired state of NetworkContext
The attached network<br/>
</td>
<td>true</td>
</tr><tr>
<td><b>fabricIdentity</b></td>
<td>integer</td>
<td>
FabricIdentity is the network's fabric identity, projected from the
Network's status. This is where a location reads it: cells cannot reach
project control planes, and propagation to them carries spec and not
status.

Zero means the identity has not been projected here yet, either because
the network does not have one or because this location has not caught up
with the allocation. A reader that finds it unset must wait rather than
choose an identity of its own, which is what every location does today
and is the reason one network is two on the fabric.<br/>
<br/>
<i>Format</i>: int64<br/>
<i>Minimum</i>: 0<br/>
<i>Maximum</i>: 4.294967295e+09<br/>
</td>
<td>false</td>
</tr><tr>
<td><b>ipFamilies</b></td>
<td>[]enum</td>
Expand Down Expand Up @@ -128,7 +148,12 @@ the same as a network that carries nothing.<br/>
<td>integer</td>
<td>
The Network generation the projected fields were read from, so an operator
comparing this to the Network can tell whether this location has caught up.<br/>
comparing this to the Network can tell whether this location has caught up.

The identity is allocated into the Network's status, so it lands without
advancing that generation. This still answers whether the location has
caught up with the network's spec; whether it has caught up with the
allocation is answered by the identity being present.<br/>
<br/>
<i>Format</i>: int64<br/>
</td>
Expand Down
27 changes: 27 additions & 0 deletions docs/api/networks.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,33 @@ NetworkStatus defines the observed state of Network
Represents the observations of a network's current state.<br/>
</td>
<td>false</td>
</tr><tr>
<td><b>fabricIdentity</b></td>
<td>integer</td>
<td>
FabricIdentity is the identity the fabric knows this network by,
allocated once, platform-wide, and the same in every location the network
reaches. What consumes it derives the network's BGP Route Target from it,
which is what makes two locations of one network import each other's
routes rather than behave as two networks that share a name.

It is an integer rather than an encoded string because the consumer
builds `ASN:<identity>`, and it is 32 bits wide because that is what
survives into the Route Target. A wider value would be uniqueness the
platform believes it has and the fabric does not.

Zero means unallocated, so an unset field and a real allocation never
read alike. Once set it never changes: the fabric embeds it in import
policy in every location the network reaches, so a network that changed
identity would be a different network to everything already carrying its
traffic.<br/>
<br/>
<i>Validations</i>:<li>oldSelf == 0 || self == oldSelf: fabricIdentity is immutable once allocated</li>
<i>Format</i>: int64<br/>
<i>Minimum</i>: 0<br/>
<i>Maximum</i>: 4.294967295e+09<br/>
</td>
<td>false</td>
</tr><tr>
<td><b><a href="#networkstatusipam">ipam</a></b></td>
<td>object</td>
Expand Down
Loading
Loading