Client Delphi per l'API Kubernetes da OpenAPI

Ogni cluster Kubernetes descrive la propria API, e sgcOpenAPI trasforma quella descrizione in una unit Pascal che chiami da Delphi. È la più grande fra le specifiche pubbliche presenti in queste pagine, ed è quella in cui la scelta del documento sorgente cambia davvero il risultato, quindi questa pagina ti dice da quale endpoint generare e quali sono i due limiti noti.

Kubernetes + sgcOpenAPI

Tutto quello che segue è stato misurato eseguendo il generatore sulle specifiche Kubernetes e compilando il risultato, non sono stime.

Genera da questo

I documenti OpenAPI 3 per gruppo sotto /openapi/v3, uno alla volta. È la strada che produce un client corretto.

Non da questo

Il documento aggregato /openapi/v2. È Swagger 2.0, si converte e si genera, ma due cose escono sbagliate. Sono descritte entrambe più sotto.

Autenticazione

Genera con -a 2 e imposta Authentication.Token.BearerToken, che invia il token del ServiceAccount come Authorization: Bearer.

Base URL

Kubernetes non dichiara nessun host di server, quindi passa -u https://cluster:6443 in fase di generazione oppure chiama SetBaseURL a run time.

/openapi/v3 è un indice, non un documento

È la prima cosa da capire. Un cluster non serve un unico file OpenAPI 3. /openapi/v3 restituisce un elenco di path di gruppo, e ogni gruppo con la sua versione è un documento separato al proprio URL.

# un documento per gruppo e versione API, 65 in un cluster standard
> sgcOpenAPI.exe -i "https://10.0.0.1:6443/openapi/v3/api/v1" \
      -o "k8s_core_v1.pas" -a 2 -u "https://10.0.0.1:6443"

File successfully created k8s_core_v1.pas

> sgcOpenAPI.exe -i "https://10.0.0.1:6443/openapi/v3/apis/apps/v1" \
      -o "k8s_apps_v1.pas" -a 2 -u "https://10.0.0.1:6443"

File successfully created k8s_apps_v1.pas

Generato in questo modo, il gruppo core dà 113 path, 248 metodi e 293 classi di modello in una unit di 42.705 righe, e il gruppo apps dà 38 path, 77 metodi e 180 classi di modello in 17.061 righe. Entrambe compilano pulite su RAD Studio 12 per Win32 con nient'altro nel library path se non la cartella Source di sgcOpenAPI. Una unit per gruppo è anche più comoda da gestire di una unit enorme, e generi solo i gruppi che chiami davvero.

Gli stessi documenti sono pubblicati nel repository di Kubernetes sotto api/openapi-spec/v3/, quindi puoi generare da un file versionato invece che da un cluster attivo e tenere il risultato sotto controllo di versione.

Elenca i pod di un namespace

Kubernetes scrive i propri operation id già come identificatori validi, quindi il metodo generato mantiene il nome della specifica.

uses
  k8s_core_v1;   // la unit appena generata

procedure TfrmK8s.btnPodsClick(Sender: TObject);
var
  oResponse: TsgcOpenAPI_listCoreV1NamespacedPod_Response;
  oPod: TsgcOpenAPI_io_k8s_api_core_v1_Pod_Class;
begin
  GetOpenAPIClient.Authentication.Token.BearerToken := vToken;
  GetOpenAPIClient.SetBaseURL('https://10.0.0.1:6443');

  // aNamespace, aPretty, poi i parametri di query in ordine di dichiarazione
  oResponse := GetOpenAPIClient.listCoreV1NamespacedPod('production',
    '', oapiBoolNull, '', '', 'app=api,tier=backend');
  try
    if oResponse.IsSuccessful then
      for oPod in oResponse.Successful.Items do
        memoLog.Lines.Add(Format('%-30s %s %s',
          [oPod.Metadata.Name, oPod.Status.Phase, oPod.Status.HostIP]))
    else
      memoLog.Lines.Add(IntToStr(oResponse.ResponseCode) + ' ' +
        oResponse.ResponseError);
  finally
    oResponse.Free;
  end;
end;

Le classi di modello portano i nomi Kubernetes completi, quindi un pod è TsgcOpenAPI_io_k8s_api_core_v1_Pod_Class con Metadata, Spec e Status, e la lista è TsgcOpenAPI_io_k8s_api_core_v1_PodList_Class con un Items tipizzato. Un parametro di query booleano che Kubernetes dichiara opzionale diventa TsgcOpenAPIBoolean, il cui valore oapiBoolNull significa che il parametro viene omesso dall'URL invece di essere inviato come false.

Fai lo scale di un deployment

Dove Kubernetes descrive il body della request con uno schema nominato, e di solito lo fa, il metodo generato accetta la classe tipizzata invece di una stringa.

uses
  k8s_apps_v1;

var
  oRead: TsgcOpenAPI_readAppsV1NamespacedDeploymentScale_Response;
  oWrite: TsgcOpenAPI_replaceAppsV1NamespacedDeploymentScale_Response;
begin
  oRead := GetOpenAPIClient.readAppsV1NamespacedDeploymentScale(
    'api', 'production');
  try
    if not oRead.IsSuccessful then
      raise Exception.Create(oRead.ResponseError);

    oRead.Successful.Spec.Replicas := 5;

    oWrite := GetOpenAPIClient.replaceAppsV1NamespacedDeploymentScale(
      'api', 'production', oRead.Successful);
    try
      memoLog.Lines.Add(IntToStr(oWrite.ResponseCode));
    finally
      oWrite.Free;
    end;
  finally
    oRead.Free;
  end;
end;

Sull'intera superficie di Kubernetes la divisione è quasi a metà, all'incirca metà dei request body arriva come classe tipizzata, per esempio TsgcOpenAPI_io_k8s_api_autoscaling_v1_Scale_Class, e all'incirca metà come stringa, a seconda che il documento dia o meno un nome allo schema.

Cosa contengono le unit generate

La unit rispecchia il documento a cui la punti, quindi la copertura è esattamente il gruppo e la versione che hai generato.

Workload

apis/apps/v1 per Deployment, StatefulSet, DaemonSet e ReplicaSet. apis/batch/v1 per Job e CronJob. api/v1 per Pod e ReplicationController.

Servizi e rete

api/v1 per Service, Endpoint, ConfigMap e Secret. apis/networking.k8s.io/v1 per Ingress e NetworkPolicy. apis/discovery.k8s.io/v1 per gli EndpointSlice.

Storage, RBAC e policy

apis/storage.k8s.io/v1, apis/rbac.authorization.k8s.io/v1, apis/policy/v1 e apis/admissionregistration.k8s.io/v1, ognuno un documento a sé e ognuno una unit a sé.

Risorse custom

Un cluster con dei CRD installati li serve ai loro path di gruppo, quindi l'indice su /openapi/v3 li elenca accanto ai gruppi predefiniti e si generano allo stesso modo.

Ogni modello come classe

ObjectMeta, PodSpec, PodStatus, Container, i tipi di condizione, i tipi lista. Il solo gruppo core ne produce 293.

La documentazione della specifica

Le descrizioni dei campi Kubernetes arrivano come commenti Pascal sopra ogni metodo e ogni proprietà, ed è buona parte del motivo per cui le unit sono lunghe.

Cosa abbiamo trovato provandolo

Due di questi punti sono specifici del documento Swagger 2.0 aggregato, e sono il motivo per cui questa pagina ti dice di generare per gruppo.

I parametri a livello di path si perdono dal documento v2

Kubernetes dichiara namespace e pretty una volta sola sul path item e li richiama con un $ref. Generati da /openapi/v2, quei due non arrivano mai al metodo, quindi listCoreV1NamespacedPod si presenta senza l'argomento aNamespace e l'URL si tiene il segnaposto {namespace}. Generato dal documento /openapi/v3 dello stesso gruppo, l'argomento c'è. Usa i documenti v3.

Il gruppo dei CRD non compila

apis/apiextensions.k8s.io/v1 descrive JSONSchemaProps.enum come array di uno schema che non dichiara alcun tipo, quindi il generatore emette TArray<> e il compilatore lo rifiuta. Sono due righe nella unit. Salta quel gruppo, oppure genera il documento aggregato passando anche quelle 14 operazioni a -x e a -p, così la classe sparisce e l'intera unit compila.

Il documento aggregato è enorme

602 path, 1.202 metodi e una unit di circa 197.000 righe e 13 MB. Si legge e si genera in meno di un secondo, ma l'editor dell'IDE è lento con un file di quelle dimensioni. Le unit per gruppo sono una frazione, 42.705 righe per il gruppo core e 17.061 per apps.

La CA del cluster la scegli tu

La maggior parte dei cluster usa una CA self signed, quindi l'handshake TLS fallisce finché non dici cosa considerare attendibile. Il client generato espone OnSSLVerifyPeer, OnSSLGetHandler e OnSSLAfterCreateHandler, ed è lì che installi il bundle della CA del cluster preso dal tuo kubeconfig.

I watch non sono enumerabili

watch=true e il log di un container con follow=true sono risposte chunked di lunga durata. Il metodo generato è una richiesta normale che ritorna quando la risposta finisce, quindi un watch dal vivo è qualcosa che costruisci su TsgcHTTP1Client, non qualcosa che il client generato ti trasmette in streaming.

I token ServiceAccount vincolati scadono

Hanno una durata limitata da Kubernetes 1.21 in poi. Rileggi /var/run/secrets/kubernetes.io/serviceaccount/token dall'interno del cluster, oppure chiama l'API TokenRequest dall'esterno, e riassegna Authentication.Token.BearerToken. Il client conserva l'ultimo valore che gli hai dato.

Dal blog

Parser OpenAPI Delphi

Come il reader gestisce specifiche reali, e cosa registra in Warnings quando non riesce a rispettare qualcosa.

Leggi il post →

Client + parser OpenAPI

Il post di accompagnamento che presenta il client generato e il reader su cui è costruito.

Leggi il post →

sgcOpenAPI 2026.6

Note di rilascio della versione attuale, con le opzioni del generatore e le novità del reader.

Leggi il post →
La scelta più conveniente: All-AccessTutti i prodotti eSeGeCe, con Supporto Premium incluso, a partire da €1,059/anno.
Vedi i prezzi All-Access

Pilota oggi Kubernetes da Delphi

sgcOpenAPI include il reader, il code generator, il server OpenAPI e gli SDK già pronti per Amazon, Azure, Google e Microsoft. Un prodotto, tre tier, con prezzo a postazione invece che a funzionalità.