Zum Hauptinhalt springen
Version: Weekly Build

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:

  1. Ein Git-Repository mit einer gültigen Codesphere-Landscape und einer ci.yml-Datei.
  2. Eine Provider-Definition, entweder als provider.yml-Datei im Wurzelverzeichnis des Repositorys 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 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

FeldBeschreibung
nameEindeutige Kennung für den Provider. Muss ^[-a-z0-9_]+$ entsprechen.
schemaVersionVersionsangabe im Format v[0-9]+ (z. B. v0, v1). Identifiziert zusammen mit name einen Provider eindeutig.
displayNameFür Menschen lesbarer Name, der im Marketplace 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.
teamSingletonOptionaler 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.gitUrlGit-Repository-URL mit der Landscape-Konfiguration.
configSchemaOpenAPI-Schema, das vom Benutzer konfigurierbare Optionen definiert. Diese Werte werden der Landscape als Umgebungsvariablen übergeben.
secretsSchemaOpenAPI-Schema, das geheime Werte definiert (z. B. Passwörter). Diese Werte werden im Secrets-Vault der Landscape gesetzt.
detailsSchemaOpenAPI-Schema, das zur Laufzeit bereitgestellte Details definiert, die nach der Provisionierung angezeigt werden. Siehe Standard-Landscape-Details.
versionsVersionen 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:

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

Config Schema in den Service-Einstellungen

vorsicht

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

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

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

Provider-Scopes

Beim Erstellen eines Providers kannst du dessen Sichtbarkeitsbereich definieren:

Scope-TypBeschreibung
globalVerfügbar für alle Teams in der Codesphere-Instanz. Erfordert Cluster-Admin-Berechtigungen.
teamNur 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

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

FormatAuswirkung in der Oberfläche
uri, hostnameIm 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_*.
passwordIm 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

Das Format password stellt im Dialog zum Erstellen eines Services ein maskiertes Eingabefeld dar

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.