Skip to content

Commit 1ac60b0

Browse files
authored
Merge pull request #44 from datum-cloud/feature/custom-hostnames
feat: Implement custom hostname support for HTTPProxies and Gateways
2 parents c6d42f2 + cba0302 commit 1ac60b0

28 files changed

Lines changed: 1631 additions & 523 deletions

api/v1alpha/httpproxy_types.go

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,46 @@ import (
1010

1111
// HTTPProxySpec defines the desired state of HTTPProxy.
1212
type HTTPProxySpec struct {
13+
14+
// Hostnames defines a set of hostnames that should match against the HTTP
15+
// Host header to select a HTTPProxy used to process the request.
16+
//
17+
// Valid values for Hostnames are determined by RFC 1123 definition of a
18+
// hostname with 1 notable exception:
19+
//
20+
// 1. IPs are not allowed.
21+
//
22+
// Hostnames must be verified before being programmed. This is accomplished
23+
// via the use of `Domain` resources. A hostname is considered verified if any
24+
// verified `Domain` resource exists in the same namespace where the
25+
// `spec.domainName` of the resource either exactly matches the hostname, or
26+
// is a suffix match of the hostname. That means that a Domain with a
27+
// `spec.domainName` of `example.com` will match a hostname of
28+
// `test.example.com`, `foo.test.example.com`, and exactly `example.com`, but
29+
// not a hostname of `test-example.com`. If a `Domain` resource does not exist
30+
// that matches a hostname, one will automatically be created when the system
31+
// attempts to program the HTTPProxy.
32+
//
33+
// In addition to verifying ownership, hostnames must be unique across the
34+
// platform. If a hostname is already programmed on another resource, a
35+
// conflict will be encountered and communicated in the `HostnamesVerified`
36+
// condition.
37+
//
38+
// Hostnames which have been programmed will be listed in the
39+
// `status.hostnames` field. Any hostname which has not been programmed will
40+
// be listed in the `message` field of the `HostnamesVerified` condition with
41+
// an indication as to why it was not programmed.
42+
//
43+
// The system may automatically generate and associate hostnames with the
44+
// HTTPProxy. In such cases, these will be listed in the `status.hostnames`
45+
// field and do not require additional configuration by the user.
46+
//
47+
// Wildcard hostnames are not supported at this time.
48+
//
49+
// +kubebuilder:validation:Optional
50+
// +kubebuilder:validation:MaxItems=16
51+
Hostnames []gatewayv1.Hostname `json:"hostnames,omitempty"`
52+
1353
// Rules are a list of HTTP matchers, filters and actions.
1454
//
1555
// +kubebuilder:validation:Required
@@ -107,7 +147,7 @@ type HTTPProxyStatus struct {
107147
// Hostnames lists the hostnames that have been bound to the HTTPProxy.
108148
//
109149
// If this list does not match that defined in the HTTPProxy, see the
110-
// `Programmed` condition message for details.
150+
// `HostnamesVerified` condition message for details.
111151
Hostnames []gatewayv1.Hostname `json:"hostnames,omitempty"`
112152

113153
// Conditions describe the current conditions of the HTTPProxy.
@@ -126,6 +166,14 @@ const (
126166
// programmed into underlying Gateway resources, and those resources have also
127167
// been programmed.
128168
HTTPProxyConditionProgrammed = "Programmed"
169+
170+
// This condition is true when all hostnames defined in an HTTPProxy or a
171+
// Gateway listener have been verified.
172+
HTTPProxyConditionHostnamesVerified = "HostnamesVerified"
173+
174+
// This condition is present and true when a hostname defined in an HTTPProxy
175+
// is in use by another resource.
176+
HTTPProxyConditionHostnamesInUse = "HostnamesInUse"
129177
)
130178

131179
const (
@@ -144,6 +192,18 @@ const (
144192
// conditions when the status is "Unknown" and no controller has reconciled
145193
// the HTTPProxy.
146194
HTTPProxyReasonPending = "Pending"
195+
196+
// This reason is used with the "HostnamesVerified" condition when all hostnames
197+
// defined in an HTTPProxy or Gateway listener have been verified.
198+
HTTPProxyReasonHostnamesVerified = "HostnamesVerified"
199+
200+
// This reason is used with the a hostname defined in an HTTPProxy or Gateway
201+
// has not been verified.
202+
UnverifiedHostnamesPresent = "UnverifiedHostnamesPresent"
203+
204+
// This reason is used with the a hostname defined in an HTTPProxy or Gateway
205+
// is in use by another resource.
206+
HostnameInUseReason = "HostnameInUse"
147207
)
148208

149209
// +kubebuilder:object:root=true

api/v1alpha/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/main.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -240,11 +240,10 @@ func main() {
240240
}
241241

242242
validationOpts := validation.GatewayValidationOptions{
243-
ControllerName: serverConfig.Gateway.ControllerName,
244-
PermittedTLSOptions: serverConfig.Gateway.PermittedTLSOptions,
245-
ValidPortNumbers: serverConfig.Gateway.ValidPortNumbers,
246-
ValidProtocolTypes: serverConfig.Gateway.ValidProtocolTypes,
247-
CustomHostnameAllowList: serverConfig.Gateway.CustomHostnameAllowList,
243+
ControllerName: serverConfig.Gateway.ControllerName,
244+
PermittedTLSOptions: serverConfig.Gateway.PermittedTLSOptions,
245+
ValidPortNumbers: serverConfig.Gateway.ValidPortNumbers,
246+
ValidProtocolTypes: serverConfig.Gateway.ValidProtocolTypes,
248247
}
249248

250249
if err := networkinggatewayv1webhooks.SetupGatewayWebhookWithManager(mgr, validationOpts); err != nil {

config/crd/bases/networking.datumapis.com_httpproxies.yaml

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,64 @@ spec:
5151
spec:
5252
description: Spec defines the desired state of an HTTPProxy.
5353
properties:
54+
hostnames:
55+
description: |-
56+
Hostnames defines a set of hostnames that should match against the HTTP
57+
Host header to select a HTTPProxy used to process the request.
58+
59+
Valid values for Hostnames are determined by RFC 1123 definition of a
60+
hostname with 1 notable exception:
61+
62+
1. IPs are not allowed.
63+
64+
Hostnames must be verified before being programmed. This is accomplished
65+
via the use of `Domain` resources. A hostname is considered verified if any
66+
verified `Domain` resource exists in the same namespace where the
67+
`spec.domainName` of the resource either exactly matches the hostname, or
68+
is a suffix match of the hostname. That means that a Domain with a
69+
`spec.domainName` of `example.com` will match a hostname of
70+
`test.example.com`, `foo.test.example.com`, and exactly `example.com`, but
71+
not a hostname of `test-example.com`. If a `Domain` resource does not exist
72+
that matches a hostname, one will automatically be created when the system
73+
attempts to program the HTTPProxy.
74+
75+
In addition to verifying ownership, hostnames must be unique across the
76+
platform. If a hostname is already programmed on another resource, a
77+
conflict will be encountered and communicated in the `HostnamesVerified`
78+
condition.
79+
80+
Hostnames which have been programmed will be listed in the
81+
`status.hostnames` field. Any hostname which has not been programmed will
82+
be listed in the `message` field of the `HostnamesVerified` condition with
83+
an indication as to why it was not programmed.
84+
85+
The system may automatically generate and associate hostnames with the
86+
HTTPProxy. In such cases, these will be listed in the `status.hostnames`
87+
field and do not require additional configuration by the user.
88+
89+
Wildcard hostnames are not supported at this time.
90+
items:
91+
description: |-
92+
Hostname is the fully qualified domain name of a network host. This matches
93+
the RFC 1123 definition of a hostname with 2 notable exceptions:
94+
95+
1. IPs are not allowed.
96+
2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard
97+
label must appear by itself as the first label.
98+
99+
Hostname can be "precise" which is a domain name without the terminating
100+
dot of a network host (e.g. "foo.example.com") or "wildcard", which is a
101+
domain name prefixed with a single wildcard label (e.g. `*.example.com`).
102+
103+
Note that as per RFC1035 and RFC1123, a *label* must consist of lower case
104+
alphanumeric characters or '-', and must start and end with an alphanumeric
105+
character. No other punctuation is allowed.
106+
maxLength: 253
107+
minLength: 1
108+
pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
109+
type: string
110+
maxItems: 16
111+
type: array
54112
rules:
55113
description: Rules are a list of HTTP matchers, filters and actions.
56114
items:
@@ -2136,7 +2194,7 @@ spec:
21362194
Hostnames lists the hostnames that have been bound to the HTTPProxy.
21372195
21382196
If this list does not match that defined in the HTTPProxy, see the
2139-
`Programmed` condition message for details.
2197+
`HostnamesVerified` condition message for details.
21402198
items:
21412199
description: |-
21422200
Hostname is the fully qualified domain name of a network host. This matches

config/dev/config.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ gateway:
1515
downstreamGatewayClassName: datum-downstream-gateway-e2e
1616
permittedTLSOptions:
1717
gateway.networking.datumapis.com/certificate-issuer: []
18-
customHostnameAllowList:
19-
- clusterName: ""
20-
suffixes:
21-
- e2e.env.datum.net
2218

2319
httpProxy:
2420
tlsOptions:

config/e2e/config.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,5 @@ gateway:
1010
downstreamGatewayClassName: datum-downstream-gateway-e2e
1111
permittedTLSOptions:
1212
gateway.networking.datumapis.com/certificate-issuer: []
13-
customHostnameAllowList:
14-
- clusterName: ""
15-
suffixes:
16-
- e2e.env.datum.net
1713
downstreamResourceManagement:
1814
kubeconfigPath: /etc/downstream-cluster/kubeconfig

config/resource-metrics/domains.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@ spec:
1010
name: [metadata, name]
1111
namespace: [metadata, namespace]
1212
metrics:
13+
- name: "owner"
14+
help: "Owner information"
15+
errorLogV: 10
16+
each:
17+
type: Info
18+
info:
19+
path: [metadata,ownerReferences]
20+
labelsFromPath:
21+
owner_kind: [kind]
22+
owner_name: [name]
23+
owner_uid: [uid]
24+
controller: [controller]
1325
- name: "info"
1426
help: "Domain information"
1527
each:

config/resource-metrics/gateways.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@ spec:
1010
name: [metadata, name]
1111
namespace: [metadata, namespace]
1212
metrics:
13+
- name: "owner"
14+
help: "Owner information"
15+
errorLogV: 10
16+
each:
17+
type: Info
18+
info:
19+
path: [metadata,ownerReferences]
20+
labelsFromPath:
21+
owner_kind: [kind]
22+
owner_name: [name]
23+
owner_uid: [uid]
24+
controller: [controller]
1325
- name: "info"
1426
help: "Gateway information"
1527
each:
@@ -48,6 +60,18 @@ spec:
4860
name: [metadata, name]
4961
namespace: [metadata, namespace]
5062
metrics:
63+
- name: "owner"
64+
help: "Owner information"
65+
errorLogV: 10
66+
each:
67+
type: Info
68+
info:
69+
path: [metadata,ownerReferences]
70+
labelsFromPath:
71+
owner_kind: [kind]
72+
owner_name: [name]
73+
owner_uid: [uid]
74+
controller: [controller]
5175
- name: "info"
5276
help: "HTTPRoute information"
5377
each:

config/resource-metrics/httpproxies.yaml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,23 @@ spec:
55
group: networking.datumapis.com
66
kind: "HTTPProxy"
77
version: "v1alpha"
8-
metricNamePrefix: datum_cloud_networking_httpproxy
8+
metricNamePrefix: datum_cloud_networking_http_proxy
99
labelsFromPath:
1010
name: [metadata, name]
1111
namespace: [metadata, namespace]
1212
metrics:
13+
- name: "owner"
14+
help: "Owner information"
15+
errorLogV: 10
16+
each:
17+
type: Info
18+
info:
19+
path: [metadata,ownerReferences]
20+
labelsFromPath:
21+
owner_kind: [kind]
22+
owner_name: [name]
23+
owner_uid: [uid]
24+
controller: [controller]
1325
- name: "info"
1426
help: "HTTPProxy information"
1527
each:

config/resource-metrics/locations.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@ spec:
1010
namespace: [metadata, namespace]
1111
name: [metadata, name]
1212
metrics:
13+
- name: "owner"
14+
help: "Owner information"
15+
errorLogV: 10
16+
each:
17+
type: Info
18+
info:
19+
path: [metadata,ownerReferences]
20+
labelsFromPath:
21+
owner_kind: [kind]
22+
owner_name: [name]
23+
owner_uid: [uid]
24+
controller: [controller]
1325
- name: "info"
1426
help: "Information about location"
1527
each:

0 commit comments

Comments
 (0)