basic share/unshare sdk functions (#893)

This commit is contained in:
Michael Quigley 2025-03-03 13:44:07 -05:00
parent 48bbc681f9
commit a17e461bf4
No known key found for this signature in database
GPG Key ID: 9B60314A9DD20A62
3 changed files with 203 additions and 1 deletions

View File

@ -1,5 +1,6 @@
import {Command} from "commander";
import {loadRoot} from "@openziti/zrok/dist/environment";
import {createShare, deleteShare, PROXY_BACKEND_MODE, PUBLIC_SHARE_MODE, ShareRequest} from "@openziti/zrok/dist/share";
const program = new Command();
@ -11,6 +12,17 @@ program
.action(() => {
let root = loadRoot();
console.log("root.isEnabled", root.isEnabled());
let req = new ShareRequest(PUBLIC_SHARE_MODE, PROXY_BACKEND_MODE, "http://localhost:8000");
req.frontends = ["public"];
createShare(root, req)
.then(shr => {
console.log(shr);
deleteShare(root, shr);
})
.catch(ex => {
console.log("exception", ex);
});
});
program.parse(process.argv);

View File

@ -1,19 +1,58 @@
import {environmentFile, metadataFile} from "./paths";
import * as fs from "node:fs";
import {Configuration} from "./api";
const ENVIRONMENT_V = "v0.4";
export class Root {
metadata: Metadata;
config: Config|undefined;
environment: Environment|undefined;
constructor(metadata: Metadata, environment: Environment|undefined) {
this.metadata = metadata;
this.config = undefined;
this.environment = environment;
}
public apiConfiguration = (): Configuration => {
let apiEndpoint = this.apiEndpoint();
if(this.isEnabled()) {
return new Configuration({basePath: apiEndpoint.endpoint + "/api/v1", apiKey: this.environment?.accountToken})
} else {
return new Configuration({basePath: apiEndpoint.endpoint + "/api/v1"});
}
}
public apiEndpoint = (): ApiEndpoint => {
let endpoint = "https://api-v1.zrok.io";
let from = "binary";
if(this.config?.apiEndpoint !== "") {
endpoint = this.config?.apiEndpoint!;
from = "config";
}
let env = process.env.ZROK_API_ENDPOINT;
if(env != null) {
endpoint = env;
from = "ZROK_API_ENDPOINT";
}
if(this.isEnabled()) {
endpoint = this.environment?.apiEndpoint!;
from = "env";
}
return new ApiEndpoint(endpoint, from);
}
public hasConfig = (): boolean => {
return this.config !== undefined;
}
public isEnabled = (): boolean => {
return this.environment != undefined;
return this.environment !== undefined;
}
}
@ -39,6 +78,24 @@ export class Environment {
}
}
export class Config {
apiEndpoint: string;
constructor(apiEndpoint: string) {
this.apiEndpoint = apiEndpoint;
}
}
export class ApiEndpoint {
endpoint: string;
from: string;
constructor(endpoint: string, from: string) {
this.endpoint = endpoint;
this.from = from;
}
}
export const loadRoot = (): Root => {
if(rootExists()) {
let metadata = loadMetadata();

View File

@ -0,0 +1,133 @@
import {Root} from "./environment";
import {
ShareApi,
ShareRequest as ApiShareRequest,
ShareRequestBackendModeEnum,
ShareRequestShareModeEnum,
UnshareRequest
} from "./api";
export type ShareMode = string;
export const PRIVATE_SHARE_MODE: ShareMode = "private";
export const PUBLIC_SHARE_MODE: ShareMode = "public";
export type BackendMode = string;
export const PROXY_BACKEND_MODE: BackendMode = "proxy";
export const TCP_TUNNEL_BACKEND_MODE: BackendMode = "tcpTunnel";
export const UDP_TUNNEL_BACKEND_MODE: BackendMode = "udpTunnel";
export type PermissionMode = string;
export const OPEN_PERMISSION_MODE = "open";
export const CLOSED_PERMISSION_MODE = "closed";
export class ShareRequest {
reserved: boolean;
uniqueName: string|undefined;
backendMode: BackendMode;
shareMode: ShareMode;
target: string;
frontends: string[]|undefined;
basicAuth: string[]|undefined;
oauthProvider: string|undefined;
oauthEmailAddressPatterns: string[]|undefined;
oauthAuthorizationCheckInterval: string|undefined;
permissionMode: PermissionMode;
accessGrants: string[]|undefined;
constructor(shareMode: ShareMode, backendMode: BackendMode, target: string) {
this.reserved = false;
this.uniqueName = undefined;
this.backendMode = backendMode;
this.shareMode = shareMode;
this.target = target;
this.frontends = undefined;
this.basicAuth = undefined;
this.oauthProvider = undefined;
this.oauthEmailAddressPatterns = undefined;
this.oauthAuthorizationCheckInterval = undefined;
this.permissionMode = CLOSED_PERMISSION_MODE;
this.accessGrants = undefined;
}
}
export class Share {
shareToken: string;
frontendEndpoints: string[]|undefined;
constructor(shareToken: string, frontendEndpoints: string[]|undefined) {
this.shareToken = shareToken;
this.frontendEndpoints = frontendEndpoints;
}
}
export const createShare = async (root: Root, request: ShareRequest): Promise<Share> => {
if(!root.isEnabled()) {
throw new Error("environment is not enabled; enable with 'zrok enable' first!");
}
let req: ApiShareRequest;
switch(request.shareMode) {
case PRIVATE_SHARE_MODE:
req = toPrivateApiShareRequest(root, request);
break;
case PUBLIC_SHARE_MODE:
req = toPublicApiShareRequest(root, request);
break;
default:
throw new Error("unknown share mode '" + request.shareMode + "'");
}
let shr = await new ShareApi(root.apiConfiguration()).share({body: req})
.catch(resp => {
throw new Error("unable to create share: " + resp);
});
return new Share(shr.shareToken!, shr.frontendProxyEndpoints);
}
export const deleteShare = (root: Root, shr: Share): void => {
if(!root.isEnabled()) {
throw new Error("environment is not enable; enable with 'zrok enable' first!");
}
let req: UnshareRequest = {
envZId: root.environment?.zId!,
shareToken: shr.shareToken
};
new ShareApi(root.apiConfiguration()).unshare({body: req})
.catch(resp => {
throw new Error("unable to delete share: " + resp);
});
}
const toPrivateApiShareRequest = (root: Root, request: ShareRequest): ApiShareRequest => {
return {
envZId: root.environment?.zId,
shareMode: ShareRequestShareModeEnum.Private,
backendMode: toApiBackendMode(request.backendMode),
backendProxyEndpoint: request.target,
};
}
const toPublicApiShareRequest = (root: Root, request: ShareRequest): ApiShareRequest => {
return {
envZId: root.environment?.zId,
shareMode: ShareRequestShareModeEnum.Public,
frontendSelection: request.frontends,
backendMode: toApiBackendMode(request.backendMode),
backendProxyEndpoint: request.target,
authScheme: "none",
};
}
const toApiBackendMode = (mode: BackendMode): ShareRequestBackendModeEnum|undefined => {
switch(mode) {
case PROXY_BACKEND_MODE:
return ShareRequestBackendModeEnum.Proxy;
case TCP_TUNNEL_BACKEND_MODE:
return ShareRequestBackendModeEnum.TcpTunnel;
case UDP_TUNNEL_BACKEND_MODE:
return ShareRequestBackendModeEnum.UdpTunnel;
default:
return undefined;
}
}