UNPKG

@sourceregistry/node-ovsdb

Version:
2 lines 8.18 kB
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("node:fs"),t=require("node:net"),n=require("node:events"),r=require("node:tls");var i=class extends Error{response;constructor(e){super(e.details?`${e.error}: ${e.details}`:e.error),this.name=`OvsdbRpcError`,this.response=e}},a=class extends Error{payload;constructor(e,t){super(e),this.name=`OvsdbProtocolError`,this.payload=t}},o=class extends Error{operationIndex;operation;result;results;constructor(e){super(`Transaction operation ${e.operationIndex} failed: ${e.result.error}`),this.name=`OvsdbTransactionError`,this.operationIndex=e.operationIndex,this.operation=e.operation,this.result=e.result,this.results=e.results}},s=class{stagedOperations=[];get operations(){return this.stagedOperations}add(e){return this.stagedOperations.push(e),e}insert(e){return this.add(e)}select(e){return this.add(e)}update(e){return this.add(e)}mutate(e){return this.add(e)}delete(e){return this.add(e)}wait(e){return this.add(e)}comment(e){return this.add({op:`comment`,comment:e})}assert(e){return this.add({op:`assert`,lock:e})}commit(e=!1){return this.add({op:`commit`,durable:e})}abort(){return this.add({op:`abort`})}},c=class extends n.EventEmitter{timeout;connectionOptions;connectionFactory;socket=null;requestId=1;receiveBuffer=``;pendingRequests=new Map;connected=!1;closeEmitted=!1;constructor(e={}){super(),this.timeout=e.timeout??5e3,this.connectionOptions=l(e),this.connectionFactory=e.connectionFactory}get isConnected(){return this.connected}async connect(){if(this.connected)return this;if(!this.connectionFactory&&this.connectionOptions.transport===`unix`&&!(0,e.existsSync)(this.connectionOptions.socketPath))throw Error(`OVSDB socket not found: ${this.connectionOptions.socketPath}`);let t=this.connectionFactory?this.connectionFactory(this.connectionOptions):u(this.connectionOptions);this.attachSocket(t);let n=this.connectionOptions.transport===`tls`?`secureConnect`:`connect`;return await new Promise((e,r)=>{let i=setTimeout(()=>{s(),this.disposeTransport(Error(`Connection timeout after ${this.timeout}ms`)),r(Error(`Connection timeout after ${this.timeout}ms`))},this.timeout),a=()=>{s(),this.connected=!0,this.closeEmitted=!1,this.emit(`connect`),e()},o=e=>{s(),r(e)},s=()=>{clearTimeout(i),t.off(n,a),t.off(`error`,o)};t.once(n,a),t.once(`error`,o)}),this}async request(e,t=[]){this.assertConnected();let n=this.requestId++,r={method:e,params:t,id:n};return await new Promise((t,i)=>{let a=setTimeout(()=>{this.pendingRequests.delete(n),i(Error(`Request timeout for method: ${e}`))},this.timeout);this.pendingRequests.set(n,{resolve:e=>t(e),reject:i,timeoutId:a}),this.writeMessage(r).catch(e=>{clearTimeout(a),this.pendingRequests.delete(n),i(e)})})}async notify(e,t=[]){this.assertConnected(),await this.writeMessage({method:e,params:t})}async listDbs(){return await this.request(`list_dbs`,[])}async getSchema(e=`Open_vSwitch`){return await this.request(`get_schema`,[e])}async transact(e,t){return await this.request(`transact`,[e,...t])}async transaction(e,t,n={}){let r=new s,i=await t(r),a=[...r.operations],c=n.autoCommit??!0,l=a.some(e=>e.op===`commit`||e.op===`abort`);if(c&&!l&&a.push({op:`commit`,durable:n.durable??!1}),a.length===0)return{value:i,operations:a,results:[]};let u=await this.request(`transact`,[e,...a]);for(let[e,t]of u.entries())if(d(t))throw new o({operationIndex:e,operation:a[e],result:t,results:u});return{value:i,operations:a,results:u}}async cancel(e){return await this.request(`cancel`,[e])}async monitor(e,t,n){return await this.request(`monitor`,[e,t,n])}async monitorCond(e,t,n){return await this.request(`monitor_cond`,[e,t,n])}async monitorCondSince(e,t,n,r=null){return await this.request(`monitor_cond_since`,[e,t,n,r])}async monitorCancel(e){return await this.request(`monitor_cancel`,[e])}async lock(e){return await this.request(`lock`,[e])}async steal(e){return await this.request(`steal`,[e])}async unlock(e){return await this.request(`unlock`,[e])}async echo(...e){return await this.request(`echo`,e)}async setDbChangeAware(e=!0){return await this.request(`set_db_change_aware`,[e])}async close(){this.disposeTransport()}async[Symbol.asyncDispose](){await this.close()}attachSocket(e){this.socket=e,this.receiveBuffer=``,e.on(`data`,this.handleData),e.on(`error`,this.handleSocketError),e.on(`close`,this.handleSocketClose)}handleData=e=>{this.receiveBuffer+=typeof e==`string`?e:e.toString(`utf8`);let t=f(this.receiveBuffer);for(;t;)this.receiveBuffer=t.rest,this.parseFrame(t.frame),t=f(this.receiveBuffer);let n=this.receiveBuffer.trimStart();n&&n[0]!==`{`&&n[0]!==`[`&&(this.emitProtocolError(`Received non-JSON data on the transport`,this.receiveBuffer),this.receiveBuffer=``)};handleSocketError=e=>{this.emit(`transportError`,e),this.disposeTransport(e)};handleSocketClose=()=>{this.disposeTransport()};parseFrame(e){try{let t=JSON.parse(e);this.handleMessage(t)}catch(t){let n=new a(`Failed to parse JSON message`,e);this.emit(`protocolError`,n,e),t instanceof Error}}handleMessage(e){if(!e||typeof e!=`object`){this.emitProtocolError(`Expected a JSON object message`,e);return}if(`method`in e&&typeof e.method==`string`){let t=e;if(t.id!==void 0&&t.id!==null){this.handleIncomingRequest(t.method,t.params??[],t.id);return}this.handleNotification(e);return}if(`id`in e){this.handleResponse(e);return}this.emitProtocolError(`Received message without method or id`,e)}handleResponse(e){let t=this.pendingRequests.get(e.id);if(!t){this.emitProtocolError(`Received response for an unknown request id`,e);return}if(this.pendingRequests.delete(e.id),clearTimeout(t.timeoutId),e.error){t.reject(new i(e.error));return}t.resolve(e.result)}async handleIncomingRequest(e,t,n){if(e===`echo`){await this.writeMessage({id:n,result:t,error:null});return}await this.writeMessage({id:n,result:null,error:{error:`not supported`,details:`Unsupported server request: ${e}`}})}handleNotification(e){switch(this.emit(`notification`,e),e.method){case`update`:this.emit(`update`,e);break;case`update2`:this.emit(`update2`,e);break;case`update3`:this.emit(`update3`,e);break;case`locked`:this.emit(`locked`,e);break;case`stolen`:this.emit(`stolen`,e);break;default:this.emitProtocolError(`Received an unknown notification method`,e);break}}emitProtocolError(e,t){let n=new a(e,t);this.emit(`protocolError`,n,t)}async writeMessage(e){this.assertConnected(),await new Promise((t,n)=>{this.socket?.write(`${JSON.stringify(e)}\n`,e=>{if(e){n(e);return}t()})})}assertConnected(){if(!this.connected||!this.socket)throw Error(`Not connected to OVSDB`)}disposeTransport(e){let t=this.socket;this.socket=null,this.connected=!1,this.receiveBuffer=``,t&&(t.off(`data`,this.handleData),t.off(`error`,this.handleSocketError),t.off(`close`,this.handleSocketClose),t.destroyed||t.destroy());let n=e??Error(`Connection closed`);for(let e of this.pendingRequests.values())clearTimeout(e.timeoutId),e.reject(n);this.pendingRequests.clear(),this.closeEmitted||(this.closeEmitted=!0,this.emit(`close`))}};function l(e={}){if(e.host){let t=e.port??6640;return e.tls?{transport:`tls`,host:e.host,port:t,tlsOptions:{host:e.host,port:t,...e.tlsOptions}}:{transport:`tcp`,host:e.host,port:t}}return{transport:`unix`,socketPath:e.socketPath??`/var/run/openvswitch/db.sock`}}function u(e){switch(e.transport){case`unix`:return(0,t.createConnection)(e.socketPath);case`tcp`:return(0,t.createConnection)(e.port,e.host);case`tls`:return(0,r.connect)(e.tlsOptions)}}function d(e){return typeof e==`object`&&!!e&&`error`in e&&typeof e.error==`string`}function f(e){let t=0;for(;t<e.length&&/\s/u.test(e[t]);)t+=1;if(t>=e.length)return null;let n=e[t];if(!(n===`{`||n===`[`))return null;let r=0,i=!1,a=!1;for(let n=t;n<e.length;n+=1){let o=e[n];if(i){if(a){a=!1;continue}if(o===`\\`){a=!0;continue}o===`"`&&(i=!1);continue}if(o===`"`){i=!0;continue}if(o===`{`||o===`[`){r+=1;continue}if((o===`}`||o===`]`)&&(--r,r===0))return{frame:e.slice(t,n+1),rest:e.slice(n+1)}}return null}exports.OVSDBClient=c,exports.OvsdbProtocolError=a,exports.OvsdbRpcError=i,exports.OvsdbTransaction=s,exports.OvsdbTransactionError=o,exports.resolveConnectionOptions=l; //# sourceMappingURL=index.cjs.map