Zum Hauptinhalt springen
Version: 1.99.x (Q3 26)

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:

  1. Ein Git-Repository mit einer gültigen Codesphere-Landscape inklusive ci.yml-Datei.
  2. Eine Provider-Definition, entweder als provider.yml-Datei im Repository-Root oder direkt in der API-Anfrage übergeben.
  3. 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

FeldBeschreibung
nameEindeutiger Bezeichner für den Provider. 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 Services.
backend.landscape.gitUrlGit-Repository-URL mit der Landscape-Konfiguration.
configSchemaOpenAPI-Schema, das die vom Nutzer konfigurierbaren Optionen definiert. Diese Werte werden als Umgebungsvariablen an die Landscape übergeben.
secretsSchemaOpenAPI-Schema, das geheime Werte definiert (z. B. Passwörter). Diese Werte werden im Secrets-Vault der Landscape gesetzt.
detailsSchemaOpenAPI-Schema, das nach der Bereitstellung angezeigte Runtime-Details definiert. Siehe Standard-Landscape-Details.
versionsVersionen 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:

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).

Config Schema in den Service-Einstellungen

vorsicht

Das Aktualisieren von Konfigurationsparametern kann zu einer kurzen Downtime des Services führen.

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:

KeyWert
hostnameDie 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 der ci.yml der 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 name und derselben schemaVersion, 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.

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"
}
}'

Provider-Scopes

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

Scope-TypBeschreibung
globalVerfügbar für alle Teams in der Codesphere-Instanz. 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]
}

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änkungVerhalten
increase-onlyDer neue Wert muss größer oder gleich dem aktuellen Wert sein. Gilt nur für numerische Felder.
immutableDie 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:

FormatEffekt im UI
uri, hostnameIm 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.
passwordIm 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

Das Format password erzeugt ein maskiertes Eingabefeld im Dialog „Service erstellen“

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.