import * as plugins from './plugins.js'; export type TClientType = 'api' | 'ci' | 'coreflow' | 'cli' | 'serverconfig'; import { Image } from './classes.image.js'; import { Service } from './classes.service.js'; export class CloudlyApiClient { private cloudlyUrl: string; private registerAs: string; public typedrouter = new plugins.typedrequest.TypedRouter(); public typedsocketClient: plugins.typedsocket.TypedSocket; // Subjects public configUpdateSubject = new plugins.smartrx.rxjs.Subject< plugins.servezoneInterfaces.requests.config.IRequest_Cloudly_Coreflow_PushClusterConfig['request'] >(); public serverActionSubject = new plugins.smartrx.rxjs.Subject< plugins.servezoneInterfaces.requests.server.IRequest_TriggerServerAction['request'] >(); constructor(optionsArg: { registerAs: TClientType; cloudlyUrl?: string; }) { this.registerAs = optionsArg.registerAs; this.cloudlyUrl = optionsArg?.cloudlyUrl || process.env.CLOUDLY_URL || 'https://cloudly.layer.io:443'; console.log( `creating LoleCloudlyClient: registering as ${this.registerAs} and target url ${this.cloudlyUrl}` ); this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler('pushClusterConfig', async (dataArg) => { this.configUpdateSubject.next(dataArg); return {}; }) ); this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler('triggerServerAction', async (dataArg) => { this.serverActionSubject.next(dataArg); return { actionConfirmed: true, }; }) ); } public async start() { this.typedsocketClient = await plugins.typedsocket.TypedSocket.createClient( this.typedrouter, this.cloudlyUrl ); console.log( `CloudlyClient connected to cloudly at ${this.cloudlyUrl}. Remember to get an identity.` ); } public async stop() { await this.typedsocketClient.stop(); } public identity: plugins.servezoneInterfaces.data.IIdentity; public async getIdentityByToken( token: string, optionsArg?: { tagConnection?: boolean; statefullIdentity?: boolean; } ): Promise { optionsArg = Object.assign({}, { tagConnection: false, statefullIdentity: true, }, optionsArg); const identityRequest = this.typedsocketClient.createTypedRequest( 'getIdentityByToken' ); console.log(`trying to get identity from cloudly with supplied jumpCodeArg: ${token}`); const response = await identityRequest.fire({ token: token, }); console.log('got identity response'); const identity = response.identity; if (optionsArg.tagConnection) { this.typedsocketClient.addTag('identity', identity); } if (optionsArg.statefullIdentity) { this.identity = identity; } return identity; } /** * will use statefull identity by default */ public async getClusterConfigFromCloudlyByIdentity( identityArg: plugins.servezoneInterfaces.data.IIdentity = this.identity ): Promise { const clusterConfigRequest = this.typedsocketClient.createTypedRequest( 'getClusterConfig' ); const response = await clusterConfigRequest.fire({ identity: identityArg, }); return response.configData; } /** * will use statefull identity by default */ public async getServerConfigFromCloudlyByIdentity( identityArg: plugins.servezoneInterfaces.data.IIdentity = this.identity ): Promise { const serverConfigRequest = this.typedsocketClient.createTypedRequest( 'getServerConfig' ); const response = await serverConfigRequest.fire({ identity: identityArg, serverId: '', // TODO: get server id here }); return response.configData; } /** * gets a certificate for a domain used by a service */ public async getCertificateForDomain(optionsArg: { domainName: string; type: plugins.servezoneInterfaces.requests.certificate.IRequest_Any_Cloudly_GetCertificateForDomain['request']['type']; identity?: plugins.servezoneInterfaces.data.IIdentity; }): Promise { optionsArg.identity = optionsArg.identity || this.identity; if (!optionsArg.identity) { throw new Error('identity is required. Either provide one or login first.'); } const typedCertificateRequest = this.typedsocketClient.createTypedRequest( 'getCertificateForDomain' ); const typedResponse = await typedCertificateRequest.fire({ identity: this.identity, // do proper auth here domainName: optionsArg.domainName, type: optionsArg.type, }); return typedResponse.certificate; } public images = { // Images getImageById: async (imageIdArg: string) => { return Image.getImageById(this, imageIdArg); }, getImages: async () => { return Image.getImages(this); }, createImage: async (optionsArg: Parameters[1]) => { return Image.createImage(this, optionsArg); } } public services = { // Services getServiceById: async (serviceIdArg: string) => { return Service.getServiceById(this, serviceIdArg); }, getServices: async () => { return Service.getServices(this); }, createService: async (optionsArg: Parameters[1]) => { return Service.createService(this, optionsArg); } } }