Skip to content
Draft
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
8 changes: 8 additions & 0 deletions features/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,14 @@ var (
enable(inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()).
mustRegister()

FeatureGateDNSTemplatePlugin = newFeatureGate("DNSTemplatePlugin").
reportProblemsToJiraComponent("dns").
contactPerson("grzpiotrowski").
productScope(ocpSpecific).
enhancementPR("https://issues.redhat.com/browse/NE-2118").
enable(inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()).
mustRegister()

FeatureGateMachineConfigNodes = newFeatureGate("MachineConfigNodes").
reportProblemsToJiraComponent("MachineConfigOperator").
contactPerson("ijanssen").
Expand Down
101 changes: 101 additions & 0 deletions operator/v1/types_dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,26 @@ type DNSSpec struct {
// 30 seconds or as noted in the respective Corefile for your version of OpenShift.
// +optional
Cache DNSCache `json:"cache,omitempty"`

// templates is an optional list of template configurations for custom DNS
// query handling.
// Each template defines how to handle queries matching specific zones and
// query types.
//
// Templates are injected into ALL Corefile server blocks (both custom
// servers from spec.servers and the default .:5353 block). This ensures
// consistent behavior across all DNS resolution paths.
//
// Templates are evaluated in order of zone specificity (most specific first).
// The kubernetes plugin always processes cluster.local queries before templates.
//
// IMPORTANT: AAAA filtering in dual-stack clusters requires careful configuration.
// The operator automatically excludes cluster.local from broad filters to prevent
// breaking IPv6 service connectivity.
//
// +optional
// +openshift:enable:FeatureGate=DNSTemplatePlugin
Templates []Template `json:"templates,omitempty"`
}

// DNSCache defines the fields for configuring DNS caching.
Expand Down Expand Up @@ -467,6 +487,87 @@ const (
DNSAvailable = "Available"
)

// QueryType represents DNS query types supported by templates.
// Only AAAA is supported in the initial implementation.
// Valid value is "AAAA".
// +kubebuilder:validation:Enum=AAAA
type QueryType string

const (
// QueryTypeAAAA represents IPv6 address records (AAAA).
QueryTypeAAAA QueryType = "AAAA"
// Future expansion: A, CNAME, etc.
)

// QueryClass represents DNS query classes supported by templates.
// Only IN is supported in the initial implementation.
// Valid value is "IN".
// +kubebuilder:validation:Enum=IN
type QueryClass string

const (
// QueryClassIN represents the Internet class.
QueryClassIN QueryClass = "IN"
// Future expansion: CH (Chaos), etc.
)

// ResponseCode represents DNS response codes.
// Only NOERROR is supported in the initial implementation.
// Valid value is "NOERROR".
// +kubebuilder:validation:Enum=NOERROR
type ResponseCode string

const (
// ResponseCodeNOERROR indicates successful query with or without answers.
ResponseCodeNOERROR ResponseCode = "NOERROR"
// Future expansion: NXDOMAIN, SERVFAIL, etc.
)

// Template defines a template for custom DNS query handling.
type Template struct {
// zones specifies the DNS zones this template applies to.
// Each zone must be a valid DNS name as defined in RFC 1123.
// The special zone "." matches all domains (catch-all).
// At least one zone must be specified.
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinItems=1
Zones []string `json:"zones"`

Comment on lines +528 to +535
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add schema validation for zones item format.

The comments require RFC1123-compatible zones (plus "."), but the schema currently only enforces presence/count. That allows malformed zones to be persisted and fail downstream.

Suggested CRD validation guard
 type Template struct {
 	// zones specifies the DNS zones this template applies to.
 	// Each zone must be a valid DNS name as defined in RFC 1123.
 	// The special zone "." matches all domains (catch-all).
 	// At least one zone must be specified.
+	// +kubebuilder:validation:items:Pattern=`^(\.|([a-z0-9]([-a-z0-9]*[a-z0-9])?)(\.([a-z0-9]([-a-z0-9]*[a-z0-9])?))*)$`
 	// +kubebuilder:validation:Required
 	// +kubebuilder:validation:MinItems=1
 	Zones []string `json:"zones"`
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// zones specifies the DNS zones this template applies to.
// Each zone must be a valid DNS name as defined in RFC 1123.
// The special zone "." matches all domains (catch-all).
// At least one zone must be specified.
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinItems=1
Zones []string `json:"zones"`
// zones specifies the DNS zones this template applies to.
// Each zone must be a valid DNS name as defined in RFC 1123.
// The special zone "." matches all domains (catch-all).
// At least one zone must be specified.
// +kubebuilder:validation:items:Pattern=`^(\.|([a-z0-9]([-a-z0-9]*[a-z0-9])?)(\.([a-z0-9]([-a-z0-9]*[a-z0-9])?))*)$`
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinItems=1
Zones []string `json:"zones"`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@operator/v1/types_dns.go` around lines 528 - 535, The Zones slice lacks
per-item format validation; update the Zones field in operator/v1/types_dns.go
to add a kubebuilder validation Pattern that enforces RFC1123 DNS names or the
literal ".". Specifically, add a comment like //
+kubebuilder:validation:Pattern="^(\\.|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$"
immediately above the Zones []string `json:"zones"` declaration so each entry is
validated as either "." or an RFC1123-compliant name. Ensure the annotation is
placed alongside the existing Required/MinItems tags.

// queryType specifies the DNS query type to match.
// +kubebuilder:validation:Required
// +kubebuilder:default=AAAA
QueryType QueryType `json:"queryType"`

// queryClass specifies the DNS query class to match.
// +kubebuilder:validation:Required
// +kubebuilder:default=IN
QueryClass QueryClass `json:"queryClass"`

// action defines what the template should do with matching queries.
// Exactly one action type must be specified.
// +kubebuilder:validation:Required
Action TemplateAction `json:"action"`
}

// TemplateAction defines the action taken by the template.
// This is a discriminated union - exactly one action type must be specified.

// +union
// +kubebuilder:validation:XValidation:rule="has(self.response)",message="response must be specified"
type TemplateAction struct {
// +kubebuilder:validation:Required
// +unionDiscriminator
Response *ReturnEmptyAction `json:"response"`
}

// ReturnEmptyAction configures returning empty responses for filtering.
type ReturnEmptyAction struct {
// +kubebuilder:validation:Required
// +kubebuilder:validation:Enum=NOERROR
// +kubebuilder:default=NOERROR
Rcode ResponseCode `json:"rcode"`
}

// DNSStatus defines the observed status of the DNS.
type DNSStatus struct {
// clusterIP is the service IP through which this DNS is made available.
Expand Down