Skip to content

Commit f53ffeb

Browse files
damianr13sketch
andcommitted
feat: add configurable service endpoint path for RestateDeployment
- Add optional service_path field to RestateSpec for custom endpoint paths - Update controller logic to use validated service path when registering with Restate - Default behavior unchanged: services register at root path '/' if not specified - Add path validation ensuring paths start with '/' and don't end with '/' (except root) - Update CRD schema and documentation with examples - Add comprehensive unit tests for path validation and endpoint construction Co-Authored-By: sketch <hello@sketch.dev> Change-ID: s114ac83524847582k (cherry picked from commit 53adb341dd10fb201a7dfe4327180403e9b28138)
1 parent 0dd8cfa commit f53ffeb

4 files changed

Lines changed: 267 additions & 73 deletions

File tree

README.md

Lines changed: 75 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -88,80 +88,80 @@ More examples are available just below the spec that follows.
8888

8989
#### Spec Fields
9090

91-
| Field | Type | Description |
92-
|---|---|---|
93-
| `compute` | `object` | Compute configuration. See details below. |
94-
| `storage` | `object` | Storage configuration. See details below. |
95-
| `security` | `object` | Security configuration. See details below. |
96-
| `config` | `string` | TOML-encoded Restate config file. See details below. |
91+
| Field | Type | Description |
92+
| ------------- | -------- | ---------------------------------------------------------------------------------- |
93+
| `compute` | `object` | Compute configuration. See details below. |
94+
| `storage` | `object` | Storage configuration. See details below. |
95+
| `security` | `object` | Security configuration. See details below. |
96+
| `config` | `string` | TOML-encoded Restate config file. See details below. |
9797
| `clusterName` | `string` | Sets the `RESTATE_CLUSTER_NAME` environment variable. Defaults to the object name. |
9898

9999
---
100100

101101
#### `spec.compute`
102102

103-
| Field | Type | Description |
104-
|---|---|---|
105-
| `replicas` | `integer` | The desired number of Restate nodes. Defaults to 1. |
106-
| `image` | `string` | **Required**. Container image name. |
107-
| `imagePullPolicy` | `string` | Image pull policy. One of `Always`, `Never`, `IfNotPresent`. Defaults to `Always` if `:latest` tag is specified, or `IfNotPresent` otherwise. |
108-
| `resources` | `object` | Compute Resources for the Restate container. e.g., `requests` and `limits` for `cpu` and `memory`. |
109-
| `env` | `array` | List of environment variables to set in the container. |
110-
| `affinity` | `object` | Standard Kubernetes affinity rules. |
111-
| `nodeSelector` | `object` | Standard Kubernetes node selector. |
112-
| `tolerations` | `array` | Standard Kubernetes tolerations. |
113-
| `dnsPolicy` | `string` | Pod DNS policy. |
114-
| `dnsConfig` | `object` | Pod DNS configuration. |
103+
| Field | Type | Description |
104+
| ----------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
105+
| `replicas` | `integer` | The desired number of Restate nodes. Defaults to 1. |
106+
| `image` | `string` | **Required**. Container image name. |
107+
| `imagePullPolicy` | `string` | Image pull policy. One of `Always`, `Never`, `IfNotPresent`. Defaults to `Always` if `:latest` tag is specified, or `IfNotPresent` otherwise. |
108+
| `resources` | `object` | Compute Resources for the Restate container. e.g., `requests` and `limits` for `cpu` and `memory`. |
109+
| `env` | `array` | List of environment variables to set in the container. |
110+
| `affinity` | `object` | Standard Kubernetes affinity rules. |
111+
| `nodeSelector` | `object` | Standard Kubernetes node selector. |
112+
| `tolerations` | `array` | Standard Kubernetes tolerations. |
113+
| `dnsPolicy` | `string` | Pod DNS policy. |
114+
| `dnsConfig` | `object` | Pod DNS configuration. |
115115

116116
---
117117

118118
#### `spec.storage`
119119

120-
| Field | Type | Description |
121-
|---|---|---|
120+
| Field | Type | Description |
121+
| --------------------- | --------- | ------------------------------------------------------------------------------------------------ |
122122
| `storageRequestBytes` | `integer` | **Required**. Amount of storage to request in volume claims. Can be increased but not decreased. |
123-
| `storageClassName` | `string` | The name of the `StorageClass` for the volume claims. This field is immutable. |
123+
| `storageClassName` | `string` | The name of the `StorageClass` for the volume claims. This field is immutable. |
124124

125125
---
126126

127127
#### `spec.security`
128128

129-
| Field | Type | Description |
130-
|---|---|---|
131-
| `disableNetworkPolicies` | `boolean` | If `true`, the operator will not create any network policies. Defaults to `false`. |
132-
| `allowOperatorAccessToAdmin` | `boolean` | If `true`, adds a rule to allow the operator to access the admin API. Needed for `RestateDeployment`. Defaults to `true`. |
133-
| `networkPeers` | `object` | Defines network peers to allow inbound access to `admin`, `ingress`, and `metrics` ports. |
134-
| `networkEgressRules` | `array` | Custom egress rules for outbound traffic from the cluster. |
135-
| `serviceAccountAnnotations` | `object` | Annotations to add to the `ServiceAccount`. |
136-
| `serviceAnnotations`| `object` | Annotations to add to the `Service`. |
137-
| `awsPodIdentityAssociationRoleArn` | `string` | **Use this to grant your Restate cluster fine-grained access to other AWS resources (like S3) without managing static credentials.** Creates a `PodIdentityAssociation` to grant the cluster an IAM role. Requires the ACK EKS controller. |
138-
| `awsPodSecurityGroups` | `array` | **Use this to isolate your Restate cluster within specific AWS Security Groups for enhanced network control and auditing.** Creates a `SecurityGroupPolicy` to place pods into these security groups. Requires the Security Groups for Pods CRD. |
139-
| `requestSigningPrivateKey` | `object` | Configures a private key to sign outbound requests from this cluster. Can be sourced from a `secret` or a CSI `secretProvider`. See details below. |
129+
| Field | Type | Description |
130+
| ---------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
131+
| `disableNetworkPolicies` | `boolean` | If `true`, the operator will not create any network policies. Defaults to `false`. |
132+
| `allowOperatorAccessToAdmin` | `boolean` | If `true`, adds a rule to allow the operator to access the admin API. Needed for `RestateDeployment`. Defaults to `true`. |
133+
| `networkPeers` | `object` | Defines network peers to allow inbound access to `admin`, `ingress`, and `metrics` ports. |
134+
| `networkEgressRules` | `array` | Custom egress rules for outbound traffic from the cluster. |
135+
| `serviceAccountAnnotations` | `object` | Annotations to add to the `ServiceAccount`. |
136+
| `serviceAnnotations` | `object` | Annotations to add to the `Service`. |
137+
| `awsPodIdentityAssociationRoleArn` | `string` | **Use this to grant your Restate cluster fine-grained access to other AWS resources (like S3) without managing static credentials.** Creates a `PodIdentityAssociation` to grant the cluster an IAM role. Requires the ACK EKS controller. |
138+
| `awsPodSecurityGroups` | `array` | **Use this to isolate your Restate cluster within specific AWS Security Groups for enhanced network control and auditing.** Creates a `SecurityGroupPolicy` to place pods into these security groups. Requires the Security Groups for Pods CRD. |
139+
| `requestSigningPrivateKey` | `object` | Configures a private key to sign outbound requests from this cluster. Can be sourced from a `secret` or a CSI `secretProvider`. See details below. |
140140

141141
---
142142

143143
#### `spec.security.requestSigningPrivateKey`
144144

145-
| Field | Type | Description |
146-
|---|---|---|
147-
| `version` | `string` | **Required**. The version of Restate request signing. Currently, only "v1" is accepted. |
148-
| `secret` | `object` | A Kubernetes Secret source for the private key. |
149-
| `secretProvider` | `object` | A CSI secret provider source for the private key. |
145+
| Field | Type | Description |
146+
| ---------------- | -------- | --------------------------------------------------------------------------------------- |
147+
| `version` | `string` | **Required**. The version of Restate request signing. Currently, only "v1" is accepted. |
148+
| `secret` | `object` | A Kubernetes Secret source for the private key. |
149+
| `secretProvider` | `object` | A CSI secret provider source for the private key. |
150150

151151
**`secret` Fields**
152152

153-
| Field | Type | Description |
154-
|---|---|---|
155-
| `secretName` | `string` | **Required**. The name of the secret. |
156-
| `key` | `string` | **Required**. The key within the secret that contains the private key. |
153+
| Field | Type | Description |
154+
| ------------ | -------- | ---------------------------------------------------------------------- |
155+
| `secretName` | `string` | **Required**. The name of the secret. |
156+
| `key` | `string` | **Required**. The key within the secret that contains the private key. |
157157

158158
**`secretProvider` Fields**
159159

160-
| Field | Type | Description |
161-
|---|---|---|
162-
| `provider` | `string` | The name of the CSI secret provider (e.g., `secrets-store.csi.k8s.io`). |
163-
| `path` | `string` | **Required**. The path of the private key file within the mounted volume. |
164-
| `parameters` | `object` | Provider-specific configuration parameters. |
160+
| Field | Type | Description |
161+
| ------------ | -------- | ------------------------------------------------------------------------- |
162+
| `provider` | `string` | The name of the CSI secret provider (e.g., `secrets-store.csi.k8s.io`). |
163+
| `path` | `string` | **Required**. The path of the private key file within the mounted volume. |
164+
| `parameters` | `object` | Provider-specific configuration parameters. |
165165

166166
---
167167

@@ -307,6 +307,9 @@ spec:
307307
restate:
308308
register:
309309
cluster: restate-test
310+
# Optional: specify a custom path for service registration
311+
# If not provided, service will be registered at root path "/"
312+
service_path: "/api/v1"
310313
selector:
311314
matchLabels:
312315
app: my-deployment
@@ -326,25 +329,25 @@ For the full schema as a [Pkl](https://pkl-lang.org/) template see [`crd/Restate
326329

327330
#### Spec Fields
328331

329-
| Field | Type | Description |
330-
|---|---|---|
331-
| `replicas` | `integer` | Number of desired pods. Defaults to 1. |
332-
| `selector` | `object` | **Required**. Label selector for pods. Must match the pod template's labels. See details below. |
333-
| `template` | `object` | **Required**. Pod template for the deployment. See details below. |
334-
| `restate` | `object` | **Required**. Restate-specific configuration. See details below. |
335-
| `minReadySeconds` | `integer` | Minimum seconds a new pod should be ready before it's considered available. Defaults to 0. |
336-
| `revisionHistoryLimit`| `integer` | Number of old ReplicaSets to retain for rollbacks. Defaults to 10. |
332+
| Field | Type | Description |
333+
| ---------------------- | --------- | ----------------------------------------------------------------------------------------------- |
334+
| `replicas` | `integer` | Number of desired pods. Defaults to 1. |
335+
| `selector` | `object` | **Required**. Label selector for pods. Must match the pod template's labels. See details below. |
336+
| `template` | `object` | **Required**. Pod template for the deployment. See details below. |
337+
| `restate` | `object` | **Required**. Restate-specific configuration. See details below. |
338+
| `minReadySeconds` | `integer` | Minimum seconds a new pod should be ready before it's considered available. Defaults to 0. |
339+
| `revisionHistoryLimit` | `integer` | Number of old ReplicaSets to retain for rollbacks. Defaults to 10. |
337340

338341
---
339342

340343
#### `spec.selector`
341344

342345
This is a standard Kubernetes [label selector](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors). It must match the labels of the pod template.
343346

344-
| Field | Type | Description |
345-
|---|---|---|
346-
| `matchLabels` | `object` | A map of key-value pairs. |
347-
| `matchExpressions` | `array` | A list of label selector requirements. |
347+
| Field | Type | Description |
348+
| ------------------ | -------- | -------------------------------------- |
349+
| `matchLabels` | `object` | A map of key-value pairs. |
350+
| `matchExpressions` | `array` | A list of label selector requirements. |
348351

349352
---
350353

@@ -360,26 +363,27 @@ For details on the `PodTemplateSpec` schema, see the [official Kubernetes API do
360363

361364
This field contains Restate-specific configuration.
362365

363-
| Field | Type | Description |
364-
|---|---|---|
365-
| `register` | `object` | **Required**. The location of the Restate Admin API to register this deployment against. See details below. |
366+
| Field | Type | Description |
367+
| -------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
368+
| `register` | `object` | **Required**. The location of the Restate Admin API to register this deployment against. See details below. |
369+
| `service_path` | `string` | Optional path to append to the service endpoint when registering with Restate. If not provided, the service will be registered at the root path "/". Path must start with "/" and should not end with "/". |
366370

367371
The `register` field must specify exactly one of `cluster`, `service`, or `url`.
368372

369-
| Field | Type | Description |
370-
|---|---|---|
371-
| `cluster` | `string` | The name of a `RestateCluster` CRD object in the same Kubernetes cluster. |
373+
| Field | Type | Description |
374+
| --------- | -------- | ---------------------------------------------------------------------------------------------- |
375+
| `cluster` | `string` | The name of a `RestateCluster` CRD object in the same Kubernetes cluster. |
372376
| `service` | `object` | A reference to a Kubernetes `Service` that points to the Restate admin API. See details below. |
373-
| `url` | `string` | The direct URL of the Restate admin endpoint. |
377+
| `url` | `string` | The direct URL of the Restate admin endpoint. |
374378

375379
**`register.service` Fields**
376380

377-
| Field | Type | Description |
378-
|---|---|---|
379-
| `name` | `string` | **Required**. The name of the service. |
380-
| `namespace` | `string` | **Required**. The namespace of the service. |
381-
| `path` | `string` | An optional URL path to be prepended to admin API paths. Should not end with a `/`. |
382-
| `port` | `integer` | The port on the service that hosts the admin API. Defaults to 9070. |
381+
| Field | Type | Description |
382+
| ----------- | --------- | ----------------------------------------------------------------------------------- |
383+
| `name` | `string` | **Required**. The name of the service. |
384+
| `namespace` | `string` | **Required**. The namespace of the service. |
385+
| `path` | `string` | An optional URL path to be prepended to admin API paths. Should not end with a `/`. |
386+
| `port` | `integer` | The port on the service that hosts the admin API. Defaults to 9070. |
383387

384388
### EKS Pod Identity
385389

crd/restatedeployments.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ metadata:
55
spec:
66
group: restate.dev
77
names:
8+
categories: []
89
kind: RestateDeployment
910
plural: restatedeployments
1011
shortNames:
@@ -104,6 +105,10 @@ spec:
104105
description: A url of the restate admin endpoint against which to register the deployment Exactly one of `cluster`, `service` or `url` must be specified
105106
type: string
106107
type: object
108+
service_path:
109+
description: Optional path to append to the service endpoint when registering with Restate. If not provided, the service will be registered at the root path "/". Path must start with "/" and should not end with "/".
110+
nullable: true
111+
type: string
107112
required:
108113
- register
109114
type: object

src/controllers/restatedeployment/controller.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,11 @@ impl RestateDeployment {
277277
)
278278
.await?;
279279

280-
let service_endpoint =
281-
format!("http://{versioned_name}.{namespace}.svc.cluster.local:9080/");
280+
// Get the validated service path
281+
let service_path = self.spec.restate.validated_service_path()?;
282+
let service_endpoint = format!(
283+
"http://{versioned_name}.{namespace}.svc.cluster.local:9080{service_path}"
284+
);
282285

283286
let mut endpoints = self
284287
.list_endpoints(&ctx.http_client, &admin_endpoint)

0 commit comments

Comments
 (0)