Zum Hauptinhalt springen
Version: Weekly Build
sidebar_position: 6
title: Ein eigenes REST-Backend erstellen
slug: /managed-services/create-custom-rest-backend

So erstellst du dein eigenes REST-Backend

info

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

Die Managed-Services-Architektur von Codesphere ist auf Erweiterbarkeit ausgelegt. Codesphere enthält zwar grundlegende Managed-Service-Provider wie PostgreSQL und S3, aber du kannst auch eigene, benutzerdefinierte Provider integrieren, indem du ein RESTful-Backend implementierst, das der Codesphere Managed Service Adapter API Specification entspricht.

Dadurch kannst du beliebige Ressourcen bereitstellen – sei es eine Datenbank bei einem bestimmten Cloud-Anbieter, ein Legacy-System oder ein internes Custom-Tool – und diese direkt über die Codesphere-UI und die CLI verwalten.

Neben den in diesem Artikel beschriebenen RESTful-Provider-Backends kannst du auch benutzerdefinierte Provider implementieren, die auf Codesphere-Landscapes basieren.

Architekturübersicht

Der Codesphere Marketplace fungiert als zentrale Steuerungsebene für unterschiedliche Managed-Service-Provider. Wenn ein Nutzer einen Service bereitstellt, verwaltet Codesphere die zugrunde liegende Infrastruktur nicht selbst. Stattdessen sendet Codesphere eine Anfrage an das konfigurierte Managed Service Backend des Providers. Dieses Backend ist für die eigentliche Bereitstellung und das Lifecycle-Management der Ressource verantwortlich.

Managed-Service-Architektur

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 Services ab. Auf Anfrage gibt dein Backend den aktuellen Status zurück (z. B. Connection-Strings, Health-Status), den Codesphere dem Nutzer anzeigt.
  4. Zugrunde liegende Infrastruktur: Dein Backend empfängt die Anfrage und führt die notwendigen Aktionen aus (z. B. Aufruf einer AWS-API, Start eines Kubernetes-Pods, Ausführung 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 angefragt wird.

  • Methode: POST
  • Body: Ein vollständiges Objekt mit id, plan, config und secrets.
  • Response: 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 Services und dem gewünschten Zustand feststellt.

  • Methode: PATCH
  • Pfadparameter: id (UUID)
  • Body: Ein partielles Objekt, das nur die zu aktualisierenden Felder enthält.
  • Response: 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 von Services zu synchronisieren. Dies 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.
  • Response: 200 OK mit einer Zuordnung von ID zu Status-Objekten.

Das Status-Objekt sollte details enthalten (schreibgeschützte Informationen wie Hostnamen, Connection-Strings), 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 diesen Endpunkt 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)
  • Response: 204 No Content oder Fehler.

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

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

  • Methode: PUT
  • Pfadparameter: id (UUID, eindeutiger Bezeichner für dieses Backup)
  • Body: TakeBackupArgs mit msId, config (Konfiguration des Backup-Speichers), secrets (Zugangsdaten des Backup-Speichers) und dem optionalen retentionDays (Ganzzahl, konfigurierter Aufbewahrungszeitraum für das Backup).
  • Response: 202 Accepted

Backends können mit retentionDays auf eine von zwei Arten umgehen:

  • Retention-aware (aufbewahrungsbewusst): Verwende retentionDays, 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, behandle dies als Bestätigung und nicht als Auslöser für eine tatsächliche Löschung.
  • Nicht retention-aware (Standard): Ignoriere retentionDays. Codesphere übernimmt das Lifecycle-Management, indem es „Delete Backup“ aufruft, sobald der Aufbewahrungszeitraum abgelaufen ist.

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

Codesphere ruft diesen Endpunkt auf, wenn der Aufbewahrungszeitraum 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 und erfordert keine weitere Aktion.

  • Methode: DELETE
  • Pfadparameter: id (UUID des Backups)
  • Body: TakeBackupArgs mit msId, config, secrets und optional retentionDays.
  • Response: 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)
  • Response: 200 OK mit einem JSON-Body { "exists": boolean, "error"?: string }. Ist exists gleich true, ist das Backup abgeschlossen. Bei false ist es noch in Bearbeitung. Der String error 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"

Sicherheitsaspekte

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

  1. Netzwerkisolation: Idealerweise sollte dein Backend nur von der gewünschten Codesphere-Umgebung aus erreichbar sein, z. B. indem der Zugriff auf die Codesphere-Egress-IPs beschränkt wird.
  2. Authentifizierung: Implementiere einen Mechanismus mit Shared Secret oder Token-Authentifizierung. Codesphere sendet das für deinen Provider konfigurierte Secret unverändert als Authorization-Header bei jeder Anfrage, sodass dein Backend diesen Header lediglich mit dem gleichen Wert vergleichen muss. Wo dieses Secret konfiguriert wird, erfährst du unter Rest-basierte Provider.
  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 wird.

Dazu musst du in der config.yaml deiner Installation deine neue Service-Provider-Definition sowie die Backend-Konfiguration ergänzen. Konkret musst du das Array codesphere.managedServices sowie den Abschnitt managedServiceBackends anpassen.

Eine ausführliche Anleitung zur Registrierung deines Backends findest du unter Managed Services in der Private-Cloud-Dokumentation.