Skip to content

Repository files navigation

managed-services-lib

LicenseCISecurity

Core library for building Codesphere managed-service provider backends. Implement one interface; the library serves it over the Codesphere REST contract.

Not a runnable service. Start from managed-services-template for a working server with an example provider, Dockerfile, and CI.

Install

go get github.com/codesphere-cloud/managed-services-lib

Go 1.26+.

Provider interface

typeProvider[PlanParams, Config, Secrets, Details, UpdateParamsany] interface {
Create(ctx context.Context, reqCreateRequest[PlanParams, Config, Secrets]) errorList(ctx context.Context) ([]model.ServiceID, error)
GetStatus(ctx context.Context, ids []model.ServiceID) (map[model.ServiceID]ServiceStatus[PlanParams, Config, Details], error)
Update(ctx context.Context, reqUpdateRequest[UpdateParams]) errorDelete(ctx context.Context, id model.ServiceID) error
}
typeCreateRequest[PlanParams, Config, Secretsany] struct {
ID model.ServiceIDTeamIDintCustomSubdomain*stringPlanPlanParams// contents of plan.parametersConfigConfigSecretsSecretsRecoverFrom*model.RecoverFrom// set when restoring into a new service
}
typeUpdateRequest[UpdateParamsany] struct {
ID model.ServiceIDTeamIDintCustomSubdomain*stringPause*bool// nil = leave as isParamsUpdateParams// your partial PATCH payload
}

The split between the contract and your provider is visible in the signatures — you never declare the contract's own fields or envelopes yourself:

The contract definesYou define
id, teamId, customSubdomain — fields on the request structPlanParams — contents of plan.parameters
pause on update, and pause in the status responseConfig — contents of config
the plan: {parameters: …} wrapper, unwrapped on the way in and re-wrapped on the way outSecrets — contents of secrets
msId and retentionDays on backup requestsDetails — read-only status data (hostnames, ports, readiness)
the {plan, config, details, pause} status envelope (ServiceStatus)UpdateParams — your partial PATCH payload
HTTP status codes and error mapping

PATCH bodies are partial, so make UpdateParams fields pointers to tell "not sent" from "sent empty".

Build status values with provider.NewServiceStatus(plan, config, details, pause, error)

Embed provider.Base for the shared dependencies (Kubernetes client, logger) and helpers.

Backups are an opt-in capability, generic over the provider's own backup-store schemas:

typeBackups[BackupConfig, BackupSecretsany] interface {
TakeBackup(ctx context.Context, reqBackupRequest[BackupConfig, BackupSecrets]) errorGetBackupStatus(ctx context.Context, reqBackupRequest[BackupConfig, BackupSecrets]) (model.BackupStatus, error)
DeleteBackup(ctx context.Context, reqBackupRequest[BackupConfig, BackupSecrets]) error
}

BackupRequest carries BackupID, ServiceID (the msId field), TeamID, the store's Config and Secrets, and RetentionDays. A provider that supports backups implements Backups and calls RegisterBackupRoutes.

Wiring

cfg, _:=config.Load()
k8s, _:=client.NewKubernetesClient(cfg.Kubeconfig)
logger:=slog.Default()
routes:=map[string]func(*gin.RouterGroup){
"mysvc": func(g*gin.RouterGroup) {
p:=mysvc.NewProvider(k8s, logger)
provider.RegisterRoutes(g, p) // CRUDprovider.RegisterBackupRoutes(g, p) // backups
},
}
server, _:=api.NewServer(cfg, routes)
server.Run()

RegisterRoutes mounts the CRUD endpoints under /api/v1/{name}; RegisterBackupRoutes adds the /backups endpoints for providers that implement Backups.

Detached Jobs

Some operations (backups, restores, migrations) are easier to run as one-shot Kubernetes Jobs, detached from the provider pod.

  • client.JobRunner (also on provider.Base as Jobs) — Run / State / Delete / Replace a one-shot Job, with an optional owned credentials Secret injected via secretKeyRef.
  • provider.ServiceJob / ServiceJobSpec — build a JobSpec with a consistent name (<operation>-<key>) and identity labels; BackupStatusFromJob / OperationStatusFromJob map a Job's state to a status.
spec:=provider.ServiceJobSpec(provider.ServiceJob{
Operation: provider.JobOpBackup, MsID: id, Key: backupID,
Image: img, Command: []string{"/backup"},
Env: env, Secrets: secrets, // whatever your image readsImagePullSecrets: []string{"regcred"}, // for a private registry
})
err:=p.Jobs.Run(ctx, ns, spec)

See the package docs and provider/servicejob_usage_test.go for details.

Configuration

config.Load() reads these environment variables:

VariableDefault
PORT8080HTTP port
API_KEYauth key (off if unset)
KUBECONFIGkubeconfig path (in-cluster if unset)
ENVIRONMENTdevelopmentdevelopment / production

This is framework config only. Provider-specific config (storage class, credentials, image versions) belongs in your provider's constructor.

Development

make test, make lint, make mocks. make all runs everything.

About

Core library for building Codesphere managed service provider backends. Implement the provider interface and the library serves it over the Codesphere REST contract.

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages