/**
* 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 { }