@canonical/jujulib
Version:
Juju API client
234 lines (222 loc) • 11.2 kB
TypeScript
/**
This library is the JavaScript Juju API client. Use the connect function to
get access to the API. See the examples/ folder for detailed examples on how
to use this API.
*/
import { Bakery } from "@canonical/macaroon-bakery";
import AdminV3, { AuthUserInfo, LoginResult, RedirectInfoResult } from "./facades/admin/AdminV3.js";
import { MacaroonObject } from "@canonical/macaroon-bakery/dist/macaroon";
import type { Callback, CloseCallback, JujuRequest } from "../generator/interfaces";
import { ClassType, Facade, GenericFacade } from "./types.js";
import AdminV4 from "./custom-facades/AdminV4.js";
export declare const CLIENT_VERSION = "3.3.2";
export interface ConnectOptions {
bakery?: Bakery | null;
closeCallback: CloseCallback;
debug?: boolean;
facades?: (ClassType<Facade> | GenericFacade)[];
loginWithSessionCookie?: boolean;
onWSCreated?: (ws: WebSocket) => void;
wsclass?: typeof WebSocket;
}
export interface ConnectionInfo {
controllerTag?: string;
serverVersion?: string;
servers?: object[];
user?: AuthUserInfo;
getFacade?: (name: string) => Facade;
}
export type ExcludeProps<O> = Partial<Record<keyof O, never>>;
export type Credentials = {
username: string;
password: string;
} | {
macaroons: MacaroonObject[][];
};
/**
Connect to the Juju controller or model at the given URL.
@param url The WebSocket URL of the Juju controller or model.
@param options Connections options, including:
- facades (default=[]): the list of facade classes to include in the API
connection object. Those classes are usually auto-generated and can be
found in the facades directory of the project. When multiple versions of
the same facade are included, the most recent version supported by the
server is made available as part of the connection object;
- debug (default=false): when enabled, all API messages are logged at debug
level;
- wsclass (default=W3C browser native WebSocket): the WebSocket class to
use for opening the connection and sending/receiving messages. Server
side, require('websocket').w3cwebsocket can be used safely, as it
implements the W3C browser native WebSocket API;
- bakery (default: null): the bakery client to use when macaroon discharges
are required, in the case an external user is used to connect to Juju;
see <https://www.npmjs.com/package/macaroon-bakery>;
- closeCallback: a callback to be called with the exit code when the
connection is closed.
@param callback Called when the connection is made, the
callback receives an error and a client object. If there are no errors, the
client can be used to login and logout to Juju. See the docstring for the
Client class for information on how to use the client.
@return This promise will be rejected if there is an error
connecting, or resolved with a new Client instance. Note that the promise
will not be resolved or rejected if a callback is provided.
*/
declare function connect(url: string, options?: ConnectOptions, callback?: Callback<Client>): Promise<Client>;
/**
Connect to the Juju controller or model at the given URL and the authenticate
using the given credentials.
@param url The WebSocket URL of the Juju controller or model.
@param credentials An object with the user and password fields for
userpass authentication or the macaroons field for bakery authentication.
If an empty object is provided a full bakery discharge will be attempted
for logging in with macaroons. Any necessary third party discharges are
performed using the bakery instance provided in the options (see below).
@param options Connections options, including:
- facades (default=[]): the list of facade classes to include in the API
connection object. Those classes are usually auto-generated and can be
found in the facades directory of the project. When multiple versions of
the same facade are included, the most recent version supported by the
server is made available as part of the connection object;
- debug (default=false): when enabled, all API messages are logged at debug
level;
- wsclass (default=W3C browser native WebSocket): the WebSocket class to
use for opening the connection and sending/receiving messages. Server
side, require('websocket').w3cwebsocket can be used safely, as it
implements the W3C browser native WebSocket API;
- bakery (default: null): the bakery client to use when macaroon discharges
are required, in the case an external user is used to connect to Juju;
see <https://www.npmjs.com/package/macaroon-bakery>;
- closeCallback: a callback to be called with the exit code when the
connection is closed.
@return This promise will be rejected if there is an error
connecting, or resolved with a new {conn, logout} object. Note that the
promise will not be resolved or rejected if a callback is provided.
*/
declare function connectAndLogin(url: string, options: ConnectOptions, credentials?: Credentials, clientVersion?: string): Promise<{
conn?: Connection;
logout: typeof Client.prototype.logout;
}>;
/**
Returns a URL that is to be used to connect to a supplied model uuid on the
supplied controller host.
@param controllerHost The url that's used to connect to the controller.
The `connectAndLogin` method handles redirections so the public URL is fine.
@param modelUUID The UUID of the model to connect to.
@returns The fully qualified wss URL to connect to the model.
*/
declare function generateModelURL(controllerHost: string, modelUUID: string): string;
/**
A Juju API client allowing for logging in and get access to facades.
@param ws The WebSocket instance already connected to a Juju
controller or model.
@param options Connections options. See the connect documentation
above for a description of available options.
*/
declare class Client {
_transport: Transport;
_bakery?: Bakery | null;
_facades: (ClassType<Facade> | GenericFacade)[];
_admin: AdminV3 | AdminV4;
_loginWithSessionCookie: boolean;
constructor(ws: WebSocket, options: ConnectOptions);
/**
Log in to Juju.
@param credentials An object with the user and password fields for
userpass authentication or the macaroons field for bakery authentication.
If an empty object is provided a full bakery discharge will be attempted
for logging in with macaroons. Any necessary third party discharges are
performed using the bakery instance originally provided to connect().
@param clientVersion The Juju controller version to target.
@return This promise will be rejected if there is an error
connecting, or resolved with a new connection instance. Note that the
promise will not be resolved or rejected if a callback is provided.
*/
login(credentials?: Credentials, clientVersion?: string): Promise<Connection | undefined>;
/**
Log out from Juju.
@param callback Called when the logout process completes and the
connection is closed, the callback receives the close code and optionally
another callback. It is responsibility of the callback to call the
provided callback if present.
*/
logout(callback?: (code: number, callback: CloseCallback) => void): void;
/**
Report whether the given error is a redirection error from Juju.
@param err The error returned by the login request.
@returns Whether the given error is a redirection error.
*/
isRedirectionError(err: unknown): err is RedirectionError;
}
declare class RedirectionError extends Error {
servers: RedirectInfoResult["servers"];
caCert: string;
constructor(info: RedirectInfoResult);
}
/**
A transport providing the ability of sending and receiving WebSocket messages
to and from Juju controllers and models.
@param ws The WebSocket instance already connected to a Juju
controller or model.
@param closeCallback A callback to be called after the transport
closes the connection. The callback receives the close code.
@param debug When enabled, all API messages are logged at debug
level.
*/
export declare class Transport {
_ws: WebSocket;
_counter: number;
_callbacks: Record<number, Callback<unknown>>;
_closeCallback: CloseCallback;
_debug: boolean;
constructor(ws: WebSocket, closeCallback: CloseCallback, debug: boolean);
/**
Send a message to Juju.
@param req A Juju API request, typically in the form of an object
like {type: 'Client', request: 'DoSomething', version: 1, params: {}}.
The request must not be already serialized and must not include the
request id, as those are responsibilities of the transport.
@param resolve Function called when the request is successful.
@param reject Function called when the request is not successful.
*/
write<R>(req: JujuRequest, resolve: (value: R) => void, reject: (error: Error) => void): void;
/**
Close the transport, and therefore the connection.
@param callback Called after the transport is closed, the
callback receives the close code and optionally another callback. It is
responsibility of the callback to call the provided callback if present.
*/
close(callback?: (code: number, callback: CloseCallback) => void): void;
/**
Handle responses arriving from Juju.
@param data: the raw response from Juju, usually as a JSON encoded
string.
*/
_handle(data: string): void;
}
/**
A connection to a Juju controller or model. This is the object users use to
perform Juju API calls, as it provides access to all available facades
(conn.facades), to a transport connected to Juju (conn.transport) and to
information about the connected Juju server (conn.info).
@param transport The Transport instance used to communicate with
Juju. The transport is available exposed to users via the transport
property of the connection instance. See the Transport docstring for
information on how to use the transport, typically calling transport.write.
@param facades The facade classes provided in the facades property
of the options provided to the connect function. When the connection is
instantiated, the matching available facades as declared by Juju are
instantiated and access to them is provided via the facades property of the
connection.
@param loginResult The result to the Juju login request. It includes
information about the Juju server and available facades. This info is made
available via the info property of the connection instance.
*/
declare class Connection {
facades: {
[k: string]: Facade;
};
transport: Transport;
info: ConnectionInfo;
constructor(transport: Transport, facades: (ClassType<Facade> | GenericFacade)[], loginResult: LoginResult);
}
export { Client, connect, connectAndLogin, Connection, generateModelURL, RedirectionError, };