Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@

All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). The format is based on [Keep a Changelog](http://keepachangelog.com/).

## Version 0.16.0 - 18-May-2026

### Added

- Added `SubscriptionDependencyMode` support (`Auto`, `Always`, `Never`) to `serviceInstances` in `values.schema.json`.
- Added `startupProbe` field to workload definitions in `values.schema.json`.

### Changed

- Updated `getDependencies` and `dependenciesCallbacks` URLs in `runtime-values.yaml` to use the CAP Operator-managed endpoints (`/dependencies/{{providerSubaccountId}}/{{appName}}`), replacing the previous approuter callback URLs.
- Removed optional mutual TLS (`OptionalMutual`) configuration; TLS mode is now always set to `Simple`.
- Removed `sme.sap.com/vs-route-request-header-set` (`x-forwarded-client-cert`) annotation from CAPApplication templates.
- Improved validation logic for `appName` field during `runtime-values.yaml` generation.
- Simplified `Duration` type in `values.schema.json` from a nested object to a plain string.

## Version 0.15.0 - 29-April-2026

### Changed
Expand Down
78 changes: 43 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,41 +110,49 @@ To integrate the CAP Operator Plugin into your project, follow these steps:

## Configure Your Chart

The generated `chart/values.yaml` contains two types of information:

* Design-time deployment
* Without option `--with-configurable-templates`
- [serviceInstances](https://github.com/SAP/sap-btp-service-operator?tab=readme-ov-file#service-instance)
- [serviceBindings](https://github.com/SAP/sap-btp-service-operator?tab=readme-ov-file#service-binding)
- workloads - There are two types of workloads:
- [Deployment definition](https://sap.github.io/cap-operator/docs/usage/resources/capapplicationversion/#workloads-with-deploymentdefinition)
- [Job definition](https://sap.github.io/cap-operator/docs/usage/resources/capapplicationversion/#workloads-with-jobdefinition)
- [tenantOperations](https://sap.github.io/cap-operator/docs/usage/resources/capapplicationversion/#sequencing-tenant-operations)
- [contentJobs](https://sap.github.io/cap-operator/docs/usage/resources/capapplicationversion/#sequencing-content-jobs)
* With option `--with-configurable-templates`
- [serviceInstances](https://github.com/SAP/sap-btp-service-operator?tab=readme-ov-file#service-instance)
- [serviceBindings](https://github.com/SAP/sap-btp-service-operator?tab=readme-ov-file#service-binding)
- workloads - With this option all the workload configuations are maintained in `templates/cap-operator-cros.yaml` and in the `values.yaml` you can only define the images for the workloads.

* Runtime deployment
- app
- Primary - Primary application domain is used to generate a wildcard TLS certificate. In clusters managed by project "Gardener", this is (usually) a subdomain of the cluster domain
- Secondary ***[DEPRECATED with v0.7.0]*** - Customer-specific domains to serve application endpoints (optional). Use `additionalDomainRefs` instead.
- additionalDomainRefs - References to exisiting customer specific `Domains` or `ClusterDomain` resources. For details, refer to the [CAP Operator documentation](https://sap.github.io/cap-operator/docs/usage/domain-management).
- IstioIngressGatewayLabels - Labels used to identify the Istio ingress-gateway component and its corresponding namespace. Usually {“app”:“istio-ingressgateway”,“istio”:“ingressgateway”}
- btp
- Subdomain - Subdomain of the provider subaccount to which you deploy the application. This is not required for services-only applications.
- TenantId - Tenant ID of the provider subaccount to which you deploy the application. This is not required for services-only applications.
- [imagePullSecrets](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) - Kubernetes secret used to pull the application docker images from a private container image registry or repository.
- env information inside workloads

As a developer, you must fill in the design-time deployment information in the `values.yaml` file, which can then be pushed to your GitHub repository. The plugin auto-populates some values based on your project configuration, but verifying them and manually filling in any missing information is essential. You can refer to `values.schema.json` file for the structure of the `values.yaml` file.

**Please fill the `values.yaml` according to the schema as it is tightly coupled to the predefined templates.** You can use a YAML schema validation extension such as [YAML](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml) or run the following command to validate your `values.yaml` file. You can ignore the errors from runtime values as they are not filled in yet.
The generated `chart/values.yaml` contains two categories of values: **design-time** and **runtime**.

**Design-time values** describe your application's services and workloads. They are stable across environments and can be committed to your repository. The plugin auto-populates many of these from your project configuration, but you should verify them and fill in any gaps.

Depending on whether you used `--with-configurable-templates`, the design-time section contains:

- Basic chart (default):
- [serviceInstances](https://github.com/SAP/sap-btp-service-operator?tab=readme-ov-file#service-instance) (enhanced with [`subscriptionDependency`](https://sap.github.io/cap-operator/docs/usage/tenant-provisioning/#configuring-dependencies-with-subscriptiondependency) parameter)
- [serviceBindings](https://github.com/SAP/sap-btp-service-operator?tab=readme-ov-file#service-binding)
- workloads ([Deployment](https://sap.github.io/cap-operator/docs/usage/resources/capapplicationversion/#workloads-with-deploymentdefinition) or [Job](https://sap.github.io/cap-operator/docs/usage/resources/capapplicationversion/#workloads-with-jobdefinition) definitions)
- [tenantOperations](https://sap.github.io/cap-operator/docs/usage/resources/capapplicationversion/#sequencing-tenant-operations)
- [contentJobs](https://sap.github.io/cap-operator/docs/usage/resources/capapplicationversion/#sequencing-content-jobs)
- [serviceExposures](https://sap.github.io/cap-operator/docs/usage/resources/capapplicationversion/#serviceexposures-configuration)

- Configurable templates chart (`--with-configurable-templates`):
- [serviceInstances](https://github.com/SAP/sap-btp-service-operator?tab=readme-ov-file#service-instance) (enhanced with [`subscriptionDependency`](https://sap.github.io/cap-operator/docs/usage/tenant-provisioning/#configuring-dependencies-with-subscriptiondependency) parameter)
- [serviceBindings](https://github.com/SAP/sap-btp-service-operator?tab=readme-ov-file#service-binding)
- workload images only — full workload configurations are defined in `templates/cap-operator-cros.yaml`

**Runtime values** are environment-specific and must be provided separately at deploy time (see [Deploy Your Application](#deploy-your-application)). They include:

- `app`
- `domains`
- `primary` — Primary application domain, used to generate a wildcard TLS certificate. In Gardener-managed clusters, this is typically a subdomain of the cluster domain.
- `additionalDomainRefs` — References to existing customer-specific `Domain` or `ClusterDomain` resources. See the [Domain Management](https://sap.github.io/cap-operator/docs/usage/domain-management) for details.
- `istioIngressGatewayLabels` — Labels identifying the Istio ingress-gateway and its namespace. Typically `{“app”:”istio-ingressgateway”,”istio”:”ingressgateway”}`.
- `enableCleanupMonitoring` — Enable monitoring for cleanup operations.
- `btp`
- `providerSubaccountId` — ID of the provider subaccount to which you deploy the application.
- `provider`
- `subdomain` — Subdomain of the provider subaccount. Not required for services-only applications.
- `tenantId` — Tenant ID of the provider subaccount. Not required for services-only applications.
- [imagePullSecrets](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) — Kubernetes secret for pulling images from a private registry.
- `env` — Environment variables defined inside individual workloads.

> The `values.yaml` is tightly coupled to the predefined templates, so it must conform to `values.schema.json`. You can validate it with the [YAML extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml) or by running:
>
> ```sh
> helm lint <chart-path>
> ```
>
> You can ignore validation errors for runtime values, as those are filled in later.

```sh
helm lint <chart-path>
```
## Deploy Your Application

1. You must generate the final Helm chart before deploying your application. You can do so by running `cds build`. During the build, the plugin generates the final Helm chart in your project's `gen` directory, which includes the predefined `templates` folder.
Expand All @@ -157,7 +165,7 @@ The generated `chart/values.yaml` contains two types of information:

The plugin requires the following information to generate the `runtime-values.yaml`:

* **Application name (appName) *[Mandatory]***
* **Application name (appName) *[Mandatory]*** - Must consist of lowercase alphanumeric characters and hyphens only (`^[a-z0-9-]+$`). This value is used as `xsappname` in the saas-registry which have the same restriction.
* **CAP Operator subdomain (capOperatorSubdomain) *[Mandatory]*** - In Kyma clusters, CAP Operator subdomain defaults to `cap-op`. But if you're using your "Gardener" cluster, you must provide the subdomain you used to install the CAP Operator.
* **Cluster shoot domain (clusterDomain) *[Mandatory]*** - Shoot domain of your cluster. In Kyma clusters, you can get the shoot domain by running the following command.
```sh
Expand Down
7 changes: 6 additions & 1 deletion bin/cap-op-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,14 @@ async function generateRuntimeValues(option, inputYamlPath) {
throw new Error(`Missing mandatory fields in the input yaml file: ${missingFields.join(', ')}`)
}

if (!isServiceOnly && !/^[a-z0-9-]+$/.test(answerStruct['appName']?.trim())) {
throw new Error(`Invalid app name '${answerStruct['appName']}': only a-z, 0-9 and - are allowed`)
}

} else {
const appNameValidator = !isServiceOnly ? (value) => /^[a-z0-9-]+$/.test(value?.trim()) || 'Only a-z, 0-9 and - are allowed' : undefined
Comment thread
anirudhprasad-sap marked this conversation as resolved.
const questions = [
['Enter app name for deployment', appName, true],
['Enter app name for deployment', appName, true, appNameValidator],
['Enter CAP Operator subdomain (In kyma cluster it is "cap-op" by default)', 'cap-op', true],
['Enter your cluster shoot domain', await getShootDomain(), true],
['Enter your provider sub-account ID', '', true],
Expand Down
53 changes: 21 additions & 32 deletions files/chart/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,9 @@
"serviceAccountName": {
"type": "string"
},
"startupProbe": {
"$ref": "#/$defs/Probe"
},
"stickiness": {
"$ref": "#/$defs/Stickiness"
},
Expand Down Expand Up @@ -745,16 +748,7 @@
"type": "object"
},
"Duration": {
"additionalProperties": false,
"properties": {
"Duration": {
"$ref": "#/$defs/Duration"
}
},
"required": [
"Duration"
],
"type": "object"
"type": "string"
},
"EmptyDirVolumeSource": {
"additionalProperties": false,
Expand Down Expand Up @@ -893,8 +887,7 @@
"type": "object"
},
"FieldsV1": {
"additionalProperties": false,
"properties": {},
"additionalProperties": true,
"type": "object"
},
"FileKeySelector": {
Expand Down Expand Up @@ -1249,24 +1242,14 @@
"type": "object"
},
"IntOrString": {
"additionalProperties": false,
"properties": {
"IntVal": {
"anyOf": [
{
"type": "integer"
},
"StrVal": {
{
"type": "string"
},
"Type": {
"type": "integer"
}
},
"required": [
"Type",
"IntVal",
"StrVal"
],
"type": "object"
]
},
"JobDetails": {
"additionalProperties": false,
Expand Down Expand Up @@ -2774,9 +2757,7 @@
"type": "object"
},
"Time": {
"additionalProperties": false,
"properties": {},
"type": "object"
"type": "string"
},
"Toleration": {
"additionalProperties": false,
Expand Down Expand Up @@ -3199,6 +3180,9 @@
"domains": {
"$ref": "#/$defs/Domains"
},
"enableCleanupMonitoring": {
"type": "boolean"
},
"istioIngressGatewayLabels": {
"additionalProperties": {
"type": "string"
Expand All @@ -3207,9 +3191,6 @@
},
"version": {
"type": "string"
},
"enableCleanupMonitoring": {
"type": "boolean"
}
},
"required": [
Expand Down Expand Up @@ -3403,6 +3384,14 @@
"shared": {
"type": "boolean"
},
"subscriptionDependency": {
"enum": [
"Auto",
"Always",
"Never"
],
"type": "string"
},
"userInfo": {
"$ref": "#/$defs/UserInfo"
},
Expand Down
14 changes: 11 additions & 3 deletions files/configurableTemplatesChart/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@
"domains": {
"$ref": "#/$defs/Domains"
},
"enableCleanupMonitoring": {
"type": "boolean"
},
"istioIngressGatewayLabels": {
"additionalProperties": {
"type": "string"
Expand All @@ -130,9 +133,6 @@
},
"version": {
"type": "string"
},
"enableCleanupMonitoring": {
"type": "boolean"
}
},
"required": [
Expand Down Expand Up @@ -314,6 +314,14 @@
"shared": {
"type": "boolean"
},
"subscriptionDependency": {
"enum": [
"Auto",
"Always",
"Never"
],
"type": "string"
},
"userInfo": {
"$ref": "#/$defs/UserInfo"
},
Expand Down
9 changes: 2 additions & 7 deletions files/runtime-values.yaml.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,7 @@ serviceInstances:
displayName: {{appName}}
description: {{appDescription}}
appUrls:
{{#isApp}}
getDependencies: "https://{{providerSubdomain}}.{{appName}}.{{clusterDomain}}/callback/v1.0/dependencies"
{{/isApp}}
{{#isService}}
getDependencies: "https://{{appName}}.{{clusterDomain}}/callback/v1.0/dependencies"
{{/isService}}
getDependencies: "https://{{capOperatorSubdomain}}.{{clusterDomain}}/dependencies/{{providerSubaccountId}}/{{appName}}"
onSubscription: "https://{{capOperatorSubdomain}}.{{clusterDomain}}/provision/tenants/{tenantId}"
{{/isApp}}
{{xsuaaKeyName}}:
Expand All @@ -31,7 +26,7 @@ serviceInstances:
category: CAP
appCallbacks:
dependenciesCallbacks:
url: "https://{{providerSubdomain}}.{{appName}}.{{clusterDomain}}/v1.0/callback/tenants/{app_tid}/dependencies"
url: "https://{{capOperatorSubdomain}}.{{clusterDomain}}/sms/dependencies/{{providerSubaccountId}}/{{appName}}/{app_tid}"
subscriptionCallbacks:
url: "https://{{capOperatorSubdomain}}.{{clusterDomain}}/sms/provision/tenants/{app_tid}"
{{/isApp}}
Expand Down
Loading
Loading