Zum Hauptinhalt springen
Version: Weekly Build

Creating Service Providers

title: "Service Providers erstellen" slug: /managed-services/creating-service-providers sidebar_position: 3

Mit Codesphere kann ein Service als Managed Service Provider paketiert werden, damit andere Entwickler ihn im Service-Katalog finden und bereitstellen können. Provider gibt es in zwei Typen:

  • Landscape-basierte Provider stellen eine Codesphere-Landscape (eine ci.yml) als Managed Service bereit, orchestriert innerhalb des Codesphere-Clusters — es ist kein Backend-Code erforderlich.
  • REST-basierte Provider verbinden den Katalog mit selbst betriebener Infrastruktur über ein eigenes Backend, das die Provider-REST-API implementiert.

Eine ausführlichere Erklärung der beiden Typen und wann welcher verwendet werden sollte, findest du unter Service-Kategorien. Zur Implementierung des Backends für einen REST-basierten Provider siehe Eigenes REST-Backend erstellen.

Diese Seite erklärt, wie ein Provider definiert wird und wie er in Codesphere veröffentlicht, aktualisiert und gelöscht wird.

Einen Provider definieren

Voraussetzungen

Ein Landscape-basierter Provider stellt eine Landscape aus einem Git-Repository bereit. Bevor du einen solchen erstellst, benötigst du:

  1. Ein Git-Repository, das eine gültige Codesphere-Landscape mit einer ci.yml-Datei enthält.
  2. Eine Provider-Definition, entweder als Provider-Datei im Repository (standardmäßig provider.yml oder provider.yaml im Root-Verzeichnis, oder ein benutzerdefinierter Pfad über das Argument filepath) oder direkt in der API-Anfrage angegeben.
  3. 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 entsprechende Zugriffsberechtigung verfügen. Git-Verbindungen können in den Benutzereinstellungen verwaltet werden.

Ein Beispiel findest du in unserem öffentlichen URL-Shortener-Repository.

Git-Zugriff ist an einen Benutzer gebunden

Für das 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 — anschließend wird dessen Verbindung für das Abrufen verwendet. Für langlebige Provider empfiehlt sich die Veröffentlichung mit einem technischen Benutzer.

Provider-Schema

Die Provider-Definition legt alle Metadaten und Konfigurationsschemas für den Service Provider fest. Die beiden Provider-Typen teilen sich die meisten Felder; der Hauptunterschied liegt im backend-Block — Landscape-basierte Provider verweisen auf ein Git-Repository (backend.landscape), während REST-basierte Provider auf den Backend-Endpunkt (backend.api) verweisen und zusätzlich plans, capabilities und backups deklarieren können.

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
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: Mattermost v11.10.1
ciProfile: prod
gitRef: release-branches/1-0-0-rc
description: |
Release Candidate.
Changelog:
- Feature X
- Feature Y
- Fix Z
1.0.0:
appVersion: Mattermost v11.10.1
ciProfile: prod
gitRef: release-tags/1-0-0
description: Long Term Support Release

Provider-Felder

Diese Felder sind bei beiden Provider-Typen identisch:

FeldBeschreibung
nameEindeutige Kennung des Providers. Muss dem Muster ^[-a-z0-9_]+$ entsprechen.
schemaVersionVersionsstring im Format v[0-9]+ (z. B. v0, v1). Identifiziert zusammen mit name einen Provider eindeutig.
displayNameFür Menschen lesbarer Name, der im Marketplace-UI angezeigt wird.
iconUrlURL zum Provider-Icon (absoluter oder relativer Pfad).
categoryGruppierungskategorie (z. B. databases, messaging, monitoring).
authorOrganisation oder Person, die für den Provider verantwortlich ist.
descriptionMarkdown-formatierte Beschreibung des Service.
documentationUrlOptionaler Link zu externer Dokumentation für den Service, der im UI angezeigt wird.
teamSingletonOptionaler boolescher Wert. Bei true kann jedes Team nur einen nicht gelöschten Service für diesen Provider und diese Version besitzen. Ein Service, der den Status deleted erreicht hat, blockiert eine erneute Erstellung nicht mehr; ein Service, der sich noch im Löschvorgang befindet, tut dies. Weglassen oder auf false setzen erlaubt mehrere Services.
configSchemaOpenAPI-Schema, das die vom Nutzer konfigurierbaren Optionen definiert. Siehe configSchema.
secretsSchemaOpenAPI-Schema, das geheime Werte definiert (z. B. Passwörter). Siehe secretsSchema.
detailsSchemaOpenAPI-Schema, das nach der Bereitstellung offengelegte Laufzeitdetails definiert. Siehe detailsSchema.

Die übrigen Felder hängen vom Provider-Typ ab:

FeldBeschreibung
backend.landscape.gitUrlGit-Repository-URL mit der Landscape-Konfiguration.
versionsVersionen des Service, die Nutzer bereitstellen können. Mindestens eine Version ist erforderlich. Siehe Provider-Versionen.

Capabilities bei Landscape-basierten Providern

Landscape-basierte Provider unterstützen bislang keine Capabilities. Du kannst sie dennoch explizit auf false setzen, um im UI ein deutliches Kreuz ("nicht unterstützt") anzuzeigen; wird eine Capability weggelassen, wird sie komplett ausgeblendet.

Konfigurationsschemas

Ein Provider definiert bis zu drei Schemas: configSchema, secretsSchema und detailsSchema. Sie erfüllen unterschiedliche Zwecke, werden aber auf die gleiche Weise geparst.

Die drei Schemas teilen sich ein Format — ein gültiges OpenAPI-Schemaobjekt

configSchema, secretsSchema und detailsSchema erfüllen unterschiedliche Zwecke, müssen aber jeweils ein gültiges OpenAPI-Schemaobjekt sein — so parst Codesphere sie. Wie in OpenAPI können Eigenschaften als required markiert oder mit sinnvollen default-Werten versehen werden.

Eigenschaftsschlüssel werden im UI in lesbare Bezeichnungen umgewandelt

Codesphere zeigt den Nutzern nicht die rohen Schlüssel an — sie werden im UI in lesbare Bezeichnungen umgewandelt (zum Beispiel wird service_url_frontend_3000 als Service Url Frontend 3000 angezeigt).

1.4.1. ConfigSchema

Das configSchema definiert die Konfigurationseigenschaften, die der Nutzer bei der Erstellung eines Service festlegt — zum Beispiel die zu deployende PostgreSQL-Version. Bei Landscape-basierten Providern werden diese Werte als Umgebungsvariablen an die Landscape übergeben (siehe Konfiguration an Landscapes übergeben); bei REST-basierten Providern werden sie im Body der Erstellungs-/Aktualisierungsanfrage an dein Backend gesendet. Sobald der Service erstellt ist, 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).

Config Schema in den Service-Einstellungen

vorsicht

Das Aktualisieren von Konfigurationsparametern kann zu einer kurzen Ausfallzeit des Service führen.

Update-Einschränkungen mit x-update-constraint

Das configSchema unterstützt eine benutzerdefinierte Erweiterung x-update-constraint, mit der eingeschränkt werden kann, wie einzelne Eigenschaften nach der Erstellung eines Service geändert werden dürfen. Das ist nützlich, um operative Regeln durchzusetzen — zum Beispiel um zu verhindern, dass der Speicherplatz verringert wird, oder um die Version einer Datenbank-Engine nach der initialen Einrichtung zu fixieren.

Füge das Schlüsselwort x-update-constraint zu einer beliebigen Eigenschaft 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: minor-upgrade-only
EinschränkungVerhalten
increase-onlyDer neue Wert muss größer oder gleich dem aktuellen Wert sein. Gilt nur für numerische Felder.
minor-upgrade-onlyDer neue Wert darf sich nur innerhalb derselben Hauptversion vorwärts bewegen (z. B. 17.617.9, aber nicht 16.x17.x). Gedacht für Versionsfelder.
immutableDie Eigenschaft kann nach dem ersten Setzen nicht mehr geändert werden.

info

Update-Einschränkungen greifen nur bei der Aktualisierung eines bestehenden Service. Bei der initialen Erstellung werden alle Werte akzeptiert, solange sie die Standard-Schemavalidierung bestehen.

1.4.2. SecretsSchema

Im secretsSchema definierte Secrets erscheinen als Formularfelder im Dialog zum Erstellen eines Service und müssen vom Nutzer ausgefüllt werden — zum Beispiel das PostgreSQL-Superuser-Passwort. Die Werte werden bei der Erstellung in den Service injiziert: bei Landscape-basierten Providern in den Secrets-Vault der Landscape, bei REST-basierten Providern als secrets an dein Backend gesendet. Wird eine Eigenschaft mit format: password markiert, wird sie als maskiertes Eingabefeld dargestellt.

Secrets Schema im Dialog zum Erstellen eines Service

1.4.3. DetailsSchema

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

Details Schema in den Service-Einstellungen

Standardmäßige Landscape-Details

Nur für Landscape-basierte Provider

Bei Landscape-basierten Providern werden folgende Details immer automatisch berechnet und zurückgegeben:

SchlüsselWert
hostnameDie URL der Landscape.
service_url_<serverName>_<port>Die URL eines Service, ein Eintrag pro in der Landscape definiertem Service.

Zum Beispiel erzeugt eine Landscape mit einem frontend-Service auf Port 3000 den Eintrag service_url_frontend_3000. Um diese Werte auf der Details-Seite des Service anzuzeigen, deklariere sie in deinem detailsSchema:

detailsSchema:
type: object
properties:
hostname:
type: string
format: uri
service_url_frontend_3000:
type: string
format: uri

1.4.4. Dynamische Details mit x-endpoint

Das detailsSchema unterstützt eine benutzerdefinierte OpenAPI-Erweiterung x-endpoint, mit der Laufzeitdetails dynamisch aus deinem Service abgerufen werden können. Das ist nützlich, um Live-Statusinformationen, Metriken oder andere Daten abzurufen, die sich nach der Bereitstellung ändern.

Wird x-endpoint bei einer Eigenschaft gesetzt, ruft Codesphere den Wert zur Laufzeit vom angegebenen Endpunkt ab und validiert ihn anhand des Schemas der Eigenschaft.

Die Endpunkt-URL ist eine Vorlage: Andere Detailfelder können mit der Syntax ${{ .field_name }} referenziert werden, und Codesphere ersetzt deren Werte vor dem Absenden der Anfrage. So lässt sich der Endpunkt aus Details zusammensetzen, 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-Service abgerufen. Die Vorlage löst ${{ .service_url_frontend_3000 }} zur URL des laufenden Service 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 dem Schema der Eigenschaft entspricht.

1.4.5. Unterstützte Formate

Provider-Schemas unterstützen die gängigen OpenAPI-format-Werte zur Validierung:

int32, int64, float, double, byte, binary, date, date-time, password, uri, hostname

Über die Validierung hinaus beeinflussen manche Formate, wie ein Wert im Codesphere-UI dargestellt wird:

FormatAuswirkung im UI
uri, hostnameIm Bereich Details der Service-Einstellungen wird der Wert als klickbarer Link statt als reiner Text dargestellt. Verwende dieses Format für detailsSchema-Eigenschaften wie hostname oder service_url_*.
passwordIm Dialog Service erstellen wird das entsprechende secretsSchema-Feld als maskiertes Passwortfeld statt als reines Textfeld dargestellt.
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

1.4.6. Konfiguration und Secrets an Landscapes übergeben

Nur für Landscape-basierte Provider

Wenn ein Service aus einem Landscape-basierten Provider erstellt wird, werden die Eingaben des Nutzers an die Landscape weitergereicht: 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.

Capabilities

capabilities ist eine optionale Map, die deklariert, welche Lifecycle-Funktionen das Backend eines Providers unterstützt. Jeder Eintrag ist ein boolescher Wert und wird im Service-UI angezeigt: true zeigt ein Häkchen, false zeigt ein explizites Kreuz ("nicht unterstützt"), und eine ausgelassene Capability wird komplett ausgeblendet.

CapabilityBeschreibung
pauseDer Service kann pausiert und später fortgesetzt werden, wobei Rechenleistung freigegeben wird, während seine Daten erhalten bleiben.
backupsDer Service unterstützt Backups auf einen externen Speicher. Erfordert den backups-Schemablock. Siehe Managed Service Backups.
pointInTimeRecoveryDer Service kann auf einen beliebigen Zeitpunkt wiederhergestellt werden, nicht nur auf diskrete Backup-Snapshots.
highAvailabilityDer Service kann in einer hochverfügbaren Konfiguration betrieben werden (z. B. redundante Replikate mit Failover).

hinweis

Capabilities beschreiben, was das Backend eines Providers implementiert. Landscape-basierte Provider können bislang keine dieser Capabilities unterstützen.

Provider-Versionen

Nur für Landscape-basierte Provider

Jeder Landscape-basierte Provider muss mindestens einen Eintrag unter 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 der ci.yml der Landscape, das für die Bereitstellung verwendet wird.
  • appVersion (optional): Eine für Menschen lesbare Bezeichnung der bereitgestellten Anwendungsversion.
  • description (optional): Markdown-formatierte Release-Notizen, die dem Nutzer angezeigt werden.

Beim Erstellen eines Service wählen Nutzer aus, welche Version bereitgestellt werden soll. Nutzer können die Version ihrer bereitgestellten Services ändern und dadurch 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 einmalig für den gesamten Provider festzulegen. Sie gelten als veraltet — ciProfile und gitRef werden inzwischen pro Version definiert —, bleiben aber aus Gründen der Abwärtskompatibilität weiterhin verfügbar.

Provider veröffentlichen und verwalten

Sobald ein Provider definiert ist, wird er über die Codesphere Public API in Codesphere veröffentlicht. Die im Folgenden beschriebenen Mechanismen für Veröffentlichung, Aktualisierung, Löschung, Scope und Singleton sind für Landscape-basierte und REST-basierte Provider identisch.

info

Zum Veröffentlichen von Providern sind Cluster-Admin-Berechtigungen erforderlich. Team-Admins können beantragen, dass Provider auf bestimmte Teams beschränkt werden.

Provider-Scopes

Beim Erstellen eines Providers kann dessen Sichtbarkeitsbereich (Scope) festgelegt werden:

Scope-TypBeschreibung
globalFür alle Teams der Codesphere-Instanz verfügbar. Erfordert Cluster-Admin-Berechtigungen.
teamNur 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]
}

Einen Provider veröffentlichen und aktualisieren

Die empfohlene Methode zum Veröffentlichen und Aktualisieren eines Providers ist der idempotente Upsert-Endpunkt. Sende eine PUT-Anfrage an /managed-services/providers:

  • Existiert noch kein Provider mit demselben name und derselben schemaVersion, wird er erstellt.
  • Existiert bereits einer, werden alle veränderbaren Felder direkt aktualisiert.

Das bedeutet, dieselbe Anfrage kann sowohl zum Erstellen eines Providers als auch für spätere Änderungen verwendet werden — es muss nicht nachverfolgt werden, 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-Datei enthält, oder die vollständige Provider-Spezifikation im Payload übergeben.

tipp

Eigene Endpunkte für Erstellen (POST) und Aktualisieren (PATCH) existieren weiterhin für partielle Updates und explizitere Workflows, aber für die meisten Fälle ist der Upsert-Endpunkt die einfachste Wahl. Siehe Einen Provider direkt aktualisieren.

Versionen können nur ergänzt werden

Bei Landscape-basierten Providern können neue Einträge zu versions hinzugefügt werden, aber bestehende Versionseinträge können über ein Upsert weder geändert noch entfernt werden. Alle anderen Provider-Felder werden direkt aktualisiert.

Der einfachste Ansatz besteht darin, die Git-Repository-URL anzugeben. Codesphere ruft die Provider-Datei automatisch aus deinem Repository ab und validiert sie. Standardmäßig wird nach provider.yml im Root-Verzeichnis des Repositorys gesucht; wird diese Datei nicht gefunden, wird auf provider.yaml zurückgegriffen.

hinweis

Wird gitRef weggelassen, wird der Standard-Branch des Repositorys zum Abrufen der Provider-Datei verwendet.

Um einen anderen Dateinamen oder Speicherort zu verwenden — zum Beispiel um mehrere Provider-Dateien in einem Repository zu verwalten — übergib das optionale Argument filepath. Es wird relativ zum Root-Verzeichnis des Repositorys aufgelöst und ist standardmäßig provider.yml, wenn es weggelassen wird.

scope und filepath sind kein Bestandteil der Provider-Datei — sie werden hier, in der Veröffentlichungsanfrage, zusammen mit der Git-URL angegeben:

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",
"filepath": "config/prov-definition.yml",
"scope": {
"type": "global"
}
}'

Einen Provider direkt aktualisieren

Um bestimmte Felder zu ändern, ohne die gesamte Definition erneut zu übermitteln, verwende den PATCH-Endpunkt. Nur die von dir angegebenen Felder werden geändert; alle anderen gespeicherten Felder bleiben erhalten.

curl -X PATCH "https://<your-codesphere-url>/api/managed-services/providers/{name}/{schemaVersion}" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"displayName": "My Updated Service",
"backend": {
"api": {
"endpoint": "https://new-endpoint.example.com",
"secret": "new-secret"
}
}
}'

Beim Aktualisieren von backend.api bleiben weggelassene Felder erhalten — so kann der endpoint aktualisiert werden, während das gespeicherte secret unverändert bleibt, oder es kann ein neues secret angegeben werden, um es zu rotieren.

Secrets werden nie zurückgegeben (REST-basierte Provider)

Das Feld secret in backend.api wird sicher gespeichert, aber niemals in der API-Antwort enthalten. Dies gilt für die PATCH-, PUT- und POST-Antworten bei REST-basierten Providern.

Einen Provider löschen

Um einen Provider zu entfernen, sende eine DELETE-Anfrage an /managed-services/providers/{name}/{schemaVersion}:

curl -X DELETE "https://<your-codesphere-url>/api/managed-services/providers/{name}/{schemaVersion}" \
-H "Authorization: Bearer YOUR_API_KEY"

Die Pfadparameter name und schemaVersion identifizieren den zu löschenden Provider.