Zum Hauptinhalt springen
Version: Weekly Build

Wie du dein eigenes REST-Backend erstellst

info

Diese Funktion ist derzeit nur auf Codesphere Private Cloud verfügbar.

Die Managed Services-Architektur von Codesphere ist auf Erweiterbarkeit ausgelegt. Codesphere enthält grundlegende Managed Service-Anbieter wie PostgreSQL und S3, jedoch können auch eigene benutzerdefinierte Anbieter integriert werden, indem ein RESTful-Backend implementiert wird, das der Codesphere Managed Service Adapter API-Spezifikation entspricht.

Dies ermöglicht die Bereitstellung beliebiger Ressourcen – sei es eine Datenbank bei einem bestimmten Cloud-Anbieter, ein Altsystem oder ein internes benutzerdefiniertes Tool – und deren Verwaltung direkt über die Codesphere-UI und die CLI.

Neben den in diesem Artikel beschriebenen RESTful-Provider-Backends können auch benutzerdefinierte Anbieter auf Basis von Codesphere-Landscapes implementiert werden.

Architekturübersicht

Der Codesphere-Marketplace fungiert als zentrale Steuerungsebene für verschiedene Managed Service-Anbieter. Wenn ein Nutzer einen Service bereitstellt, verwaltet Codesphere die zugrunde liegende Infrastruktur nicht selbst. Stattdessen wird eine Anfrage an das konfigurierte Managed Service Backend des Anbieters gesendet. Dieses Backend ist für die tatsächliche Bereitstellung und das Lebenszyklusmanagement der Ressource verantwortlich.

Managed Service Architecture

Entsprechende barrierefreie Textbeschreibung

  1. Nutzeraktion: Ein Nutzer fordert über die UI oder die API einen neuen Service an (z. B. „My Custom DB“).
  2. Marketplace Internal API: Codesphere speichert den gewünschten Zustand für diesen Service (Plan, Config, Secrets) in seiner Datenbank.
  3. Managed Service Backends: Codesphere gleicht dein Backend über einen Polling-Mechanismus mit dem gewünschten Zustand eines Service ab. Auf Anfrage liefert dein Backend den aktuellen Status (z. B. Verbindungszeichenfolgen, Health-Status) zurück, der dem Nutzer von Codesphere angezeigt wird.
  4. Zugrunde liegende Infrastruktur: Dein Backend empfängt die Anfrage und führt die notwendigen Aktionen aus (z. B. Aufruf einer AWS-API, Starten eines Kubernetes-Pods, Ausführen eines Skripts).

Der API-Vertrag

Um mit Codesphere zu integrieren, muss dein Backend die folgenden REST-Endpunkte implementieren. Alle Service-IDs sind von Codesphere generierte UUIDs.

1. Service erstellen (POST /)

Codesphere ruft diesen Endpunkt auf, wenn ein neuer Service angefordert wird.

  • Methode: POST
  • Body: Ein vollständiges Objekt mit id, plan, config und secrets.
  • Antwort: 201 Created (leerer Body) oder Fehler.
// Beispiel für den Request Body
{
"id": "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11",
"plan": {
"parameters": { "storage": 1000 }
},
"config": {
"version": "14.2",
"myCustomParameter": "value"
},
"secrets": {
"password": "super-secret-password"
}
}

2. Service aktualisieren (PATCH /{id})

Codesphere ruft diesen Endpunkt auf, wenn ein Nutzer die Konfiguration ändert, den Plan skaliert, Secrets rotiert oder eine Abweichung zwischen dem gemeldeten Status eines Service und dem gewünschten Zustand erkannt wird.

  • Methode: PATCH
  • Pfadparameter: id (UUID)
  • Body: Ein partielles Objekt, das nur die zu aktualisierenden Felder enthält.
  • Antwort: 204 No Content oder Fehler.
// Beispiel für den Request Body
{
"plan": {
"parameters": { "storage": 2000 }
}
}

3. Status abrufen (GET /?id=...)

Codesphere fragt diesen Endpunkt regelmäßig ab, um den Status der Services zu synchronisieren. Er dient sowohl als „List“- als auch als „Get Details“-Operation.

  • Methode: GET
  • Query-Parameter: id (wiederholbar, z. B. ?id=uuid-1&id=uuid-2). Werden keine IDs angegeben, sollen alle bekannten Service-IDs zurückgegeben werden.
  • Antwort: 200 OK mit einer Zuordnung von ID zu Status-Objekten.

Das Status-Objekt sollte details (schreibgeschützte Informationen wie Hostnamen, Verbindungszeichenfolgen) enthalten, die dem Nutzer angezeigt werden.

// Beispiel für den Response Body
{
"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11": {
"plan": { "parameters": { "storage": 1000 } },
"config": { "version": "14.2" },
"details": {
"hostname": "10.0.0.5",
"port": 5432,
"ready": true
}
}
}

4. Service löschen (DELETE /{id})

Codesphere ruft dies auf, wenn ein Nutzer den Service löscht. Dein Backend sollte die Ressourcen deprovisionieren und sicherstellen, dass keine Daten erhalten bleiben, sofern dies nicht beabsichtigt ist.

  • Methode: DELETE
  • Pfadparameter: id (UUID)
  • Antwort: 204 No Content oder Fehler.

5. Backup erstellen (PUT /backups/{id}) (optional)

Codesphere ruft diesen Endpunkt auf, um ein bedarfsgesteuertes oder geplantes Backup auszulösen, sofern dein Anbieter Backups unterstützt. Nutzerseitige Details zur Konfiguration und Wiederherstellung von Backups findest du im Leitfaden Managed Service Backups.

  • Methode: PUT
  • Pfadparameter: id (UUID, der eindeutige Bezeichner für dieses Backup)
  • Body: TakeBackupArgs mit msId, config (Konfiguration des Backup-Speichers), secrets (Zugangsdaten des Backup-Speichers) und dem optionalen retentionDays (Ganzzahl, die konfigurierte Aufbewahrungsdauer für das Backup).
  • Antwort: 202 Accepted

Backends können mit retentionDays auf zwei Arten umgehen:

  • Retention-aware (aufbewahrungsbewusst): retentionDays wird verwendet, um die Aufbewahrungsrichtlinie des Backups direkt im zugrunde liegenden Speicher festzulegen (z. B. eine S3-Object-Lifecycle-Regel). Wenn Codesphere später „Delete Backup“ aufruft, sollte dies als Bestätigung behandelt werden, ohne eine tatsächliche Löschung auszulösen.
  • Nicht retention-aware (Standard): retentionDays wird ignoriert. Codesphere übernimmt die Verwaltung des Lebenszyklus, indem es „Delete Backup“ aufruft, sobald die Aufbewahrungsdauer abgelaufen ist.

6. Backup löschen (DELETE /backups/{id}) (optional)

Codesphere ruft dies auf, wenn die Aufbewahrungsdauer erreicht ist, um alte Backups zu bereinigen.

Bei nicht retention-aware Backends sollte dies das Backup löschen. Bei retention-aware Backends, die ihre eigene Aufbewahrungsrichtlinie über retentionDays verwalten, dient dieser Aufruf lediglich als Bestätigung, ohne dass eine weitere Aktion erforderlich ist.

  • Methode: DELETE
  • Pfadparameter: id (UUID des Backups)
  • Body: TakeBackupArgs mit msId, config, secrets und optional retentionDays.
  • Antwort: 202 Accepted

7. Backup-Status abrufen (POST /backups/{id}/status) (optional)

Codesphere fragt diesen Endpunkt regelmäßig ab, um zu bestätigen, ob ein Backup erfolgreich abgeschlossen wurde.

  • Methode: POST
  • Pfadparameter: id (UUID des Backups)
  • Antwort: 200 OK mit einem JSON-Body { "exists": boolean, "error"?: string }. Ist exists gleich true, ist das Backup abgeschlossen. Ist es false, ist es noch in Bearbeitung. Der error-String kann verwendet werden, um einen Fehler zu melden.

Beispiel: Postgres-Backend

Nachfolgend findest du eine partielle OpenAPI-Spezifikation für unser internes PostgreSQL-Backend. Sie zeigt, wie wir die Schemas config, plan und details definieren.

openapi: "3.1.0"
info:
title: Postgres Managed Service Provider
version: "1.0"

paths:
/postgres:
post:
summary: Create a new postgres service
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Postgres"
responses:
201:
description: Postgres service created

get:
summary: Get status of postgres services.
parameters:
- name: id
in: query
schema:
type: array
items:
type: string
format: uuid
responses:
200:
content:
application/json:
schema:
oneOf:
- type: array # List all IDs if no query param
items:
type: string
format: uuid
- type: array # List status if query param provided
items:
$ref: "#/components/schemas/PostgresStatus"

/postgres/{id}:
delete:
summary: Delete a postgres service
responses:
204:
description: Postgres service deleted
patch:
summary: Update a postgres service
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Postgres"
responses:
204:
description: Postgres service updated

/postgres/backups/{id}:
put:
summary: Take a backup of a postgres service
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/TakeBackupArgs"
responses:
202:
description: Backup request accepted
delete:
summary: Delete a backup of a postgres service
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/TakeBackupArgs"
responses:
202:
description: Backup deletion accepted

/postgres/backups/{id}/status:
post:
summary: Get the status of a postgres backup
responses:
200:
description: Backup status
content:
application/json:
schema:
$ref: "#/components/schemas/BackupStatus"

components:
schemas:
BackupStatus:
type: object
required:
- exists
properties:
exists:
type: boolean
error:
type: string

TakeBackupArgs:
type: object
properties:
msId:
type: string
format: uuid
config:
type: object
secrets:
type: object
retentionDays:
type: integer
description: Configured retention period in days. Present on all backup requests. Retention-aware backends use this to manage their own lifecycle; others may ignore it.

PostgresConfig:
type: object
properties:
version:
type: string
enum: ["15.14", "14.19"]
databaseName:
type: string

PostgresPlan:
type: object
properties:
parameters:
$ref: "#/components/schemas/PostgresPlanParameters"

PostgresPlanParameters:
type: object
properties:
storage:
type: integer
description: Storage size in MB (not MiB)
cpu:
type: integer
description: CPU in tenths
memory:
type: integer
description: Memory in MB (not MiB)

PostgresDetails:
type: object
properties:
hostname:
type: string
dsn:
type: string
ready:
type: boolean

PostgresStatus:
type: object
properties:
config:
$ref: "#/components/schemas/PostgresConfig"
details:
$ref: "#/components/schemas/PostgresDetails"

PostgresSecrets:
type: object
properties:
superuserPassword:
type: string
userPassword:
type: string

Postgres:
type: object
properties:
id:
type: string
format: uuid
config:
$ref: "#/components/schemas/PostgresConfig"
plan:
$ref: "#/components/schemas/PostgresPlan"
secrets:
$ref: "#/components/schemas/PostgresSecrets"

Sicherheitsüberlegungen

Da dein Backend sensible Daten (Secrets) empfängt und kritische Infrastrukturänderungen durchführt, hat Sicherheit oberste Priorität.

  1. Netzwerkisolierung: Idealerweise sollte dein Backend nur aus der gewünschten Codesphere-Umgebung heraus erreichbar sein, z. B. durch Beschränkung des Zugriffs auf die Codesphere Egress-IPs.
  2. Authentifizierung: Implementiere einen Mechanismus mit einem gemeinsamen Secret oder einer Token-Authentifizierung. Codesphere kann so konfiguriert werden, dass dieses Token bei jeder Anfrage im Authorization-Header gesendet wird.
  3. Eingabevalidierung: Validiere alle eingehenden config- und plan-Parameter strikt anhand deines Schemas, um Injection-Angriffe oder ungültige Zustände zu verhindern.

Registrierung des Backends

Sobald dein Backend entwickelt und bereitgestellt ist, musst du es in deiner Codesphere Private Cloud-Umgebung registrieren, damit es für Nutzer verfügbar ist.

Dazu muss die config.yaml deiner Installation aktualisiert werden, um die Definition deines neuen Service-Anbieters sowie die Backend-Konfiguration einzuschließen. Konkret musst du das Array codesphere.managedServices sowie den Abschnitt managedServiceBackends anpassen.

Detaillierte Anweisungen zur Registrierung deines Backends findest du unter Managed Services in der Private Cloud-Dokumentation.