1 // Copyright 2020 Datawire. All rights reserved 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 /////////////////////////////////////////////////////////////////////////// 16 // Important: Run "make generate-fast" to regenerate code after modifying 17 // this file. 18 /////////////////////////////////////////////////////////////////////////// 19 20 package v3alpha1 21 22 import ( 23 corev1 "k8s.io/api/core/v1" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 ) 26 27 type ACMEProviderSpec struct { 28 // Specifies who to talk ACME with to get certs. Defaults to Let's 29 // Encrypt; if "none" (case-insensitive), do not try to do ACME for 30 // this Host. 31 Authority string `json:"authority,omitempty"` 32 Email string `json:"email,omitempty"` 33 34 // Specifies the Kubernetes Secret to use to store the private key of the ACME 35 // account (essentially, where to store the auto-generated password for the 36 // auto-created ACME account). You should not normally need to set this--the 37 // default value is based on a combination of the ACME authority being registered 38 // wit and the email address associated with the account. 39 // 40 // Note that this is a native-Kubernetes-style core.v1.LocalObjectReference, not 41 // an Ambassador-style `{name}.{namespace}` string. Because we're opinionated, it 42 // does not support referencing a Secret in another namespace (because most native 43 // Kubernetes resources don't support that), but if we ever abandon that opinion 44 // and decide to support non-local references it, it would be by adding a 45 // `namespace:` field by changing it from a core.v1.LocalObjectReference to a 46 // core.v1.SecretReference, not by adopting the `{name}.{namespace}` notation. 47 PrivateKeySecret *corev1.LocalObjectReference `json:"privateKeySecret,omitempty"` 48 49 // This is normally set automatically 50 Registration string `json:"registration,omitempty"` 51 } 52 53 type InsecureRequestPolicy struct { 54 // +kubebuilder:validation:Enum={"Redirect","Reject","Route"} 55 Action string `json:"action,omitempty"` 56 AdditionalPort *int `json:"additionalPort,omitempty"` 57 } 58 59 type RequestPolicy struct { 60 Insecure InsecureRequestPolicy `json:"insecure,omitempty"` 61 62 // Later we may define a 'secure' section too. 63 } 64 65 type PreviewURLSpec struct { 66 // Is the Preview URL feature enabled? 67 Enabled *bool `json:"enabled,omitempty"` 68 69 // What type of Preview URL is allowed? 70 Type PreviewURLType `json:"type,omitempty"` 71 } 72 73 // What type of Preview URL is allowed? 74 // 75 // - path 76 // - wildcard 77 // - datawire // FIXME rename this before release 78 // 79 // +kubebuilder:validation:Enum={"Path"} 80 type PreviewURLType string 81 82 // HostSpec defines the desired state of Host 83 type HostSpec struct { 84 // Common to all Ambassador objects (and optional). 85 AmbassadorID AmbassadorID `json:"ambassador_id,omitempty"` 86 87 // Hostname by which the Ambassador can be reached. 88 Hostname string `json:"hostname,omitempty"` 89 90 // DEPRECATED: Selector by which we can find further configuration. Use MappingSelector instead. 91 // 92 // TODO(lukeshu): In v3alpha2, figure out how to get rid of HostSpec.DeprecatedSelector. 93 DeprecatedSelector *metav1.LabelSelector `json:"selector,omitempty"` 94 95 // Selector for Mappings we'll associate with this Host. At the moment, Selector and 96 // MappingSelector are synonyms, but that will change soon. 97 MappingSelector *metav1.LabelSelector `json:"mappingSelector,omitempty"` 98 99 // Specifies whether/who to talk ACME with to automatically manage the $tlsSecret. 100 AcmeProvider *ACMEProviderSpec `json:"acmeProvider,omitempty"` 101 102 // Name of the Kubernetes secret into which to save generated 103 // certificates. If ACME is enabled (see $acmeProvider), then the 104 // default is $hostname; otherwise the default is "". If the value 105 // is "", then we do not do TLS for this Host. 106 TLSSecret *corev1.SecretReference `json:"tlsSecret,omitempty"` 107 108 // Request policy definition. 109 RequestPolicy *RequestPolicy `json:"requestPolicy,omitempty"` 110 111 // Configuration for the Preview URL feature of Service Preview. Defaults to preview URLs not enabled. 112 PreviewUrl *PreviewURLSpec `json:"previewUrl,omitempty"` 113 114 // Name of the TLSContext the Host resource is linked with. 115 // It is not valid to specify both `tlsContext` and `tls`. 116 // 117 // Note that this is a native-Kubernetes-style core.v1.LocalObjectReference, not 118 // an Ambassador-style `{name}.{namespace}` string. Because we're opinionated, it 119 // does not support referencing a Secret in another namespace (because most native 120 // Kubernetes resources don't support that), but if we ever abandon that opinion 121 // and decide to support non-local references it, it would be by adding a 122 // `namespace:` field by changing it from a core.v1.LocalObjectReference to a 123 // core.v1.SecretReference, not by adopting the `{name}.{namespace}` notation. 124 TLSContext *corev1.LocalObjectReference `json:"tlsContext,omitempty"` 125 126 // TLS configuration. It is not valid to specify both 127 // `tlsContext` and `tls`. 128 TLS *TLSConfig `json:"tls,omitempty"` 129 } 130 131 type TLSConfig struct { 132 CertChainFile string `json:"cert_chain_file,omitempty"` 133 PrivateKeyFile string `json:"private_key_file,omitempty"` 134 CASecret string `json:"ca_secret,omitempty"` 135 CAcertChainFile string `json:"cacert_chain_file,omitempty"` 136 CRLSecret string `json:"crl_secret,omitempty"` 137 AlpnProtocols string `json:"alpn_protocols,omitempty"` 138 CertRequired *bool `json:"cert_required,omitempty"` 139 MinTLSVersion string `json:"min_tls_version,omitempty"` 140 MaxTLSVersion string `json:"max_tls_version,omitempty"` 141 CipherSuites []string `json:"cipher_suites,omitempty"` 142 ECDHCurves []string `json:"ecdh_curves,omitempty"` 143 RedirectCleartextFrom *int `json:"redirect_cleartext_from,omitempty"` 144 SNI string `json:"sni,omitempty"` 145 } 146 147 // The first value listed in the Enum marker becomes the "zero" value, 148 // and it would be great if "Pending" could be the default value; but 149 // it's Important that the "zero" value be able to be shown as 150 // empty/omitted from display, and we really do want `kubectl get 151 // hosts` to say "Pending" in the "STATE" column, and not leave the 152 // column empty. 153 // 154 // +kubebuilder:validation:Type=string 155 // +kubebuilder:validation:Enum={"Initial","Pending","Ready","Error"} 156 type HostState int 157 158 // +kubebuilder:validation:Type=string 159 // +kubebuilder:validation:Enum={"NA","DefaultsFilled","ACMEUserPrivateKeyCreated","ACMEUserRegistered","ACMECertificateChallenge"} 160 type HostPhase int 161 162 // HostStatus defines the observed state of Host 163 type HostStatus struct { 164 TLSCertificateSource HostTLSCertificateSource `json:"tlsCertificateSource,omitempty"` 165 166 State HostState `json:"state,omitempty"` 167 168 // phaseCompleted and phasePending are valid when state==Pending or 169 // state==Error. 170 PhaseCompleted HostPhase `json:"phaseCompleted,omitempty"` 171 // phaseCompleted and phasePending are valid when state==Pending or 172 // state==Error. 173 PhasePending HostPhase `json:"phasePending,omitempty"` 174 175 // errorReason, errorTimestamp, and errorBackoff are valid when state==Error. 176 ErrorReason string `json:"errorReason,omitempty"` 177 ErrorTimestamp *metav1.Time `json:"errorTimestamp,omitempty"` 178 ErrorBackoff *metav1.Duration `json:"errorBackoff,omitempty"` 179 } 180 181 // +kubebuilder:validation:Enum={"Unknown","None","Other","ACME"} 182 type HostTLSCertificateSource string 183 184 // Host is the Schema for the hosts API 185 // 186 // +kubebuilder:object:root=true 187 // +kubebuilder:subresource:status 188 // +kubebuilder:printcolumn:name="Hostname",type=string,JSONPath=`.spec.hostname` 189 // +kubebuilder:printcolumn:name="State",type=string,JSONPath=`.status.state` 190 // +kubebuilder:printcolumn:name="Phase Completed",type=string,JSONPath=`.status.phaseCompleted` 191 // +kubebuilder:printcolumn:name="Phase Pending",type=string,JSONPath=`.status.phasePending` 192 // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` 193 type Host struct { 194 metav1.TypeMeta `json:""` 195 metav1.ObjectMeta `json:"metadata,omitempty"` 196 197 Spec *HostSpec `json:"spec,omitempty"` 198 Status HostStatus `json:"status,omitempty"` 199 } 200 201 // HostList contains a list of Hosts. 202 // 203 // +kubebuilder:object:root=true 204 type HostList struct { 205 metav1.TypeMeta `json:""` 206 metav1.ListMeta `json:"metadata,omitempty"` 207 Items []Host `json:"items"` 208 } 209 210 func init() { 211 SchemeBuilder.Register(&Host{}, &HostList{}) 212 } 213