Service Provider erstellen
Mit Codesphere kannst du bestehende Codesphere-Landscapes als Managed Service Provider veröffentlichen. So können andere Entwickler deine individuellen Lösungen entdecken und bereitstellen.
Landscape-basierte Service Provider
Ein Landscape-basierter Service Provider ermöglicht es anderen, deine Codesphere-Landscape als vorkonfigurierten Managed Service zu instanziieren, den sie über den Servicekatalog bereitstellen und verwalten können.
info
Für das Veröffentlichen von Providern sind Cluster-Admin-Berechtigungen erforderlich. Team-Admins können beantragen, dass Provider auf bestimmte Teams eingeschränkt werden.
Voraussetzungen
Bevor du einen Landscape-basierten Service Provider erstellst, benötigst du:
- Ein Git-Repository mit einer gültigen Codesphere-Landscape und einer
ci.yml-Datei. - Eine Provider-Definition, entweder als
provider.yml-Datei im Wurzelverzeichnis des Repositorys oder direkt in der API-Anfrage angegeben. - Git-Zugriff auf das Landscape-Repository. Codesphere zieht das Repository über deine Git-Verbindung, daher muss das Konto, mit dem der Provider erstellt wird, über die Berechtigung verfügen, darauf zuzugreifen. Du kannst deine Git-Verbindungen in deinen Benutzereinstellungen verwalten.
Ein Beispiel findest du in unserem öffentlichen URL-Shortener-Repository.
Der Git-Zugriff ist an einen Benutzer gebunden
Zum Abrufen 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 – seine Verbindung wird dann für das Abrufen verwendet. Für langlebige Provider empfiehlt sich die Veröffentlichung mit einem technischen Benutzer.
Provider-Definition
Die Datei provider.yml definiert alle Metadaten und Konfigurationsschemata für deinen 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.
teamSingleton: true
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 | Eindeutige Kennung für den Provider. Muss ^[-a-z0-9_]+$ entsprechen. |
schemaVersion | Versionsangabe 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 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. |
teamSingleton | Optionaler Boolean. Wenn true, kann jedes Team nur einen nicht gelöschten Service für diesen Provider und diese Version haben. Ein Service, der den Status deleted erreicht hat, blockiert die erneute Erstellung nicht mehr; ein Service, der sich noch im Löschvorgang befindet, tut dies. Weglassen oder auf false setzen, um mehrere Services zu erlauben. |
backend.landscape.gitUrl | Git-Repository-URL mit der Landscape-Konfiguration. |
configSchema | OpenAPI-Schema, das vom Benutzer konfigurierbare Optionen definiert. Diese Werte werden der Landscape als Umgebungsvariablen ü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 zur Laufzeit bereitgestellte Details definiert, die nach der Provisionierung angezeigt werden. Siehe Standard-Landscape-Details. |
versions | Versionen des Services, die Benutzer bereitstellen können. Mindestens eine Version ist erforderlich. Siehe Provider-Versionen. |
Die drei Schemata 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 belegt werden.
Nachfolgend ist dargestellt, wo jeder Schema-Typ in der Codesphere-Oberfläche erscheint:
- ConfigSchema
- SecretsSchema
- DetailsSchema
Das configSchema definiert die Konfigurationseigenschaften, die der Benutzer beim Erstellen eines Services festlegt – zum Beispiel die zu deployende PostgreSQL-Version. Diese Werte werden der Landscape als Umgebungsvariablen übergeben (siehe Konfiguration an Landscapes übergeben). Nach der Erstellung des Services kann die Konfiguration in den Service-Einstellungen eingesehen werden. Eigenschaften, die nicht als readOnly markiert sind, können später aktualisiert werden (siehe Aktualisierungsbeschrä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 Benutzer ausgefüllt werden – zum Beispiel das PostgreSQL-Superuser-Passwort. Die Werte werden während der Erstellung in den Service eingefügt.

Im detailsSchema definierte Eigenschaften werden zur Laufzeit vom Service bereitgestellt – zum Beispiel der PostgreSQL-Hostname. Sie sind schreibgeschützt und können im Details-Bereich der Service-Einstellungen eingesehen werden.

Eigenschaftsschlüssel werden in der Oberfläche in lesbare Bezeichnungen umgewandelt
Codesphere zeigt Benutzern nicht die rohen Schlüssel an, sondern wandelt sie in der Oberfläche in lesbare Bezeichnungen um (zum Beispiel wird service_url_frontend_3000 als Service Url Frontend 3000 angezeigt).
Standard-Landscape-Details
Für Landscape-basierte Provider werden folgende Details immer automatisch berechnet und zurückgegeben:
| Schlüssel | 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 Details-Seite des Services anzuzeigen, deklariere sie in deinem detailsSchema:
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 fixiert den genauen Zustand der Landscape, 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 für die deployte Anwendungsversion.description(optional): Markdown-formatierte Release-Notes, die dem Benutzer angezeigt werden.
Beim Erstellen eines Services wählen Benutzer aus, welche Version bereitgestellt werden soll. Benutzer können die Version ihrer deployten Services ändern, wodurch ein Upgrade oder Downgrade ausgelöst wird. 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 einmalig für den gesamten Provider zu definieren. Sie sind veraltet — ciProfile und gitRef werden jetzt pro Version definiert — bleiben aber aus Gründen der Abwärtskompatibilität verfügbar.
Veröffentlichen und Aktualisieren eines Landscape-basierten Providers
Der empfohlene Weg, um einen Provider zu veröffentlichen und zu aktualisieren, 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 direkt aktualisiert.
Das bedeutet, du kannst dieselbe Anfrage verwenden, um einen Provider zu erstellen und um spätere Änderungen auszurollen — du musst nicht verfolgen, ob der Provider bereits existiert. Das ist zum Beispiel in CI/CD-Pipelines nützlich.
Du kannst entweder eine Git-URL angeben, die die provider.yml-Datei enthält, oder die vollständige Provider-Spezifikation im Payload angeben.
tipp
Für Teilaktualisierungen und explizitere Workflows gibt es weiterhin dedizierte Endpunkte zum Erstellen (POST) und Aktualisieren (PATCH), doch für die meisten Fälle ist der Upsert-Endpunkt die einfachste Wahl.
Versionen können nur hinzugefügt, nicht geändert werden
Du kannst neue Einträge zu versions hinzufügen, aber bestehende Versionseinträge können über ein Upsert nicht verändert oder entfernt werden. Alle anderen Provider-Felder werden direkt aktualisiert.
- provider.yml aus Git abrufen
- Vollständige Spezifikation angeben
Der einfachste Ansatz besteht darin, die Git-Repository-URL anzugeben. Codesphere ruft die Datei provider.yml automatisch aus deinem Repository ab und validiert sie.
hinweis
Wenn du gitRef weglässt, wird der Standard-Branch des Repositorys verwendet, um die Datei provider.yml abzurufen.
Der scope ist nicht Teil der provider.yml — du gibst ihn hier, in der Publish-Anfrage, 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 du keine provider.yml in dein Repository aufnehmen möchtest, kannst du die vollständige Provider-Spezifikation direkt in der API-Anfrage angeben:
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.",
"teamSingleton": true,
"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 kannst du dessen Sichtbarkeitsbereich definieren:
| Scope-Typ | Beschreibung |
|---|---|
global | Verfügbar für alle Teams in der Codesphere-Instanz. Erfordert Cluster-Admin-Berechtigungen. |
team | Nur für bestimmte Teams verfügbar. Gib ein Array von teamIds an. |
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]
}
Team-Singleton-Provider
Setze teamSingleton: true, wenn ein Provider für eine bestimmte Provider-Version höchstens einen nicht gelöschten Managed Service pro Team bereitstellen soll. Codesphere weist eine zweite Erstellungsanfrage mit einem AlreadyExists-Fehler zurück, solange ein bestehender Service für dieses Team, diesen Provider und diese Version den Status deleted noch nicht erreicht hat. Das gilt auch für Services, die sich noch im Löschvorgang befinden. Sobald der bestehende Service den Status deleted erreicht hat, kann das Team einen weiteren erstellen.
Lasse teamSingleton unangegeben oder setze es auf false, wenn Teams mehrere Services derselben Provider-Version erstellen dürfen.
Konfiguration an Landscapes übergeben
Wenn ein Service aus einem Landscape-basierten Provider erstellt wird, werden die Eingaben des Benutzers an die Landscape weitergegeben: Eigenschaften aus dem configSchema werden als Umgebungsvariablen gesetzt, und Secrets aus dem secretsSchema werden in den Vault der Landscape eingefügt. 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.
Aktualisierungsbeschränkungen mit x-update-constraint
Das configSchema unterstützt eine benutzerdefinierte Erweiterung x-update-constraint, mit der du einschränken kannst, 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 der Speicherplatz
verringert wird, oder um die Version einer Datenbank-Engine nach der initialen Einrichtung festzuschreiben.
Füge das Schlüsselwort x-update-constraint zu einer beliebigen Eigenschaft in deinem 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 Constraints
| Constraint | 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 Setzen nicht mehr geändert werden. |
info
Aktualisierungsbeschränkungen werden nur beim Aktualisieren eines bestehenden Services durchgesetzt. Bei der initialen Erstellung werden alle Werte akzeptiert, solange sie die standardmäßige Schema-Validierung durchlaufen.
Unterstützte Formate
Provider-Schemata unterstützen die Standard-OpenAPI-format-Werte zur Validierung:
int32, int64, float, double, byte, binary, date, date-time, password, uri, hostname
Über die Validierung hinaus verändern einige Formate, wie ein Wert in der Codesphere-Oberfläche dargestellt wird:
| Format | Auswirkung in der Oberfläche |
|---|---|
uri, hostname | Im Details-Bereich der Service-Einstellungen wird der Wert als anklickbarer Link statt als reiner Text dargestellt. Verwende es für detailsSchema-Eigenschaften wie hostname oder service_url_*. |
password | Im Dialog zum Erstellen eines Services wird das entsprechende secretsSchema-Feld als maskiertes Passwortfeld statt als einfaches Textfeld dargestellt. |
Wenn du beispielsweise die Detail-URLs als format: uri markierst, werden sie auf der Details-Seite zu Links, und wenn du ein Secret als format: password markierst, 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 du Laufzeitdetails dynamisch von deinem Service abrufen kannst. Das ist nützlich, um Live-Statusinformationen, Metriken oder andere Daten abzurufen, die sich nach der Provisionierung ändern.
Wenn x-endpoint für eine Eigenschaft gesetzt ist, 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 ein Template: Du kannst andere Detail-Felder mit der Syntax ${{ .field_name }} referenzieren, und Codesphere ersetzt deren Werte, bevor die Anfrage ausgeführt wird. So kannst du den Endpunkt aus Details aufbauen, die erst nach der Provisionierung bekannt sind — wie zum Beispiel die Standard-Felder service_url_*.
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. Das Template 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 Schemadefinition der Eigenschaft entspricht.
Individuelle REST-Backends
Die Managed-Services-Architektur von Codesphere ist erweiterbar konzipiert. Wenn Landscape-basierte Provider deinen spezifischen Anforderungen nicht entsprechen, kannst du dein eigenes individuelles REST-Backend implementieren.
tipp
Eine vollständige Anleitung zur Implementierung der Spezifikation der Managed Service Adapter API findest du unter Ein individuelles REST-Backend erstellen.