Service Provider erstellen
Mit Codesphere lassen sich bestehende Codesphere-Landscapes als Managed Service Provider veröffentlichen. Dadurch können andere Entwickler eure individuellen Lösungen entdecken und bereitstellen.
Landscape-basierte Service Provider
Ein Landscape-basierter Service Provider ermöglicht es anderen, eure Codesphere-Landscape als vorkonfigurierten Managed Service zu instanziieren, den sie über den Service-Katalog bereitstellen und verwalten können.
info
Für die Veröffentlichung von Providern sind Cluster-Admin-Berechtigungen erforderlich. Team-Admins können beantragen, dass Provider auf bestimmte Teams beschränkt werden.
Voraussetzungen
Bevor ein Landscape-basierter Service Provider erstellt werden kann, wird Folgendes benötigt:
- Ein Git-Repository mit einer gültigen Codesphere-Landscape inklusive
ci.yml-Datei. - Eine Provider-Definition, entweder als
provider.yml-Datei im Repository-Root oder direkt in der API-Anfrage übergeben. - Git-Zugriff auf das Landscape-Repository. Codesphere zieht das Repository über eure Git-Verbindung, daher muss das für die Erstellung des Providers verwendete Konto Zugriffsrechte darauf haben. Git-Verbindungen lassen sich in den Benutzereinstellungen verwalten.
Als Beispiel könnt ihr euch unser öffentliches URL-Shortener-Repository ansehen.
Git-Zugriff ist an einen Benutzer gebunden
Für das Pullen des Landscape-Repositorys wird die Git-Verbindung des Benutzers verwendet, der den Provider erstellt (oder zuletzt aktualisiert) hat. Verliert dieser Benutzer den Zugriff auf das Repository, schlagen Deployments des Providers fehl. Um den Provider auf die Git-Verbindung eines anderen Benutzers zu übertragen, sendet dieser Benutzer eine PUT- oder PATCH-Anfrage für den Provider – anschließend wird dessen Verbindung für das Pullen verwendet. Für langlebige Provider empfiehlt sich die Veröffentlichung mit einem technischen Benutzer.
Provider-Definition
Die Datei provider.yml definiert alle Metadaten und Konfigurationsschemas für euren Service Provider.
name: mattermost
schemaVersion: v1
author: Your Team
displayName: Mattermost
iconUrl: https://example.com/mattermost-icon.png
category: collaboration
description: |
Open-source team messaging and collaboration platform.
Supports channels, direct messaging, and file sharing.
backend:
landscape:
gitUrl: https://github.com/your-org/mattermost-landscape
configSchema:
type: object
properties:
SITE_NAME:
type: string
description: Display name for your Mattermost instance
default: mattermost
readOnly: false
MAX_USERS:
type: integer
description: Maximum number of users allowed
x-update-constraint: increase-only
required: ['MAX_USERS']
secretsSchema:
type: object
properties:
ADMIN_PASSWORD:
type: string
format: password
detailsSchema:
type: object
properties:
hostname:
type: string
port:
type: integer
plans:
# The plan has no influence on the resource usage, so you should only define one.
# You can also set plans to an empty array to disable the plan selection UI.
- id: 0
name: Default Plan
description: Resource usage depends on the ci-profile of the landscape.
parameters: {}
versions:
0.0.1:
ciProfile: debug
# gitRef can be a commit-hash, branch or tag
gitRef: 1a410efbd13591db07496601ebc7a059dd55cfe9
description: Initial release
1.0.0-rc:
appVersion: Nextcloud v33
ciProfile: prod
gitRef: release-branches/1-0-0-rc
description: |
Release Candidate.
Changelog:
- Feature X
- Feature Y
- Fix Z
1.0.0:
appVersion: Nextcloud v33
ciProfile: prod
gitRef: release-tags/1-0-0
description: Long Term Support Release
Provider-Felder
| Feld | Beschreibung |
|---|---|
name | Eindeutiger Bezeichner für den Provider. Muss dem Muster ^[-a-z0-9_]+$ entsprechen. |
schemaVersion | Versionsstring im Format v[0-9]+ (z. B. v0, v1). Identifiziert zusammen mit name einen Provider eindeutig. |
displayName | Für Menschen lesbarer Name, der im Marketplace-UI angezeigt wird. |
iconUrl | URL zum Provider-Icon (absoluter oder relativer Pfad). |
category | Gruppierungskategorie (z. B. databases, messaging, monitoring). |
author | Organisation oder Person, die für den Provider verantwortlich ist. |
description | Markdown-formatierte Beschreibung des Services. |
backend.landscape.gitUrl | Git-Repository-URL mit der Landscape-Konfiguration. |
configSchema | OpenAPI-Schema, das die vom Nutzer konfigurierbaren Optionen definiert. Diese Werte werden als Umgebungsvariablen an die Landscape übergeben. |
secretsSchema | OpenAPI-Schema, das geheime Werte definiert (z. B. Passwörter). Diese Werte werden im Secrets-Vault der Landscape gesetzt. |
detailsSchema | OpenAPI-Schema, das nach der Bereitstellung angezeigte Runtime-Details definiert. Siehe Standard-Landscape-Details. |
versions | Versionen des Services, die Nutzer bereitstellen können. Mindestens eine Version ist erforderlich. Siehe Provider-Versionen. |
Die drei Schemas teilen sich ein Format – ein gültiges OpenAPI-Schema-Objekt
configSchema, secretsSchema und detailsSchema dienen unterschiedlichen Zwecken, müssen aber jeweils ein gültiges OpenAPI-Schema-Objekt sein – so werden sie von Codesphere geparst. Wie in OpenAPI können Eigenschaften als required markiert oder mit sinnvollen default-Werten versehen werden.
Nachfolgend seht ihr, wo die einzelnen Schema-Typen im Codesphere-UI erscheinen:
- ConfigSchema
- SecretsSchema
- DetailsSchema
Das configSchema definiert die Konfigurationseigenschaften, die der Nutzer beim Erstellen eines Services festlegt – zum Beispiel die zu deployende PostgreSQL-Version. Diese Werte werden als Umgebungsvariablen an die Landscape übergeben (siehe Konfiguration an Landscapes übergeben). Sobald der Service erstellt wurde, kann die Konfiguration in den Service-Einstellungen eingesehen werden. Eigenschaften, die nicht als readOnly markiert sind, können später aktualisiert werden (siehe Update-Einschränkungen).

vorsicht
Das Aktualisieren von Konfigurationsparametern kann zu einer kurzen Downtime des Services führen.
Im secretsSchema definierte Secrets erscheinen als Formularfelder im Dialog zum Erstellen eines Services und müssen vom Nutzer ausgefüllt werden – zum Beispiel das Superuser-Passwort für PostgreSQL. Die Werte werden bei der Erstellung in den Service injiziert.

Im detailsSchema definierte Eigenschaften werden vom Service zur Laufzeit bereitgestellt – zum Beispiel der PostgreSQL-Hostname. Sie sind nur lesbar und können im Detailbereich der Service-Einstellungen eingesehen werden.

Property-Keys werden im UI in lesbare Bezeichnungen umgewandelt
Codesphere zeigt Nutzern nicht die rohen Keys an – sie werden im UI in gut lesbare Bezeichnungen umgewandelt (zum Beispiel wird service_url_frontend_3000 als Service Url Frontend 3000 angezeigt).
Standard-Landscape-Details
Bei Landscape-basierten Providern werden folgende Details immer automatisch berechnet und zurückgegeben:
| Key | Wert |
|---|---|
hostname | Die URL der Landscape. |
service_url_<serverName>_<port> | Die URL eines Services, ein Eintrag pro in der Landscape definiertem Service. |
Eine Landscape mit einem frontend-Service auf Port 3000 erzeugt beispielsweise service_url_frontend_3000. Um diese Werte auf der Detailseite des Services anzuzeigen, müssen sie im detailsSchema deklariert werden:
detailsSchema:
type: object
properties:
hostname:
type: string
format: uri
service_url_frontend_3000:
type: string
format: uri
Provider-Versionen
Jeder Provider muss mindestens einen Eintrag in versions definieren. Jede Version legt den genauen Zustand der Landscape fest, der bereitgestellt wird:
gitRef: Ein Commit-Hash, Branch oder Tag des Landscape-Repositorys.ciProfile: Das CI-Profil aus derci.ymlder Landscape, das für das Deployment verwendet wird.appVersion(optional): Eine für Menschen lesbare Bezeichnung der bereitgestellten Anwendungsversion.description(optional): Markdown-formatierte Release Notes, die dem Nutzer angezeigt werden.
Beim Erstellen eines Services wählt der Nutzer, welche Version bereitgestellt werden soll. Nutzer können die Version ihrer bereitgestellten Services ändern und damit ein Upgrade oder Downgrade auslösen. Weitere Informationen findest du unter Upgrade auf eine neue Version.
Veraltete Felder
backend.landscape.ciProfile und backend.landscape.gitRef dienten früher dazu, diese Werte einmal für den gesamten Provider festzulegen. Sie sind veraltet – ciProfile und gitRef werden jetzt pro Version definiert –, bleiben aber aus Kompatibilitätsgründen weiterhin verfügbar.
Veröffentlichen und Aktualisieren eines Landscape-basierten Providers
Der empfohlene Weg zum Veröffentlichen und Aktualisieren eines Providers ist der idempotente Upsert-Endpunkt der Codesphere Public API. Sende eine PUT-Anfrage an /managed-services/providers:
- Existiert noch kein Provider mit demselben
nameund derselbenschemaVersion, wird er erstellt. - Existiert bereits einer, werden alle veränderbaren Felder an Ort und Stelle aktualisiert.
Das bedeutet, dass ihr dieselbe Anfrage sowohl zum Erstellen eines Providers als auch zum Ausrollen späterer Änderungen verwenden könnt – ihr müsst nicht nachverfolgen, ob der Provider bereits existiert. Das ist zum Beispiel in CI/CD-Pipelines nützlich.
Ihr könnt entweder eine Git-URL angeben, die die provider.yml-Datei enthält, oder die vollständige Provider-Spezifikation im Payload übermitteln.
tipp
Für partielle Updates und explizitere Workflows existieren weiterhin dedizierte Endpunkte zum Erstellen (POST) und Aktualisieren (PATCH), doch für die meisten Fälle ist der Upsert-Endpunkt die einfachste Wahl.
Versionen sind nur anfügbar
Es können neue Einträge zu versions hinzugefügt werden, aber bestehende Versionseinträge können über ein Upsert nicht verändert oder entfernt werden. Alle anderen Provider-Felder werden an Ort und Stelle aktualisiert.
- provider.yml aus Git abrufen
- Vollständige Spezifikation angeben
Der einfachste Ansatz besteht darin, die Git-Repository-URL anzugeben. Codesphere ruft die provider.yml-Datei aus eurem Repository automatisch ab und validiert sie.
hinweis
Wird gitRef weggelassen, wird der Standard-Branch des Repositorys zum Abrufen der provider.yml-Datei verwendet.
Der scope ist kein Teil der provider.yml – ihr gebt ihn hier, in der Veröffentlichungsanfrage, zusammen mit der Git-URL an:
curl -X PUT "https://<your-codesphere-url>/api/managed-services/providers" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"gitUrl": "https://github.com/your-org/mattermost-landscape",
"gitRef": "my-branch",
"scope": {
"type": "global"
}
}'
Für mehr Kontrolle, oder wenn keine provider.yml im Repository enthalten sein soll, kann die vollständige Provider-Spezifikation direkt in der API-Anfrage übergeben werden:
curl -X PUT "https://<your-codesphere-instance-url>/api/managed-services/providers" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "mattermost",
"schemaVersion": "v1",
"author": "Your Team",
"displayName": "Mattermost",
"iconUrl": "https://example.com/mattermost-icon.png",
"category": "collaboration",
"description": "Open-source team messaging platform.",
"backend": {
"landscape": {
"gitUrl": "https://github.com/your-org/mattermost-landscape",
"ciProfile": "production"
}
},
"configSchema": {
"type": "object",
"properties": {
"SITE_NAME": {
"type": "string",
"description": "Display name for your Mattermost instance"
},
"MAX_USERS": {
"type": "integer",
"description": "Maximum number of users allowed"
}
}
},
"secretsSchema": {
"type": "object",
"properties": {
"ADMIN_PASSWORD": {
"type": "string",
"format": "password"
}
}
},
"detailsSchema": {
"type": "object",
"properties": {
"hostname": { "type": "string" },
"port": { "type": "integer" }
}
},
"plans": [],
"scope": {
"type": "team",
"teamIds": [42, 43]
},
"versions": {
"0.0.1": {
"ciProfile": "debug",
"gitRef": "1a410efbd13591db07496601ebc7a059dd55cfe9",
"description": "Initial release"
},
"1.0.0-rc": {
"appVersion": "Mattermost v10",
"ciProfile": "prod",
"gitRef": "release-branches/1-0-0-rc",
"description": "Release Candidate.\nChangelog:\n - Feature X\n - Feature Y\n - Fix Z\n"
},
"1.0.0": {
"appVersion": "Mattermost v10",
"ciProfile": "prod",
"gitRef": "release-tags/1-0-0",
"description": "Long Term Support Release"
}
}
}'
Provider-Scopes
Beim Erstellen eines Providers kann dessen Sichtbarkeitsbereich (Scope) festgelegt werden:
| Scope-Typ | Beschreibung |
|---|---|
global | Verfügbar für alle Teams in der Codesphere-Instanz. Erfordert Cluster-Admin-Berechtigungen. |
team | Nur für angegebene Teams verfügbar. Ein Array von teamIds angeben. |
Den Provider für alle in der Instanz verfügbar machen:
"scope": {
"type": "global"
}
Den Provider auf bestimmte Teams beschränken:
"scope": {
"type": "team",
"teamIds": [1, 24, 56]
}
Konfiguration an Landscapes übergeben
Wenn ein Service aus einem Landscape-basierten Provider erstellt wird, wird die Eingabe des Nutzers an die Landscape weitergegeben: Eigenschaften aus dem configSchema werden als Umgebungsvariablen gesetzt, und Secrets aus dem secretsSchema werden in den Vault der Landscape injiziert. Beide können in der ci.yml der Landscape referenziert werden:
schemaVersion: v0.2
run:
my-service:
steps:
- command: ./start.sh
env:
APP_VERSION: ${{ workspace.env['APP_VERSION'] }}
ADMIN_PASSWORD: ${{ vault.ADMIN_PASSWORD }}
In diesem Beispiel ist APP_VERSION eine Eigenschaft des configSchema des Providers und ADMIN_PASSWORD eine Eigenschaft des secretsSchema des Providers.
Update-Einschränkungen mit x-update-constraint
Das configSchema unterstützt eine benutzerdefinierte Erweiterung x-update-constraint, mit der sich einschränken lässt, wie einzelne Eigenschaften nach der Erstellung eines Services geändert werden können. Das ist nützlich, um betriebliche Regeln durchzusetzen – zum Beispiel um zu verhindern, dass Speicherplatz verringert wird, oder um die Version einer Datenbank-Engine nach der Erstinstallation zu fixieren.
Fügt das Schlüsselwort x-update-constraint zu einer beliebigen Eigenschaft im configSchema hinzu:
configSchema:
type: object
properties:
storage:
type: integer
description: Storage allocation in GB
x-update-constraint: increase-only
version:
type: string,
description: Version of the Postgres DB.
enum: ['17.6', '16.10', '15.14', '14.19', '13.22']
x-update-constraint: immutable,
Verfügbare Einschränkungen
| Einschränkung | Verhalten |
|---|---|
increase-only | Der neue Wert muss größer oder gleich dem aktuellen Wert sein. Gilt nur für numerische Felder. |
immutable | Die Eigenschaft kann nach dem erstmaligen Setzen nicht mehr geändert werden. |
info
Update-Einschränkungen werden nur beim Aktualisieren eines bestehenden Services durchgesetzt. Bei der Erstellung werden alle Werte akzeptiert, solange sie die reguläre Schema-Validierung bestehen.
Unterstützte Formate
Provider-Schemas unterstützen zur Validierung die üblichen OpenAPI-format-Werte:
int32, int64, float, double, byte, binary, date, date-time, password, uri, hostname
Über die Validierung hinaus verändern manche Formate, wie ein Wert im Codesphere-UI dargestellt wird:
| Format | Effekt im UI |
|---|---|
uri, hostname | Im Detailbereich der Service-Einstellungen wird der Wert als klickbarer Link statt als reiner Text dargestellt. Wird für detailsSchema-Eigenschaften wie hostname oder service_url_* verwendet. |
password | Im Dialog Service erstellen wird das entsprechende secretsSchema-Feld als maskiertes Passwortfeld statt als reines Textfeld dargestellt. |
Markiert man beispielsweise die Detail-URLs mit format: uri, werden sie auf der Detailseite zu Links, und markiert man ein Secret mit format: password, wird es bei der Eingabe maskiert:
detailsSchema:
type: object
properties:
hostname:
type: string
format: uri # rendered as a link in the details section
readOnly: true
secretsSchema:
type: object
properties:
admin_password:
type: string
format: password # rendered as a masked input in the create dialog

Dynamische Details mit x-endpoint
Das detailsSchema unterstützt eine benutzerdefinierte OpenAPI-Erweiterung x-endpoint, mit der Runtime-Details dynamisch vom eigenen Service abgerufen werden können. Das ist nützlich, um Live-Statusinformationen, Metriken oder andere Daten abzurufen, die sich nach der Bereitstellung ändern.
Ist x-endpoint für eine Eigenschaft gesetzt, ruft Codesphere den Wert zur Laufzeit vom angegebenen Endpunkt ab und validiert ihn gegen das Schema der Eigenschaft.
Templating der Endpunkt-URL
Die Endpunkt-URL ist eine Vorlage (Template): Ihr könnt mit der Syntax ${{ .field_name }} auf andere Detail-Felder verweisen, und Codesphere ersetzt deren Werte vor dem Absenden der Anfrage. So lässt sich der Endpunkt aus Details aufbauen, die erst nach der Bereitstellung bekannt sind – etwa die standardmäßigen service_url_*-Felder.
detailsSchema:
type: object
properties:
service_url_frontend_3000:
type: string
format: uri
readOnly: true
status:
type: object
properties:
state:
type: string
# ${{ .service_url_frontend_3000 }} is replaced with that detail's value at runtime
x-endpoint: '${{ .service_url_frontend_3000 }}/health'
In diesem Beispiel wird die Eigenschaft status vom /health-Endpunkt des Frontend-Services abgerufen. Die Vorlage löst ${{ .service_url_frontend_3000 }} zur URL des laufenden Services auf, sodass die endgültige Anfrage an <service-url>/health geht und die JSON-Antwort status.state befüllt.
info
Für x-endpoint werden nur GET-Anfragen unterstützt. Der Endpunkt muss JSON zurückgeben, das der Schema-Definition der Eigenschaft entspricht.
Eigene REST-Backends
Die Managed-Services-Architektur von Codesphere ist erweiterbar konzipiert. Wenn Landscape-basierte Provider euren spezifischen Anforderungen nicht genügen, könnt ihr ein eigenes, individuelles REST-Backend implementieren.
tipp
Eine vollständige Anleitung zur Implementierung der Managed Service Adapter API-Spezifikation findet ihr unter Ein eigenes REST-Backend erstellen.