/** * Kubernetes and other dynamic plugin SDK utilities. * * @remarks * This package provides various React focused dynamic plugin SDK utilities, * including APIs for working with Kubernetes and integrating with Redux. * * @packageDocumentation */ /// import type { ActionType as ActionType_2 } from 'typesafe-actions'; import type { AnyAction } from 'redux'; import type { AnyObject } from '@openshift/dynamic-plugin-sdk'; import { Context } from 'react'; import { CustomError } from '@openshift/dynamic-plugin-sdk'; import type { Dispatch } from 'redux'; import type { EitherNotBoth } from '@openshift/dynamic-plugin-sdk'; import type { Map as Map_2 } from 'immutable'; import type { PluginStore } from '@openshift/dynamic-plugin-sdk'; import * as React_2 from 'react'; import { default as React_3 } from 'react'; import type { ResourceFetch } from '@openshift/dynamic-plugin-sdk'; import type { Store } from 'redux'; export declare enum ActionType { ReceivedResources = "resources", SetResourcesInFlight = "setResourcesInFlight", SetBatchesInFlight = "setBatchesInFlight", StartWatchK8sObject = "startWatchK8sObject", StartWatchK8sList = "startWatchK8sList", ModifyObject = "modifyObject", StopWatchK8s = "stopWatchK8s", Errored = "errored", Loaded = "loaded", BulkAddToList = "bulkAddToList", UpdateListFromWS = "updateListFromWS", FilterList = "filterList" } export declare type APIActions = { setResourcesInFlight: (isInFlight: boolean) => void; setBatchesInFlight: (isInFlight: boolean) => void; receivedResources: (resource: DiscoveryResources) => void; }; /** * Initializes the host application to work with Kubernetes and related SDK utilities. * Add this at app-level to make use of app's redux store and pass configurations prop needed to initialize the app, preferred to have it under Provider. * It checks for store instance if present or not. * If the store is there then the reference is persisted to be used in SDK else it creates a new store and passes it to the children with the provider * * @example * ```tsx * return ( * * * * * * ) * ``` */ export declare const AppInitSDK: React_2.FC; export declare type AppInitSDKProps = { configurations: { apiDiscovery?: InitAPIDiscovery; apiPriorityList?: string[]; appFetch: UtilsConfig['appFetch']; pluginStore: PluginStore; wsAppSettings: UtilsConfig['wsAppSettings']; }; }; export declare type BulkMessageHandler = GenericHandler; export declare type CloseHandler = GenericHandler; export declare const commonFetch: (url: string, requestInit?: RequestInit | undefined, timeout?: number | undefined, isK8sAPIRequest?: boolean | undefined) => Promise; export declare const commonFetchJSON: { (url: string, requestInit?: RequestInit | undefined, timeout?: number | undefined, isK8sAPIRequest?: boolean | undefined): Promise; put(url: string, data: unknown, requestInit?: RequestInit | undefined, timeout?: number | undefined, isK8sAPIRequest?: boolean | undefined): Promise; post(url: string, data: unknown, requestInit?: RequestInit | undefined, timeout?: number | undefined, isK8sAPIRequest?: boolean | undefined): Promise; patch(url: string, data: unknown, requestInit?: RequestInit | undefined, timeout?: number | undefined, isK8sAPIRequest?: boolean | undefined): Promise; delete(url: string, data?: unknown, requestInit?: RequestInit | undefined, timeout?: number | undefined, isK8sAPIRequest?: boolean | undefined): Promise; }; export declare const commonFetchText: (url: string, requestInit?: RequestInit | undefined, timeout?: number | undefined, isK8sAPIRequest?: boolean | undefined) => Promise; export declare const createAPIActions: (dispatch: Dispatch) => APIActions; /** * Data is provided potentially by .destroy() caller. */ export declare type DestroyHandler = GenericHandler; export declare type DiscoveryResources = { adminResources: string[]; allResources: string[]; configResources: K8sModelCommon[]; clusterOperatorConfigResources: K8sModelCommon[]; models: K8sModelCommon[]; namespacedSet: Set; safeResources: string[]; groupVersionMap: { [key: string]: { versions: string[]; preferredVersion: string; }; }; }; export declare type ErrorHandler = GenericHandler; export declare type FilterValue = Partial<{ selected: string[]; all: string[]; }>; export declare type GenericHandler = (data: T) => void; /** * @returns the activeWorkspace as a string or null */ export declare function getActiveWorkspace(): string | null; export declare type GetGroupVersionKindForModel = (model: K8sModelCommon) => K8sResourceIdentifier; /** * Builds a k8s resource URL to the provided model, augmented with the resource or query metadata. * @param model - the model of the resource you want to connect to * @param resource - inspected if you provide it for metadata attributes * @param queryOptions - additional and alternative configuration for the URL * @param queryOptions.ns - namespace, if omitted resource.metadata.namespace * @param queryOptions.name - name, if omitted resource.metadata.name * @param queryOptions.path - additional path you want on the end * @param queryOptions.queryParams - any additional query params you way want * @param isCreate - boolean indicating if the resulting URL will be used for resource creation */ export declare const getK8sResourceURL: (model: K8sModelCommon, resource?: K8sResourceCommon | undefined, queryOptions?: QueryOptions, isCreate?: boolean) => string; /** * Get the {@link UtilsConfig} reference. * * Throws an error if the reference isn't already set. */ export declare const getUtilsConfig: () => UtilsConfig; /** * @deprecated Use K8sResourceIdentifier type instead. Support for type GroupVersionKind will be removed in a future release. * @see K8sResourceIdentifier * GroupVersionKind unambiguously identifies a kind. * https://godoc.org/k8s.io/apimachinery/pkg/runtime/schema#GroupVersionKind * TODO: Change this to a regex-type if it ever becomes a thing (https://github.com/Microsoft/TypeScript/issues/6579) */ export declare type GroupVersionKind = string; export declare type InitAPIDiscovery = (store: Store>, preferenceList?: string[]) => void; export declare const initAPIDiscovery: InitAPIDiscovery; /** * Validates if the provided unknown data is of the K8sStatus type. * @param data - the unknown data to check. * @returns true if data is of the K8sStatus type, otherwise false. */ export declare const isK8sStatus: (data: unknown) => data is K8sStatus; /** * Checks if the {@link UtilsConfig} is set. */ export declare const isUtilsConfigSet: () => boolean; export declare const k8sCreateResource: ({ model, resource, queryOptions, fetchOptions, }: K8sResourceUpdateOptions) => Promise; export declare const k8sDeleteResource: ({ model, payload, queryOptions, fetchOptions, }: K8sResourceDeleteOptions) => Promise; export declare const k8sGetResource: ({ model, queryOptions, fetchOptions, }: K8sResourceReadOptions) => Promise; export declare type K8sGroupVersionKind = { group?: string; version: string; kind: string; }; export declare const k8sListResource: ({ model, queryOptions, fetchOptions, }: K8sResourceListOptions) => Promise>; export declare const k8sListResourceItems: (options: K8sResourceListOptions) => Promise; export declare type K8sModelCommon = K8sResourceIdentifier & { plural: string; propagationPolicy?: 'Foreground' | 'Background'; verbs?: K8sVerb[]; shortNames?: string[]; crd?: boolean; namespaced?: boolean; }; export declare const k8sPatchResource: ({ model, patches, queryOptions, fetchOptions, }: K8sResourcePatchOptions) => Promise; export declare type K8sResourceBaseOptions = { model: K8sModelCommon; queryOptions?: TQueryOptions; fetchOptions?: Partial<{ requestInit: RequestInit & { wsPrefix?: string; pathPrefix?: string; }; timeout: number; }>; }; export declare type K8sResourceCommon = K8sResourceIdentifier & Partial<{ metadata: Partial<{ annotations: Record; clusterName: string; creationTimestamp: string; deletionGracePeriodSeconds: number; deletionTimestamp: string; finalizers: string[]; generateName: string; generation: number; labels: Record; managedFields: unknown[]; name: string; namespace: string; ownerReferences: OwnerReference[]; resourceVersion: string; uid: string; }>; spec: { selector?: Selector | MatchLabels; [key: string]: unknown; }; status: { [key: string]: unknown; }; data: { [key: string]: unknown; }; }>; export declare type K8sResourceDeleteOptions = K8sResourceBaseOptions & { payload?: AnyObject; }; export declare type K8sResourceIdentifier = { apiGroup?: string; apiVersion: string; kind: string; }; /** * @deprecated Use GetGroupVersionKindForModel type instead. Support for type K8sResourceKindReference will be removed in a future release. * @see GetGroupVersionKindForModel * The canonical, unique identifier for a Kubernetes resource type. * Maintains backwards-compatibility with references using the `kind` string field. */ export declare type K8sResourceKindReference = GroupVersionKind | string; export declare type K8sResourceListOptions = K8sResourceBaseOptions>; export declare type K8sResourceListResult = { apiVersion: string; items: TResource[]; metadata: { resourceVersion: string; continue: string; }; }; export declare type K8sResourcePatchOptions = K8sResourceBaseOptions & { patches: Patch[]; }; export declare type K8sResourceReadOptions = K8sResourceBaseOptions; export declare type K8sResourceUpdateOptions = K8sResourceBaseOptions & { resource: TResource; }; export declare type K8sState = Map_2; /** * K8s status object used when Kubernetes cannot handle a request. */ export declare type K8sStatus = K8sResourceIdentifier & { code: number; message: string; reason: string; status: 'Success' | 'Failure'; }; /** * Error class used when Kubernetes cannot handle a request. */ export declare class K8sStatusError extends CustomError { readonly status: K8sStatus; constructor(status: K8sStatus); } export declare const k8sUpdateResource: ({ model, resource, queryOptions, fetchOptions, }: K8sResourceUpdateOptions) => Promise; export declare type K8sVerb = 'create' | 'get' | 'list' | 'update' | 'patch' | 'delete' | 'deletecollection' | 'watch'; export declare type MatchExpression = { key: string; operator: Operator | string; values?: string[]; value?: string; }; export declare type MatchLabels = { [key: string]: string; }; /** * The WebSocket data can be returned in an object state or in the raw string response passed. * * This is configured through `jsonParse` options flag. * @see WebSocketOptions */ export declare type MessageDataType = AnyObject | string; export declare type MessageHandler = GenericHandler; export declare type OpenHandler = GenericHandler; export declare enum Operator { Exists = "Exists", DoesNotExist = "DoesNotExist", In = "In", NotIn = "NotIn", Equals = "Equals", NotEqual = "NotEqual", GreaterThan = "GreaterThan", LessThan = "LessThan", NotEquals = "NotEquals" } export declare type OwnerReference = { apiVersion: string; kind: string; name: string; uid: string; controller?: boolean; blockOwnerDeletion?: boolean; }; export declare type Patch = { op: string; path: string; value?: unknown; }; export declare type Query = { [key: string]: unknown; }; export declare type QueryOptions = Partial<{ ns: string; name: string; path: string; queryParams: QueryParams; }>; export declare type QueryParams = Partial<{ watch: string; labelSelector: string; fieldSelector: string; resourceVersion: string; pretty: string; dryRun: string; fieldManager: string; fieldValidation: string; [key: string]: string; }>; /** * Renders a Redux.Provider for each `core.redux-provider` extension. * Should be rendered near the root of the application. */ export declare const ReduxExtensionProvider: React_2.FC; export declare type ResourcesObject = { [key: string]: K8sResourceCommon | K8sResourceCommon[]; }; /** * Dynamic Plugin SDK Redux store reducers * * If the app uses Redux, these can be spread into the root of your store to provide an integrated SDK. * If the app does not use Redux, these will be provided via the SDK Redux Store. */ export declare const SDKReducers: Readonly<{ k8s: (state: K8sState, action: { type: import("../actions/k8s").ActionType.StartWatchK8sObject; payload: { id: string; }; } | { type: import("../actions/k8s").ActionType.StartWatchK8sList; payload: { id: string; query: Query; }; } | { type: import("../actions/k8s").ActionType.ModifyObject; payload: { id: string; k8sObjects: K8sResourceCommon; }; } | { type: import("../actions/k8s").ActionType.StopWatchK8s; payload: { id: string; }; } | { type: import("../actions/k8s").ActionType.Errored; payload: { id: string; k8sObjects: unknown; }; } | { type: import("../actions/k8s").ActionType.Loaded; payload: { id: string; k8sObjects: K8sResourceCommon[]; }; } | { type: import("../actions/k8s").ActionType.BulkAddToList; payload: { id: string; k8sObjects: K8sResourceCommon[]; }; } | { type: import("../actions/k8s").ActionType.UpdateListFromWS; payload: { id: string; k8sObjects: { type: "ADDED" | "DELETED" | "MODIFIED"; object: K8sResourceCommon; }[]; }; } | { type: import("../actions/k8s").ActionType.FilterList; payload: { id: string; name: string; value: Partial<{ selected: string[]; all: string[]; }>; }; } | { type: import("../actions/k8s").ActionType.ReceivedResources; payload: { resources: DiscoveryResources; }; } | { type: import("../actions/k8s").ActionType.SetResourcesInFlight; payload: { isInFlight: boolean; }; } | { type: import("../actions/k8s").ActionType.SetBatchesInFlight; payload: { isInFlight: boolean; }; }) => K8sState; }>; export declare type Selector = Partial<{ matchLabels: MatchLabels; matchExpressions: MatchExpression[]; [key: string]: unknown; }>; /** * @param workspace - the string name of the workspace you wish to set as active */ export declare function setActiveWorkspaceLocalStorage(workspace: string): void; /** * Set the {@link UtilsConfig} reference. * * This must be done before using any of the Kubernetes utilities. */ export declare const setUtilsConfig: (c: UtilsConfig) => void; declare enum UpdateEvents { activeWorkspace = "activeWorkspace" } export declare type UseK8sModel = (groupVersionKind: K8sResourceKindReference | K8sGroupVersionKind) => [K8sModelCommon, boolean]; /** * Hook that retrieves the k8s model for provided K8sGroupVersionKind from redux. * @param k8sGroupVersionKind - group, version, kind of k8s resource {@link K8sGroupVersionKind} is preferred alternatively can pass reference for group, version, kind which is deprecated i.e `group~version~kind` {@link K8sResourceKindReference}. * @returns An array with the first item as k8s model and second item as inFlight status * * @example * ```ts * const Component: React.FC = () => { * const [model, inFlight] = useK8sModel({ group: 'app'; version: 'v1'; kind: 'Deployment' }); * return ... * } * ``` */ export declare const useK8sModel: UseK8sModel; export declare type UseK8sModels = () => [{ [key: string]: K8sModelCommon; }, boolean]; /** * Hook that retrieves all current k8s models from redux. * * @returns An array with the first item as the list of k8s model and second item as inFlight status * * @example * ```ts * const Component: React.FC = () => { * const [models, inFlight] = UseK8sModels(); * return ... * } * ``` */ export declare const useK8sModels: UseK8sModels; /** * Hook that retrieves the k8s resource along with status for loaded and error. * @param initResource - options needed to watch for resource. * @param initModel - static model to pull information from when watching a resource. * @param options - WS and fetch options passed down to WSFactory @see {@link WebSocketFactory} and when pulling the first item. * @returns An array with first item as resource(s), second item as loaded status and third item as error state if any. * * @example * ```ts * const Component: React.FC = () => { * const watchRes = { ... } * const [data, loaded, error] = useK8sWatchResource(watchRes, { wsPrefix: 'wss://localhost:1337/foo' }) * return ... * } * ``` */ export declare const useK8sWatchResource: (initResource: WatchK8sResource | null, initModel?: K8sModelCommon | undefined, options?: Partial | undefined) => WatchK8sResult; /** * Hook that retrieves the k8s resources along with their respective status for loaded and error. * @param initResources - resources need to be watched as key-value pair, wherein key will be unique to resource and value will be options needed to watch for the respective resource. * @param initModels - static models to pull information from when watching resources. * @param options - WS and fetch options passed down to WSFactory @see {@link WebSocketFactory} and when pulling the first item. * @returns A map where keys are as provided in initResources and value has three properties data, loaded and error. * * @example * ```ts * const Component: React.FC = () => { * const watchResources = { 'deployment': {...}, 'pod': {...} ... } * const {deployment, pod} = useK8sWatchResources(watchResources, { wsPrefix: 'wss://localhost:1337/foo' }) * return ... * } * ``` */ export declare const useK8sWatchResources: (initResources: WatchK8sResources, initModels?: K8sModelCommon[] | undefined, options?: Partial | undefined) => WatchK8sResults; /** * Hook that retrieves the active workspace from localStorage. The key for the active workspace is * always `sdk/active-workspace` * @returns a value for the activeWorkspace (string | null ) and a setter for updating the active workspace * * @example * ```ts * const Component: React.FC = () => { * const [activeWorkspace, setActiveWorkspace] = useWorkspace(); * * setActiveWorkspace("openshift-dev"); * return ... * } * ``` */ export declare const useWorkspace: () => readonly [string | null, (newWorkspace: string) => void]; export declare type UtilsConfig = { /** * Resource fetch implementation provided by the host application. * * Applications must validate the response before resolving the Promise. * * If the request cannot be completed successfully, the Promise should be rejected * with an appropriate error. */ appFetch: ResourceFetch; /** * Configure the web socket settings for your application. */ wsAppSettings: (options: WebSocketOptions & { wsPrefix?: string; pathPrefix?: string; }) => Promise; }; export declare type WatchK8sResource = EitherNotBoth<{ kind: K8sResourceKindReference; }, { groupVersionKind: K8sGroupVersionKind; }> & { name?: string; namespace?: string; isList?: boolean; selector?: Selector; namespaced?: boolean; limit?: number; fieldSelector?: string; optional?: boolean; partialMetadata?: boolean; }; export declare type WatchK8sResources = { [K in keyof R]: WatchK8sResource; }; export declare type WatchK8sResult = [ data: R, loaded: boolean, loadError: unknown ]; export declare type WatchK8sResults = { [K in keyof R]: WatchK8sResultsObject; }; export declare type WatchK8sResultsObject = { data: R; loaded: boolean; loadError: unknown; }; /** * Configuration that is used to configure WebSockets from a host app perspective. */ export declare type WebSocketAppSettings = { /** * The host to which the web socket will connect to. */ host: string; /** * The sub protocols that you wish to send along with the web socket connection call. */ subProtocols: string[]; /** * An optional function to augment the URL after it's constructed and before it is used by the * web socket. * @param url - The fully qualified URL * @returns - A optionally modified fully qualified URL */ urlAugment?: (url: string) => string; }; /** * WebSocket factory and utility wrapper. */ export declare class WebSocketFactory { /** Unique identifier for the web socket. */ private readonly id; /** Options to configure the web socket with. */ private readonly options; private readonly handlers; private readonly flushCanceler; private readonly bufferMax; private paused; private state; private messageBuffer; private connectionAttempt; private ws; constructor( /** Unique identifier for the web socket. */ id: string, /** Options to configure the web socket with. */ options: WebSocketOptions & { wsPrefix?: string; pathPrefix?: string; }); private reconnect; private connect; private invokeHandlers; private triggerEvent; /** * Sets up a listener to when a message comes through the web socket. * @param fn - The event handler that will be called */ onMessage(fn: MessageHandler): WebSocketFactory; /** * Sets up a listener for when you set `options.bufferMax` to receive multiple messages at once. * @param fn - The event handler that will be called */ onBulkMessage(fn: BulkMessageHandler): WebSocketFactory; /** * Sets up a listener for when an error gets invoked in the web socket response. * @param fn - The event handler that will be called */ onError(fn: ErrorHandler): WebSocketFactory; /** * Sets up a listener for when the web socket opens. * @param fn - The event handler that will be called */ onOpen(fn: OpenHandler): WebSocketFactory; /** * Sets up a listener for when the web socket closes. * @param fn - The event handler that will be called */ onClose(fn: CloseHandler): WebSocketFactory; /** * Sets up a listener for when the web socket is cleaned up and no longer in-use. * @param fn - The event handler that will be called */ onDestroy(fn: DestroyHandler): WebSocketFactory; /** * Pushes the messages through the `onBulkMessage` handlers that have been configured. If no * `onBulkMessage` handlers are set, multiple 'onMessage' callbacks will be invoked for each item. * * Does nothing when paused or has no messages to push out. */ flushMessageBuffer(): void; /** * Pauses the web socket event handlers from being invoked. */ pause(): void; /** * Unpauses the web socket event handlers, messages will be flushed automatically. */ unpause(): void; /** * @returns pausedState - The current pause state */ isPaused(): boolean; /** * Gets the current state of the web socket. */ getState(): WebSocketState; /** * Returns the current buffer size. */ bufferSize(): number; /** * Cleans up the web socket instance and related internal data. */ destroy(eventData?: unknown): void; /** * Send a message through the web socket to the server. * @param data - String like data for the server to consume */ send(data: Parameters[0]): void; } /** * The web socket configuration options. */ export declare type WebSocketOptions = { /** * The path to the resource you wish to watch. */ path: string; /** * Overridable web socket host URL for plugins. Normally set by the application. */ host?: string; /** * Overridable web socket sub protocols for plugins. Normally set by the application. * Note: This is ignored if `host` is not set. */ subProtocols?: string[]; /** * Set to true if you want automatic reconnection if it fails to create or when the web socket * closes. */ reconnect?: boolean; /** * Set to true if you wish to get your data back in JSON format when the web socket sends a message. * Note: If it's not valid JSON, a warning will be logged and you get back the raw message. */ jsonParse?: boolean; /** * Set a maximum buffer to hold onto between `bufferFlushInterval`s. Messages that exceed the * buffer are dropped. * * Unit is in number of messages. */ bufferMax?: number; /** * Configure a duration between messages being flushed out in events. * * Note: If `bufferMax` is not set, this is ignored. * Defaults to 500ms. */ bufferFlushInterval?: number; /** * Set a connection limit for when to give up on the current instance of the web socket. * * If omitted, the web socket will continue to try to reconnect only if you set the `reconnect` * flag. */ timeout?: number; }; /** * States the web socket can be in. */ export declare enum WebSocketState { INIT = "init", OPENED = "open", ERRORED = "error", CLOSED = "closed", DESTROYED = "destroyed" } /** * * The WorkspaceContext is a context for the `workspaceState`. It is used to access the methods * and data used to implement an `activeWorkspace`. * * @example * ``` ts * const { subscribe, unsubscribe, getState, setWorkspaceContext } = useContext(WorkspaceContext); * ``` */ export declare const WorkspaceContext: Context< { getState: () => WorkspaceContextState; setWorkspaceContext: (workspace: string | null) => void; subscribe: (event: UpdateEvents, onUpdate: () => void) => string; unsubscribe: (id: string, event: UpdateEvents) => void; update: (event: UpdateEvents, attributes: Partial) => void; }>; declare type WorkspaceContextState = { activeWorkspace: string | null; }; /** * Context for passing through the activeWorkspace. The context provides the active value * to the `useWorkspace` hook. This context maintains the state of the activeWorkspace while * providing a publish/subscribe model to refresh the kubernetes watches on a workspace change. * * @returns A full context with the activeWorkspace's state and internal update methods * * @example * ``` ts * * ``` */ export declare const WorkspaceProvider: React_3.FC>; export { }