Kubernetes API Delphi-client uit OpenAPI

Elk Kubernetes-cluster beschrijft zijn eigen API, en sgcOpenAPI maakt van die beschrijving een Pascal-unit die je vanuit Delphi aanroept. Dit is de grootste van de publieke specificaties op deze pagina’s, en de enige waarbij de keuze van het brondocument het resultaat echt verandert, dus deze pagina zegt uit welk endpoint je moet genereren en wat de twee bekende beperkingen zijn.

Kubernetes + sgcOpenAPI

Alles hieronder is gemeten door de generator over de Kubernetes-specificaties te draaien en het resultaat te compileren, niet geschat.

Genereer hieruit

De OpenAPI 3-documenten per groep onder /openapi/v3, één voor één. Dit is de weg die een correcte client oplevert.

Niet hieruit

Het samengevoegde document /openapi/v2. Het is Swagger 2.0, het converteert en genereert, maar er komen twee dingen verkeerd uit. Allebei staan hieronder beschreven.

Authenticatie

Genereer met -a 2 en zet Authentication.Token.BearerToken, waarmee het ServiceAccount-token als Authorization: Bearer wordt verstuurd.

Basis-URL

Kubernetes geeft geen serverhost op, dus geef -u https://cluster:6443 mee bij het genereren of roep SetBaseURL aan tijdens runtime.

/openapi/v3 is een index, geen document

Dit is het eerste om te begrijpen. Een cluster serveert niet één OpenAPI 3-bestand. /openapi/v3 geeft een lijst met paden per groep terug, en elke groep en versie is een apart document op een eigen URL.

# één document per API-groep en versie, 65 stuks in een standaardcluster
> 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

Zo gegenereerd geeft de core-groep 113 paths, 248 methodes en 293 modelklassen in een unit van 42.705 regels, en de apps-groep 38 paths, 77 methodes en 180 modelklassen in 17.061 regels. Allebei compileren ze schoon op RAD Studio 12 voor Win32, met niets op het library-pad behalve de map Source van sgcOpenAPI. Eén unit per groep is bovendien prettiger in het gebruik dan één enorme unit, en je genereert alleen de groepen die je echt aanroept.

Dezelfde documenten staan in de Kubernetes-repository onder api/openapi-spec/v3/, dus je kunt genereren uit een ingecheckt bestand in plaats van uit een draaiend cluster, en het resultaat in versiebeheer houden.

Lijst pods op in een namespace

Kubernetes schrijft zijn operation-id’s al als geldige identifiers, dus de gegenereerde methode houdt de naam uit de specificatie.

uses
  k8s_core_v1;   // de unit die je zojuist genereerde

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, dan de queryparameters in opgegeven volgorde
  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;

De modelklassen dragen de volledige Kubernetes-namen, dus een pod is TsgcOpenAPI_io_k8s_api_core_v1_Pod_Class met Metadata, Spec en Status, en de lijst is TsgcOpenAPI_io_k8s_api_core_v1_PodList_Class met een getypeerde Items. Een booleaanse queryparameter die Kubernetes als optioneel opgeeft wordt TsgcOpenAPIBoolean, waarvan de waarde oapiBoolNull betekent dat de parameter uit de URL blijft in plaats van als false te worden meegestuurd.

Schaal een deployment

Waar Kubernetes een request-body met een benoemd schema beschrijft, en dat doet het meestal, neemt de gegenereerde methode de getypeerde klasse in plaats van een string.

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;

Over het hele Kubernetes-oppervlak is de verdeling bijna gelijk, ruwweg de helft van de request-bodies komt binnen als getypeerde klasse zoals TsgcOpenAPI_io_k8s_api_autoscaling_v1_Scale_Class en ruwweg de helft als string, afhankelijk van of het document het schema een naam geeft.

Wat de gegenereerde units bevatten

De unit spiegelt het document waar je op wijst, dus de dekking is precies de groep en versie die je hebt gegenereerd.

Workloads

apis/apps/v1 voor Deployments, StatefulSets, DaemonSets en ReplicaSets. apis/batch/v1 voor Jobs en CronJobs. api/v1 voor Pods en ReplicationControllers.

Services en networking

api/v1 voor Services, Endpoints, ConfigMaps en Secrets. apis/networking.k8s.io/v1 voor Ingress en NetworkPolicy. apis/discovery.k8s.io/v1 voor EndpointSlices.

Storage, RBAC en policy

apis/storage.k8s.io/v1, apis/rbac.authorization.k8s.io/v1, apis/policy/v1 en apis/admissionregistration.k8s.io/v1, elk een eigen document en elk een eigen unit.

Custom resources

Een cluster met CRD’s erop serveert ze op hun eigen paden per groep, dus de index op /openapi/v3 noemt ze naast de ingebouwde groepen en ze genereren op dezelfde manier.

Elk model als klasse

ObjectMeta, PodSpec, PodStatus, Container, de condition-types, de list-types. Alleen de core-groep levert er al 293.

De documentatie uit de spec

De Kubernetes-veldbeschrijvingen komen door als Pascal-commentaar boven elke methode en property, en dat is voor een groot deel waarom de units zo lang zijn.

Wat we vonden door het te draaien

Twee ervan zijn eigen aan het samengevoegde Swagger 2.0-document, en ze zijn de reden dat deze pagina je vertelt om in plaats daarvan per groep te genereren.

Parameters op pathniveau gaan verloren in het v2-document

Kubernetes geeft namespace en pretty één keer op het path-item op en verwijst ernaar met een $ref. Gegenereerd uit /openapi/v2 bereiken die twee de methode nooit, dus listCoreV1NamespacedPod komt binnen zonder argument aNamespace en de URL houdt zijn plaatshouder {namespace}. Gegenereerd uit het /openapi/v3-document voor dezelfde groep staat het argument er wel. Gebruik de v3-documenten.

De CRD-groep compileert niet

apis/apiextensions.k8s.io/v1 beschrijft JSONSchemaProps.enum als een array van een schema dat helemaal geen type opgeeft, dus de generator schrijft TArray<> en de compiler wijst dat af. Het gaat om twee regels in de unit. Sla die groep over, of genereer het samengevoegde document met die 14 operaties meegegeven aan -x en ook aan -p, wat de klasse verwijdert, waarna de hele unit wel bouwt.

Het samengevoegde document is enorm

602 paths, 1.202 methodes en een unit van ongeveer 197.000 regels en 13 MB. Hij wordt in minder dan een seconde gelezen en gegenereerd, maar de editor van de IDE is traag bij een bestand van dat formaat. De units per groep zijn daar een fractie van, 42.705 regels voor de core-groep en 17.061 voor apps.

Het cluster-CA vertrouw je zelf

De meeste clusters gebruiken een zelfondertekend CA, dus de TLS-handshake mislukt totdat je zegt wat je vertrouwt. De gegenereerde client biedt OnSSLVerifyPeer, OnSSLGetHandler en OnSSLAfterCreateHandler, en daar installeer je de CA-bundel van het cluster uit je kubeconfig.

Watches zijn geen enumerables

watch=true en een containerlog met follow=true zijn langlopende chunked responses. De gegenereerde methode is een gewoon verzoek dat terugkeert wanneer de response eindigt, dus een live watch bouw je op TsgcHTTP1Client in plaats van dat de gegenereerde client hem voor je streamt.

Gebonden ServiceAccount-tokens verlopen

Ze zijn sinds Kubernetes 1.21 in tijd beperkt. Lees /var/run/secrets/kubernetes.io/serviceaccount/token vanuit het cluster opnieuw, of roep van buitenaf de TokenRequest-API aan, en wijs Authentication.Token.BearerToken opnieuw toe. De client houdt vast wat je hem als laatste hebt gegeven.

Vanuit de blog

OpenAPI Delphi-parser

Hoe de lezer echte specificaties afhandelt, en wat hij in Warnings noteert wanneer hij iets niet kan honoreren.

Lees post →

OpenAPI-client en parser

De begeleidende post die de gegenereerde client introduceert en de lezer waarop hij is gebouwd.

Lees post →

sgcOpenAPI 2026.6

Release-notes voor de huidige versie, met de generator-opties en de wijzigingen in de lezer.

Lees post →
De beste deal: All-AccessElk eSeGeCe-product, inclusief Premium-ondersteuning, vanaf €1,059 per jaar.
Bekijk de All-Access-prijzen

Stuur Kubernetes vandaag nog aan vanuit Delphi

sgcOpenAPI levert de lezer, de code-generator, de OpenAPI-server en kant-en-klare SDK’s voor Amazon, Azure, Google en Microsoft. Eén product, drie tiers, geprijsd per gebruiker in plaats van per functie.