Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
cbdef6e
Keep private DNS available during control plane outages
scotwells Oct 12, 2026
023b793
fix: Preserve internal DNS availability through incomplete updates
scotwells Oct 12, 2026
c7866d0
test: Qualify DNS serving beyond control plane observation deadlines
scotwells Oct 12, 2026
1026516
fix: Persist withdrawal fences before cache cleanup
scotwells Oct 12, 2026
0684369
refactor: Separate DNS capacity status projection
scotwells Oct 12, 2026
d28d68d
fix: Retain activated DNS state when validation rejects an update
scotwells Oct 13, 2026
628b04f
test: Account for independently pending zone snapshots
scotwells Oct 13, 2026
4456419
docs: Align fleet configuration with local health probes
scotwells Oct 13, 2026
ae533d9
fix: Report resolver access independently of pending zones
scotwells Oct 13, 2026
29e3609
fix: Keep capacity observations scoped to their shard
scotwells Oct 13, 2026
28caec7
fix: Keep withdrawal activation within the watchdog deadline
scotwells Oct 13, 2026
96d80b9
test: compare outage DNS response addresses
scotwells Oct 13, 2026
00a24bc
fix: Keep DNS reference identities internal
scotwells Oct 13, 2026
fc04a81
fix: Validate resolved registration readiness
scotwells Oct 13, 2026
dabfc3f
fix: Use bounded DNS reference record names
scotwells Oct 13, 2026
fb136c5
fix: Align DNS integration boundaries
scotwells Oct 13, 2026
f08aa9d
fix: Align DNS integration boundaries
scotwells Oct 13, 2026
8052a15
test: Align DNS API boundary coverage
scotwells Oct 13, 2026
d433e23
test: Align DNS API boundary coverage
scotwells Oct 13, 2026
2d6cbcf
test: Scope naming fixtures to DNS contexts
scotwells Oct 13, 2026
26590de
test: Scope naming fixtures to DNS contexts
scotwells Oct 13, 2026
fd3e22c
refactor: Consolidate DNS outage behavior
scotwells Oct 13, 2026
5488024
fix: Keep DNS stack tests buildable
scotwells Oct 13, 2026
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
35 changes: 15 additions & 20 deletions api/v1alpha1/internaldns_project_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,9 @@ type DNSZoneAssociationSpec struct {
}

type DNSZoneAssociationStatus struct {
ResolvedDNSZoneRef DNSObjectReference `json:"resolvedDNSZoneRef,omitempty"`
ResolvedResolverContextRef DNSObjectReference `json:"resolvedResolverContextRef,omitempty"`
BindingRef *DNSObjectReference `json:"bindingRef,omitempty"`
Conditions []metav1.Condition `json:"conditions,omitempty"`
ResolvedDNSZoneRef DNSNameReference `json:"resolvedDNSZoneRef,omitempty"`
ResolvedResolverContextRef DNSNameReference `json:"resolvedResolverContextRef,omitempty"`
Conditions []metav1.Condition `json:"conditions,omitempty"`
}

// DNSResolverContext is the DNS-owned serving and namespace boundary created by
Expand All @@ -63,8 +62,8 @@ type DNSResolverContextManagedNamespace struct {
}

type DNSResolverContextManagedNamespaceStatus struct {
DNSZoneRef DNSObjectReference `json:"dnsZoneRef,omitempty"`
Suffix string `json:"suffix,omitempty"`
DNSZoneRef DNSNameReference `json:"dnsZoneRef,omitempty"`
Suffix string `json:"suffix,omitempty"`
}

type DNSResolverContextStatus struct {
Expand Down Expand Up @@ -137,9 +136,8 @@ type DNSResolverAccessBindingSpec struct {
}

type DNSResolverAccessBindingStatus struct {
ObservedSequence int64 `json:"observedSequence,omitempty"`
BindingRef *DNSObjectReference `json:"bindingRef,omitempty"`
Conditions []metav1.Condition `json:"conditions,omitempty"`
ObservedSequence int64 `json:"observedSequence,omitempty"`
Conditions []metav1.Condition `json:"conditions,omitempty"`
}

// +kubebuilder:object:root=true
Expand Down Expand Up @@ -186,9 +184,9 @@ const (

const DNSRegistrationMaxTTLSeconds int32 = 30

// +kubebuilder:validation:XValidation:rule="has(self.dnsZoneRef.uid) && self.dnsZoneRef.uid.size() > 0",message="dnsZoneRef must pin the zone UID"
// +kubebuilder:validation:XValidation:rule="self.dnsZoneRef.name.size() > 0",message="dnsZoneRef requires a name"
type DNSRegistrationSpec struct {
DNSZoneRef DNSObjectReference `json:"dnsZoneRef"`
DNSZoneRef DNSNameReference `json:"dnsZoneRef"`
Name string `json:"name"`
RecordTypes []RRType `json:"recordTypes"`
PublicationPolicy DNSPublicationPolicy `json:"publicationPolicy"`
Expand Down Expand Up @@ -358,15 +356,14 @@ func (s *DNSRegistrationSelector) AsLabelSelector() *metav1.LabelSelector {
}

type DNSNamingPolicyStatus struct {
ResolvedResolverContextRef DNSObjectReference `json:"resolvedResolverContextRef,omitempty"`
ResolvedDNSZoneRef DNSObjectReference `json:"resolvedDNSZoneRef,omitempty"`
ResolvedResolverContextRef DNSNameReference `json:"resolvedResolverContextRef,omitempty"`
ResolvedAdditionalNames []DNSResolvedAdditionalNameRule `json:"resolvedAdditionalNames,omitempty"`
Conditions []metav1.Condition `json:"conditions,omitempty"`
}

type DNSResolvedAdditionalNameRule struct {
Selector *metav1.LabelSelector `json:"selector,omitempty"`
DNSZoneRef DNSObjectReference `json:"dnsZoneRef"`
DNSZoneRef DNSNameReference `json:"dnsZoneRef"`
NamePrefix string `json:"namePrefix"`
}

Expand All @@ -388,15 +385,13 @@ type DNSNamingPolicyList struct {

// DNSManagedNamespace tracks a resolver context's canonical private namespace.
type DNSManagedNamespaceSpec struct {
ProjectUID types.UID `json:"projectUID"`
ResolverContextRef DNSObjectReference `json:"resolverContextRef"`
DomainSuffix string `json:"domainSuffix"`
DNSZoneClassName string `json:"dnsZoneClassName"`
ResolverContextRef DNSNameReference `json:"resolverContextRef"`
DomainSuffix string `json:"domainSuffix"`
DNSZoneClassName string `json:"dnsZoneClassName"`
}

type DNSManagedNamespaceStatus struct {
DNSZoneRef DNSObjectReference `json:"dnsZoneRef,omitempty"`
AssociationRef DNSObjectReference `json:"associationRef,omitempty"`
DNSZoneRef DNSNameReference `json:"dnsZoneRef,omitempty"`
CanonicalSuffix string `json:"canonicalSuffix,omitempty"`
Conditions []metav1.Condition `json:"conditions,omitempty"`
}
Expand Down
3 changes: 3 additions & 0 deletions api/v1alpha1/internaldns_service_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ type DNSResolverBindingConfiguration struct {
Listeners DNSResolverBindingListeners `json:"listeners"`
// +kubebuilder:validation:MaxItems=256
ZoneRefs []DNSObjectReference `json:"zoneRefs"`
// ZoneApices reserves each private namespace before publication is available.
// +kubebuilder:validation:MaxProperties=256
ZoneApices map[string]string `json:"zoneApices,omitempty"`
}

// +kubebuilder:validation:XValidation:rule="oldSelf == self",message="listener identity is immutable for an access binding"
Expand Down
2 changes: 1 addition & 1 deletion api/v1alpha1/internaldns_validation_envtest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ func TestPrivateDNSValidationAtAPIServer(t *testing.T) {
})
for _, ttl := range []int32{0, 31, 2147483647} {
t.Run("ttl", func(t *testing.T) {
a := &DNSRegistration{ObjectMeta: metav1.ObjectMeta{GenerateName: "registration-", Namespace: "validation"}, Spec: DNSRegistrationSpec{DNSZoneRef: DNSObjectReference{Name: "zone", UID: "zone-uid"}, Name: "web", RecordTypes: []RRType{RRTypeAAAA}, PublicationPolicy: DNSPublicationPolicyEligibleContributions, TTLSeconds: ttl}}
a := &DNSRegistration{ObjectMeta: metav1.ObjectMeta{GenerateName: "registration-", Namespace: "validation"}, Spec: DNSRegistrationSpec{DNSZoneRef: DNSNameReference{Name: "zone"}, Name: "web", RecordTypes: []RRType{RRTypeAAAA}, PublicationPolicy: DNSPublicationPolicyEligibleContributions, TTLSeconds: ttl}}
requireInvalid(t, cl.Create(ctx, a))
})
}
Expand Down
19 changes: 7 additions & 12 deletions api/v1alpha1/zz_generated.deepcopy.go

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

Original file line number Diff line number Diff line change
Expand Up @@ -43,64 +43,24 @@ spec:
type: string
domainSuffix:
type: string
projectUID:
description: |-
UID is a type that holds unique ID values, including UUIDs. Because we
don't ONLY use UUIDs, this is an alias to string. Being a type captures
intent and helps make sure that UIDs and names do not get conflated.
type: string
resolverContextRef:
description: |-
DNSObjectReference pins a namespaced object by API-assigned UID. Generation
is used where a writer must also be fenced against policy changes.
DNSNameReference selects a resource in the same project namespace.
DNS records its resolved lifetime in controller-owned status.
properties:
generation:
format: int64
minimum: 0
type: integer
name:
maxLength: 253
type: string
uid:
description: |-
UID is a type that holds unique ID values, including UUIDs. Because we
don't ONLY use UUIDs, this is an alias to string. Being a type captures
intent and helps make sure that UIDs and names do not get conflated.
maxLength: 128
type: string
required:
- name
type: object
required:
- dnsZoneClassName
- domainSuffix
- projectUID
- resolverContextRef
type: object
status:
properties:
associationRef:
description: |-
DNSObjectReference pins a namespaced object by API-assigned UID. Generation
is used where a writer must also be fenced against policy changes.
properties:
generation:
format: int64
minimum: 0
type: integer
name:
maxLength: 253
type: string
uid:
description: |-
UID is a type that holds unique ID values, including UUIDs. Because we
don't ONLY use UUIDs, this is an alias to string. Being a type captures
intent and helps make sure that UIDs and names do not get conflated.
maxLength: 128
type: string
required:
- name
type: object
canonicalSuffix:
type: string
conditions:
Expand Down Expand Up @@ -161,23 +121,12 @@ spec:
type: array
dnsZoneRef:
description: |-
DNSObjectReference pins a namespaced object by API-assigned UID. Generation
is used where a writer must also be fenced against policy changes.
DNSNameReference selects a resource in the same project namespace.
DNS records its resolved lifetime in controller-owned status.
properties:
generation:
format: int64
minimum: 0
type: integer
name:
maxLength: 253
type: string
uid:
description: |-
UID is a type that holds unique ID values, including UUIDs. Because we
don't ONLY use UUIDs, this is an alias to string. Being a type captures
intent and helps make sure that UIDs and names do not get conflated.
maxLength: 128
type: string
required:
- name
type: object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,23 +204,12 @@ spec:
properties:
dnsZoneRef:
description: |-
DNSObjectReference pins a namespaced object by API-assigned UID. Generation
is used where a writer must also be fenced against policy changes.
DNSNameReference selects a resource in the same project namespace.
DNS records its resolved lifetime in controller-owned status.
properties:
generation:
format: int64
minimum: 0
type: integer
name:
maxLength: 253
type: string
uid:
description: |-
UID is a type that holds unique ID values, including UUIDs. Because we
don't ONLY use UUIDs, this is an alias to string. Being a type captures
intent and helps make sure that UIDs and names do not get conflated.
maxLength: 128
type: string
required:
- name
type: object
Expand Down Expand Up @@ -280,47 +269,14 @@ spec:
- namePrefix
type: object
type: array
resolvedDNSZoneRef:
description: |-
DNSObjectReference pins a namespaced object by API-assigned UID. Generation
is used where a writer must also be fenced against policy changes.
properties:
generation:
format: int64
minimum: 0
type: integer
name:
maxLength: 253
type: string
uid:
description: |-
UID is a type that holds unique ID values, including UUIDs. Because we
don't ONLY use UUIDs, this is an alias to string. Being a type captures
intent and helps make sure that UIDs and names do not get conflated.
maxLength: 128
type: string
required:
- name
type: object
resolvedResolverContextRef:
description: |-
DNSObjectReference pins a namespaced object by API-assigned UID. Generation
is used where a writer must also be fenced against policy changes.
DNSNameReference selects a resource in the same project namespace.
DNS records its resolved lifetime in controller-owned status.
properties:
generation:
format: int64
minimum: 0
type: integer
name:
maxLength: 253
type: string
uid:
description: |-
UID is a type that holds unique ID values, including UUIDs. Because we
don't ONLY use UUIDs, this is an alias to string. Being a type captures
intent and helps make sure that UIDs and names do not get conflated.
maxLength: 128
type: string
required:
- name
type: object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,12 @@ spec:
properties:
dnsZoneRef:
description: |-
DNSObjectReference pins a namespaced object by API-assigned UID. Generation
is used where a writer must also be fenced against policy changes.
DNSNameReference selects a resource in the same project namespace.
DNS records its resolved lifetime in controller-owned status.
properties:
generation:
format: int64
minimum: 0
type: integer
name:
maxLength: 253
type: string
uid:
description: |-
UID is a type that holds unique ID values, including UUIDs. Because we
don't ONLY use UUIDs, this is an alias to string. Being a type captures
intent and helps make sure that UIDs and names do not get conflated.
maxLength: 128
type: string
required:
- name
type: object
Expand Down Expand Up @@ -105,8 +94,8 @@ spec:
- ttlSeconds
type: object
x-kubernetes-validations:
- message: dnsZoneRef must pin the zone UID
rule: has(self.dnsZoneRef.uid) && self.dnsZoneRef.uid.size() > 0
- message: dnsZoneRef requires a name
rule: self.dnsZoneRef.name.size() > 0
status:
properties:
canonicalFQDN:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,28 +131,6 @@ spec:
> oldSelf.authorization.sequence
status:
properties:
bindingRef:
description: |-
DNSObjectReference pins a namespaced object by API-assigned UID. Generation
is used where a writer must also be fenced against policy changes.
properties:
generation:
format: int64
minimum: 0
type: integer
name:
maxLength: 253
type: string
uid:
description: |-
UID is a type that holds unique ID values, including UUIDs. Because we
don't ONLY use UUIDs, this is an alias to string. Being a type captures
intent and helps make sure that UIDs and names do not get conflated.
maxLength: 128
type: string
required:
- name
type: object
conditions:
items:
description: Condition contains details for one aspect of the current
Expand Down
Loading
Loading