@@ -8,31 +8,34 @@ import (
88
99// +kubebuilder:object:root=true
1010// +kubebuilder:subresource:status
11- // +kubebuilder:printcolumn:name="Domain",type="string",JSONPath=".spec.domainName"
12- // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
13- // +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=`.status.conditions[?(@.type=="Ready")].status`
14- // +kubebuilder:printcolumn:name="Reason",type="string",JSONPath=`.status.conditions[?(@.type=="Ready")].reason`
15- // +kubebuilder:printcolumn:name="Registrar",type="string",JSONPath=".status.registrar.ianaName"
16- // +kubebuilder:printcolumn:name="DNSSEC",type="boolean",JSONPath=".status.registrar.dnssec.signed"
17- // +kubebuilder:printcolumn:name="Expires",type="date",JSONPath=".status.registrar.expirationDate"
18- // +kubebuilder:printcolumn:name="DNS-Verify",type="string",JSONPath=".status.verification.requiredDNSRecords[0].content"
1911
2012// Domain represents a domain name in the Datum system
13+ //
14+ // +kubebuilder:printcolumn:name="Domain Name",type="string",JSONPath=".spec.domainName"
15+ // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
16+ // +kubebuilder:printcolumn:name="Verified",type="string",JSONPath=`.status.conditions[?(@.type=="Verified")].status`
17+ // +kubebuilder:printcolumn:name="Verification Message",type="string",JSONPath=`.status.conditions[?(@.type=="Verified")].message`,priority=1
2118type Domain struct {
2219 metav1.TypeMeta `json:",inline"`
2320 metav1.ObjectMeta `json:"metadata,omitempty"`
2421
25- Spec DomainSpec `json:"spec,omitempty"`
22+ // +kubebuilder:validation:Required
23+ Spec DomainSpec `json:"spec,omitempty"`
24+
25+ // +kubebuilder:default={conditions: {{type: "Verified", status: "Unknown", reason:"Pending", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"},{type: "VerifiedDNS", status: "Unknown", reason:"Pending", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"},{type: "VerifiedHTTP", status: "Unknown", reason:"Pending", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"}}}
2626 Status DomainStatus `json:"status,omitempty"`
2727}
2828
2929// DomainSpec defines the desired state of Domain
3030type DomainSpec struct {
3131 // DomainName is the fully qualified domain name (FQDN) to be managed
32+ //
3233 // +kubebuilder:validation:Required
3334 // +kubebuilder:validation:MinLength=1
3435 // +kubebuilder:validation:MaxLength=253
3536 // +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
37+ // +kubebuilder:validation:XValidation:message="A domain name is immutable and cannot be changed after creation",rule="oldSelf == '' || self == oldSelf"
38+ // +kubebuilder:validation:XValidation:message="Must have at least two segments separated by dots",rule="self.indexOf('.') != -1"
3639 DomainName string `json:"domainName"`
3740}
3841
@@ -43,9 +46,49 @@ type DomainStatus struct {
4346 Conditions []metav1.Condition `json:"conditions,omitempty"`
4447}
4548
49+ const (
50+ // This condition is true when Domain ownership has been verified via either
51+ // DNS or HTTP.
52+ DomainConditionVerified = "Verified"
53+
54+ // This condition tracks verification attempts via DNS.
55+ DomainConditionVerifiedDNS = "VerifiedDNS"
56+
57+ // This condition tracks verification attempts via HTTP.
58+ DomainConditionVerifiedHTTP = "VerifiedHTTP"
59+ )
60+
61+ const (
62+ // DomainReasonPendingVerification indicates domain verification is in
63+ // progress
64+ DomainReasonPendingVerification = "PendingVerification"
65+
66+ // DomainReasonVerificationRecordContentMismatch indicates the
67+ // verification record content does not match expected values
68+ DomainReasonVerificationRecordContentMismatch = "VerificationRecordContentMismatch"
69+
70+ // DomainReasonVerificationRecordNotFound indicates the verification record
71+ // was not found
72+ DomainReasonVerificationRecordNotFound = "RecordNotFound"
73+
74+ // DomainReasonVerificationUnexpectedResponse indicates that an unexpected
75+ // response was encountered during verification.
76+ DomainReasonVerificationUnexpectedResponse = "UnexpectedResponse"
77+
78+ // DomainReasonVerificationInternalError indicates that an internal error
79+ // was encountered during verification.
80+ DomainReasonVerificationInternalError = "InternalError"
81+
82+ // DomainReasonVerified indicates domain ownership has been successfully
83+ // verified
84+ DomainReasonVerified = "Verified"
85+ )
86+
4687// DomainVerificationStatus represents the verification status of a domain
4788type DomainVerificationStatus struct {
48- RequiredDNSRecords []DNSVerificationExpectedRecord `json:"requiredDNSRecords,omitempty"`
89+ DNSRecord DNSVerificationRecord `json:"dnsRecord,omitempty"`
90+ HTTPToken HTTPVerificationToken `json:"httpToken,omitempty"`
91+ NextVerificationAttempt metav1.Time `json:"nextVerificationAttempt,omitempty"`
4992}
5093
5194// DomainRegistrarStatus represents the registrar information for a domain
@@ -66,13 +109,18 @@ type DNSSECStatus struct {
66109 Signed bool `json:"signed"`
67110}
68111
69- // DNSVerificationExpectedRecord represents a DNS record required for verification
70- type DNSVerificationExpectedRecord struct {
112+ // DNSVerificationRecord represents a DNS record required for verification
113+ type DNSVerificationRecord struct {
71114 Name string `json:"name"`
72115 Type string `json:"type"`
73116 Content string `json:"content"`
74117}
75118
119+ type HTTPVerificationToken struct {
120+ URL string `json:"url"`
121+ Body string `json:"body"`
122+ }
123+
76124// +kubebuilder:object:root=true
77125
78126// DomainList contains a list of Domain
0 commit comments