/** * Copyright (c) Freelens Authors. All rights reserved. * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ import { KubeStatus } from "@freelensapp/kube-object"; import type { KubeJsonApiData, KubeJsonApiDataFor, KubeObject, KubeObjectConstructor, KubeObjectMetadata, KubeObjectScope, Scale, ScaleCreateOptions } from "@freelensapp/kube-object"; import type { LogFunction } from "@freelensapp/logger"; import type { RequestInit, Response } from "@freelensapp/node-fetch"; import type { Disposer } from "@freelensapp/utilities"; import type { Patch } from "rfc6902"; import type { PartialDeep } from "type-fest"; import type { KubeJsonApi } from "./kube-json-api"; import type { IKubeWatchEvent } from "./kube-watch-event"; /** * The options used for creating a `KubeApi` */ export interface KubeApiOptions = KubeJsonApiDataFor> extends DerivedKubeApiOptions { /** * base api-path for listing all resources, e.g. "/api/v1/pods" * * Must be provided either here or under `objectConstructor.apiBase` * @deprecated should be specified by `objectConstructor` */ apiBase?: string; /** * The constructor for the kube objects returned from the API */ objectConstructor: KubeObjectConstructor; /** * Must be provided either here or under `objectConstructor.namespaced` * @deprecated should be specified by `objectConstructor` */ isNamespaced?: boolean; /** * Must be provided either here or under `objectConstructor.kind` * @deprecated should be specified by `objectConstructor` */ kind?: string; } export interface DerivedKubeApiOptions { /** * If the API uses a different API endpoint (e.g. apiBase) depending on the cluster version, * fallback API bases can be listed individually. * * The first (existing) API base is used in the requests, if apiBase is not found. * * This option only has effect if {@link DerivedKubeApiOptions.checkPreferredVersion} is `true`. */ fallbackApiBases?: string[]; /** * This option is useful for protecting against newer versions on the same apiBase from being * used. So that if a certain type only supports `v1`, or `v2` of some kind and then the `v3` * version becomes the `preferredVersion` on the server but still has `v2` then the `v2` version * will be used instead. * * This can help to prevent crashes in the future if the shape of a kind sufficiently changes. * * The order is important. It should be sorted and the first entry should be the most preferable. * * This option only has effect if {@link DerivedKubeApiOptions.checkPreferredVersion} is `true` */ allowedUsableVersions?: Partial>; /** * If `true` then will check all declared apiBases against the kube api server * for the first accepted one. * * @default false */ checkPreferredVersion?: boolean; /** * The api instance to use for making requests * * @default apiKube */ request?: KubeJsonApi; } export interface KubeApiQueryParams { watch?: boolean | number; resourceVersion?: string; timeoutSeconds?: number; limit?: number; continue?: string; labelSelector?: string | string[]; fieldSelector?: string | string[]; } export interface KubeApiListOptions { namespace?: string; reqInit?: RequestInit; } export interface IKubePreferredVersion { preferredVersion?: { version: string; }; } export interface KubeApiResource { categories?: string[]; group?: string; kind: string; name: string; namespaced: boolean; shortNames?: string[]; singularName: string; storageVersionHash?: string; verbs: string[]; version?: string; } export interface KubeApiResourceList { apiVersion?: string; groupVersion?: string; kind?: string; resources: KubeApiResource[]; } export interface KubeApiResourceVersion { groupVersion: string; version: string; } export interface KubeApiResourceVersionList { apiVersion: string; kind: string; name: string; preferredVersion: KubeApiResourceVersion; versions: KubeApiResourceVersion[]; } export type PropagationPolicy = undefined | "Orphan" | "Foreground" | "Background"; export interface DeleteOptions { /** * The duration in seconds before the object should be deleted. Value must be non-negative integer. * The value zero indicates delete immediately. If this value is nil, the default grace period for the * specified type will be used. * Defaults to a per object value if not specified. zero means delete immediately. */ gracePeriodSeconds?: number; /** * Must be fulfilled before a deletion is carried out. If not possible, a 409 Conflict status will be * returned. */ preconditions?: { /** * Specifies the target ResourceVersion */ resourceVersion?: string; /** * Specifies the target UID. */ uid?: string; }; /** * Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. * Should the dependent objects be orphaned. If true/false, the "orphan" * finalizer will be added to/removed from the object's finalizers list. * Either this field or PropagationPolicy may be set, but not both. */ orphanDependents?: boolean; /** * Whether and how garbage collection will be performed. * Either this field or OrphanDependents may be set, but not both. * The default policy is decided by the existing finalizer set in the * metadata.finalizers and the resource-specific default policy. * Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow * the garbage collector to delete the dependents in the background; * 'Foreground' - a cascading policy that deletes all dependents in the * foreground. */ propagationPolicy?: PropagationPolicy; /** * When present, indicates that modifications should not be * persisted. An invalid or unrecognized dryRun directive will * result in an error response and no further processing of the * request. Valid values are: * - All: all dry run stages will be processed */ dryRun?: string[]; } export type KubeApiWatchCallback = (data: IKubeWatchEvent | null, error: KubeStatus | Response | null | Record) => void; export interface KubeApiWatchOptions> { /** * If the resource is namespaced then the default is `"default"` */ namespace?: string; /** * This will be called when either an error occurs or some data is received */ callback?: KubeApiWatchCallback; /** * This is a way of aborting the request */ abortController?: AbortController; /** * The ID used for tracking within logs */ watchId?: string; /** * @default false */ retry?: boolean; /** * timeout in seconds */ timeout?: number; } export type KubeApiPatchType = "merge" | "json" | "strategic"; export declare const patchTypeHeaders: Record; export interface ResourceDescriptor { /** * The name of the kubernetes resource */ name: string; /** * The namespace that the resource lives in (if the resource is namespaced) * * Note: if not provided and the resource kind is namespaced, then this defaults to `"default"` */ namespace?: string; } export interface SubResourceDescriptor { subResource: string; } export type SpecificResourceDescriptor = { /** * The name of the kubernetes resource */ name: string; } & (Scope extends KubeObjectScope.Cluster ? {} : Scope extends KubeObjectScope.Namespace ? { /** * The namespace that the resource lives in */ namespace: string; } : { namespace?: string; }); export type NamespacedResourceDescriptor = SpecificResourceDescriptor; export type ClusterScopedResourceDescriptor = SpecificResourceDescriptor; export interface DeleteResourceDescriptor extends ResourceDescriptor { /** * This determines how child resources should be handled by kubernetes * * @default "Background" */ propagationPolicy?: PropagationPolicy; /** * Additional options for the delete operation */ deleteOptions?: DeleteOptions; } export interface KubeApiDependencies { logDebug: LogFunction; logInfo: LogFunction; logWarn: LogFunction; logError: LogFunction; readonly maybeKubeApi: KubeJsonApi | undefined; } export declare class KubeApi = KubeJsonApiDataFor> { protected readonly dependencies: KubeApiDependencies; readonly kind: string; readonly apiVersion: string; apiBase: string; apiPrefix: string; apiGroup: string; apiVersionPreferred: string | undefined; readonly apiResource: string; readonly isNamespaced: boolean; readonly objectConstructor: KubeObjectConstructor; protected readonly request: KubeJsonApi; protected readonly resourceVersions: Map; protected readonly watchDisposer: Disposer | undefined; private watchId; protected readonly doCheckPreferredVersion: boolean; protected readonly fullApiPathname: string; protected readonly fallbackApiBases: string[] | undefined; protected readonly allowedUsableVersions: Partial> | undefined; constructor(dependencies: KubeApiDependencies, opts: KubeApiOptions); get apiVersionWithGroup(): string; /** * Returns the latest API prefix/group that contains the required resource. * First tries fullApiPathname, then urls in order from fallbackApiBases. */ private getLatestApiPrefixGroup; protected checkPreferredVersion(): Promise; setResourceVersion(namespace: string | undefined, newVersion: string): void; getResourceVersion(namespace?: string): string | undefined; refreshResourceVersion(params?: KubeApiListOptions): Promise; private computeApiBase; /** * This method differs from {@link formatUrlForNotListing} because this treats `""` as "all namespaces" * NOTE: This is also useful for watching * @param namespace The namespace to list in or `""` for all namespaces */ formatUrlForListing(namespace: string | undefined, query?: Partial): string; /** * Format a URL pathname and query for acting upon a specific resource. */ formatUrlForNotListing({ name, namespace }?: Partial): string; /** * @deprecated use {@link formatUrlForNotListing} or {@link formatUrlForListing} instead */ getUrl(resource?: Partial, query?: Partial): string; protected normalizeQuery(query?: Partial): Partial; protected parseResponse(data: unknown, namespace?: string): Object | Object[] | null; private ensureMetadataSelfLink; list({ namespace, reqInit }?: KubeApiListOptions, query?: KubeApiQueryParams): Promise; get(desc: ResourceDescriptor, query?: KubeApiQueryParams): Promise; create({ name, namespace }: Partial, partialData?: PartialDeep): Promise; update({ name, namespace }: ResourceDescriptor, data: PartialDeep): Promise; /** * An internal method for requesting the `/scale` sub-resource if it exists */ protected getResourceScale(desc: ResourceDescriptor): Promise; /** * An internal method for requesting the `/scale` sub-resource if it exists */ protected scaleResource(desc: ResourceDescriptor, data: ScaleCreateOptions): Promise; patch(desc: ResourceDescriptor, data: PartialDeep): Promise; patch(desc: ResourceDescriptor, data: PartialDeep, strategy: "strategic" | "merge"): Promise; patch(desc: ResourceDescriptor, data: Patch, strategy: "json"): Promise; patch(desc: ResourceDescriptor, data: PartialDeep | Patch, strategy: KubeApiPatchType): Promise; delete({ propagationPolicy, deleteOptions, ...desc }: DeleteResourceDescriptor): Promise, unknown, unknown>>; getWatchUrl(namespace?: string, query?: KubeApiQueryParams): string; watch(opts?: KubeApiWatchOptions): Disposer; protected modifyWatchEvent(event: IKubeWatchEvent>): void; }