Skip to content

Commit 3394146

Browse files
authored
feat: implement InterceptorRoute CRD (#1532)
1 parent 741203d commit 3394146

73 files changed

Lines changed: 4572 additions & 1975 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ This changelog keeps track of work items that have been completed and are ready
3131

3232
### New
3333

34-
- **General**: TODO ([#TODO](https://github.com/kedacore/http-add-on/issues/TODO))
34+
- **General**: Add `InterceptorRoute` CRD to separate routing/interceptor config from scaling config; `HTTPScaledObject` remains supported but will be deprecated in a future release ([#1501](https://github.com/kedacore/http-add-on/issues/1501))
3535

3636
### Improvements
3737

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
---
2+
apiVersion: apiextensions.k8s.io/v1
3+
kind: CustomResourceDefinition
4+
metadata:
5+
annotations:
6+
controller-gen.kubebuilder.io/version: v0.19.0
7+
name: interceptorroutes.http.keda.sh
8+
spec:
9+
group: http.keda.sh
10+
names:
11+
kind: InterceptorRoute
12+
listKind: InterceptorRouteList
13+
plural: interceptorroutes
14+
singular: interceptorroute
15+
scope: Namespaced
16+
versions:
17+
- additionalPrinterColumns:
18+
- jsonPath: .spec.target.service
19+
name: TargetService
20+
type: string
21+
- jsonPath: .status.conditions[?(@.type=="Ready")].status
22+
name: Ready
23+
type: string
24+
- jsonPath: .metadata.creationTimestamp
25+
name: Age
26+
type: date
27+
name: v1beta1
28+
schema:
29+
openAPIV3Schema:
30+
description: InterceptorRoute configures request routing and autoscaling for
31+
a target service.
32+
properties:
33+
apiVersion:
34+
description: |-
35+
APIVersion defines the versioned schema of this representation of an object.
36+
Servers should convert recognized schemas to the latest internal value, and
37+
may reject unrecognized values.
38+
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
39+
type: string
40+
kind:
41+
description: |-
42+
Kind is a string value representing the REST resource this object represents.
43+
Servers may infer this from the endpoint the client submits requests to.
44+
Cannot be updated.
45+
In CamelCase.
46+
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
47+
type: string
48+
metadata:
49+
type: object
50+
spec:
51+
description: InterceptorRouteSpec defines the desired state of InterceptorRoute.
52+
properties:
53+
coldStart:
54+
description: Cold start behavior when scaling from zero.
55+
properties:
56+
fallback:
57+
description: |-
58+
Fallback service to route to when the target is scaling from zero
59+
and the wait timeout expires.
60+
properties:
61+
port:
62+
description: Port number on the Service. Mutually exclusive
63+
with portName.
64+
format: int32
65+
maximum: 65535
66+
minimum: 1
67+
type: integer
68+
portName:
69+
description: Named port on the Service. Mutually exclusive
70+
with port.
71+
minLength: 1
72+
type: string
73+
service:
74+
description: Name of the Kubernetes Service.
75+
minLength: 1
76+
type: string
77+
required:
78+
- service
79+
type: object
80+
x-kubernetes-validations:
81+
- message: exactly one of 'port' or 'portName' must be set
82+
rule: has(self.port) != has(self.portName)
83+
required:
84+
- fallback
85+
type: object
86+
x-kubernetes-validations:
87+
- message: '''fallback'' must be set'
88+
rule: has(self.fallback)
89+
rules:
90+
description: Routing rules that define how requests are matched to
91+
this target.
92+
items:
93+
description: RoutingRule defines a set of matching criteria for
94+
routing requests.
95+
properties:
96+
headers:
97+
description: |-
98+
All listed headers must match the request (AND semantics).
99+
If a header's Value is omitted, the header must be present but any
100+
value is accepted.
101+
items:
102+
description: HeaderMatch defines a header matching rule.
103+
properties:
104+
name:
105+
description: Name of the HTTP header.
106+
minLength: 1
107+
type: string
108+
value:
109+
description: Value to match against (exact match). If
110+
omitted, matches any value for given header name.
111+
type: string
112+
required:
113+
- name
114+
type: object
115+
type: array
116+
x-kubernetes-list-map-keys:
117+
- name
118+
x-kubernetes-list-type: map
119+
hosts:
120+
description: |-
121+
Match any of these hostnames. Wildcard patterns (e.g. "*.example.com")
122+
are supported. A single "*" acts as a catch-all. Exact matches take
123+
priority over wildcards; more specific wildcards (e.g. "*.bar.example.com")
124+
take priority over less specific ones.
125+
items:
126+
type: string
127+
type: array
128+
x-kubernetes-list-type: set
129+
paths:
130+
description: |-
131+
Match any of these path prefixes. When multiple paths match,
132+
the longest prefix wins.
133+
items:
134+
description: PathMatch defines a path matching rule.
135+
properties:
136+
value:
137+
description: Path prefix to match against. The longest
138+
matching prefix wins.
139+
minLength: 1
140+
type: string
141+
required:
142+
- value
143+
type: object
144+
type: array
145+
x-kubernetes-list-type: atomic
146+
type: object
147+
type: array
148+
x-kubernetes-list-type: atomic
149+
scalingMetric:
150+
description: Metric configuration for autoscaling.
151+
properties:
152+
concurrency:
153+
description: Scale based on concurrent request count.
154+
properties:
155+
targetValue:
156+
default: 100
157+
description: Target concurrent request count per replica.
158+
format: int32
159+
minimum: 1
160+
type: integer
161+
type: object
162+
requestRate:
163+
description: Scale based on request rate.
164+
properties:
165+
granularity:
166+
default: 1s
167+
description: Bucket size for rate calculation within the window.
168+
type: string
169+
targetValue:
170+
default: 100
171+
description: Target request rate per replica.
172+
format: int32
173+
minimum: 1
174+
type: integer
175+
window:
176+
default: 1m
177+
description: Sliding time window over which the request rate
178+
is calculated.
179+
type: string
180+
type: object
181+
type: object
182+
x-kubernetes-validations:
183+
- message: at least one of 'concurrency' or 'requestRate' must be
184+
set
185+
rule: has(self.concurrency) || has(self.requestRate)
186+
target:
187+
description: Backend service to route traffic to.
188+
properties:
189+
port:
190+
description: Port number on the Service. Mutually exclusive with
191+
portName.
192+
format: int32
193+
maximum: 65535
194+
minimum: 1
195+
type: integer
196+
portName:
197+
description: Named port on the Service. Mutually exclusive with
198+
port.
199+
minLength: 1
200+
type: string
201+
service:
202+
description: Name of the Kubernetes Service.
203+
minLength: 1
204+
type: string
205+
required:
206+
- service
207+
type: object
208+
x-kubernetes-validations:
209+
- message: exactly one of 'port' or 'portName' must be set
210+
rule: has(self.port) != has(self.portName)
211+
required:
212+
- scalingMetric
213+
- target
214+
type: object
215+
status:
216+
description: InterceptorRouteStatus defines the observed state of InterceptorRoute.
217+
properties:
218+
conditions:
219+
description: Conditions of the InterceptorRoute.
220+
items:
221+
description: Condition contains details for one aspect of the current
222+
state of this API Resource.
223+
properties:
224+
lastTransitionTime:
225+
description: |-
226+
lastTransitionTime is the last time the condition transitioned from one status to another.
227+
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
228+
format: date-time
229+
type: string
230+
message:
231+
description: |-
232+
message is a human readable message indicating details about the transition.
233+
This may be an empty string.
234+
maxLength: 32768
235+
type: string
236+
observedGeneration:
237+
description: |-
238+
observedGeneration represents the .metadata.generation that the condition was set based upon.
239+
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
240+
with respect to the current state of the instance.
241+
format: int64
242+
minimum: 0
243+
type: integer
244+
reason:
245+
description: |-
246+
reason contains a programmatic identifier indicating the reason for the condition's last transition.
247+
Producers of specific condition types may define expected values and meanings for this field,
248+
and whether the values are considered a guaranteed API.
249+
The value should be a CamelCase string.
250+
This field may not be empty.
251+
maxLength: 1024
252+
minLength: 1
253+
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
254+
type: string
255+
status:
256+
description: status of the condition, one of True, False, Unknown.
257+
enum:
258+
- "True"
259+
- "False"
260+
- Unknown
261+
type: string
262+
type:
263+
description: type of condition in CamelCase or in foo.example.com/CamelCase.
264+
maxLength: 316
265+
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
266+
type: string
267+
required:
268+
- lastTransitionTime
269+
- message
270+
- reason
271+
- status
272+
- type
273+
type: object
274+
type: array
275+
x-kubernetes-list-map-keys:
276+
- type
277+
x-kubernetes-list-type: map
278+
type: object
279+
required:
280+
- metadata
281+
- spec
282+
type: object
283+
served: true
284+
storage: true
285+
subresources:
286+
status: {}

config/crd/kustomization.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ apiVersion: kustomize.config.k8s.io/v1beta1
22
kind: Kustomization
33
resources:
44
- bases/http.keda.sh_httpscaledobjects.yaml
5+
- bases/http.keda.sh_interceptorroutes.yaml
56
#+kubebuilder:scaffold:crdkustomizeresource
67
labels:
78
- includeSelectors: false

config/interceptor/role.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ rules:
2424
- http.keda.sh
2525
resources:
2626
- httpscaledobjects
27+
- interceptorroutes
2728
verbs:
2829
- get
2930
- list

config/operator/role.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ rules:
88
- http.keda.sh
99
resources:
1010
- httpscaledobjects
11+
- interceptorroutes
1112
verbs:
1213
- create
1314
- delete
@@ -20,12 +21,14 @@ rules:
2021
- http.keda.sh
2122
resources:
2223
- httpscaledobjects/finalizers
24+
- interceptorroutes/finalizers
2325
verbs:
2426
- update
2527
- apiGroups:
2628
- http.keda.sh
2729
resources:
2830
- httpscaledobjects/status
31+
- interceptorroutes/status
2932
verbs:
3033
- get
3134
- patch

config/scaler/role.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ rules:
1616
- http.keda.sh
1717
resources:
1818
- httpscaledobjects
19+
- interceptorroutes
1920
verbs:
2021
- get
2122
- list

docs/developing.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ ko builds Go binaries and packages them into container images without requiring
5555

5656
Set the `KO_DOCKER_REPO` environment variable for your target:
5757

58-
- **KinD:** `export KO_DOCKER_REPO=kind.local`
59-
- **Local registry:** `export KO_DOCKER_REPO=localhost:5001`
58+
- **Local registry:** `export KO_DOCKER_REPO=localhost:<port>`
59+
- **KinD:** `export KO_DOCKER_REPO=kind.local` (only works with Docker, not Podman)
6060

6161
After making code changes, deploy a single component:
6262

interceptor/forward_wait_func.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88

99
// forwardWaitFunc is a function that waits for a condition
1010
// before proceeding to serve the request.
11-
type forwardWaitFunc func(context.Context, string, string) (bool, error)
11+
type forwardWaitFunc func(ctx context.Context, namespace string, serviceName string) (bool, error)
1212

1313
func newWorkloadReplicasForwardWaitFunc(
1414
readyCache *k8s.ReadyEndpointsCache,

0 commit comments

Comments
 (0)