simple proxmox
This commit is contained in:
214
nodejs/utils/pvejs.js
Normal file
214
nodejs/utils/pvejs.js
Normal file
@ -0,0 +1,214 @@
|
||||
'use strict';
|
||||
|
||||
const fetch = require('node-fetch');
|
||||
const { URLSearchParams } = require('url');
|
||||
|
||||
var apiProto = {};
|
||||
|
||||
apiProto.__getApiDoc = async function(host){
|
||||
try{
|
||||
let setupRes = await fetch(host || this.host+'/pve-docs/api-viewer/apidoc.js', { method: 'GET'});
|
||||
let text = await setupRes.text()
|
||||
|
||||
text = text.split('// avoid errors when running without development tools')[0];
|
||||
|
||||
return eval(text += '; pveapi;');
|
||||
|
||||
}catch(error){
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
apiProto.__makeMap = async function(APItree){
|
||||
APItree = APItree || await this.__getApiDoc();
|
||||
let apiMap = {};
|
||||
|
||||
function __rec(obj){
|
||||
for(let item of obj){
|
||||
if(item.children){
|
||||
__rec(item.children);
|
||||
}
|
||||
if(item.path){
|
||||
delete item.children;
|
||||
apiMap[item.path] = item;
|
||||
item.methods = item.info;
|
||||
delete item.info;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__rec(APItree);
|
||||
|
||||
return apiMap
|
||||
};
|
||||
|
||||
//these helper functions are to build the fetch call
|
||||
apiProto.__buildHeaders = function(){
|
||||
let headers = {};
|
||||
if(this.authInfo.apiToken){
|
||||
headers = {
|
||||
"Authorization": `PVEAPIToken=${this.authInfo.username}=${this.authInfo.apiToken}`
|
||||
}
|
||||
}else{
|
||||
headers = {
|
||||
'Cookie': 'PVEAuthCookie='+this.user.ticket,
|
||||
'CSRFPreventionToken': this.user.CSRFPreventionToken
|
||||
}
|
||||
}
|
||||
|
||||
return headers;
|
||||
};
|
||||
|
||||
// this function takes an iterable of 'key':'value' pairs
|
||||
apiProto.__buildBody = function(props, data){
|
||||
const params = new URLSearchParams();
|
||||
for (let key in props){
|
||||
if(data[key]){
|
||||
params.append(key, data[key])
|
||||
continue;
|
||||
}
|
||||
if(props[key].optional !==1){
|
||||
// console.log(props[key])
|
||||
throw new Error('MissingKey');
|
||||
}
|
||||
}
|
||||
return params;
|
||||
};
|
||||
|
||||
apiProto.__getEndPoint = function(args){
|
||||
let endpoint = this.apiMap[args.path]
|
||||
if(!args || !endpoint) throw new Error('endpointNotFound');
|
||||
if(!endpoint.methods[args.method]) throw new Error('methodNotFound');
|
||||
|
||||
return endpoint;
|
||||
};
|
||||
|
||||
apiProto.__fetch = async function(method, path, params, data){
|
||||
try{
|
||||
let endpoint = this.__getEndPoint({path, method});
|
||||
|
||||
let fetchOptions = {
|
||||
method: method,
|
||||
headers: this.__buildHeaders(),
|
||||
}
|
||||
|
||||
if(['PUT', 'POST'].includes(method)){
|
||||
fetchOptions.body = this.__buildBody(
|
||||
endpoint.methods[method].parameters.properties,
|
||||
data
|
||||
)
|
||||
}
|
||||
|
||||
let HTTPres = await fetch(this.BASEURL+path, fetchOptions);
|
||||
|
||||
// console.log(HTTPres)
|
||||
|
||||
return {
|
||||
statusCode: HTTPres.status,
|
||||
statusText: HTTPres.statusText,
|
||||
json: (await HTTPres.json()).data,
|
||||
}
|
||||
|
||||
}catch(error){
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
apiProto.GET = async function(args){
|
||||
try{
|
||||
|
||||
return await this.__fetch(
|
||||
'GET',
|
||||
args.path,
|
||||
args.parama || {},
|
||||
);
|
||||
|
||||
}catch(error){
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
apiProto.DELETE = async function(args){
|
||||
try{
|
||||
|
||||
return await this.__fetch(
|
||||
'DELETE',
|
||||
args.path,
|
||||
args.parama || {},
|
||||
);
|
||||
|
||||
}catch(error){
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
apiProto.POST = async function(args){
|
||||
try{
|
||||
|
||||
return await this.__fetch(
|
||||
'POST',
|
||||
args.path,
|
||||
args.parama || {},
|
||||
args.data || {}
|
||||
);
|
||||
|
||||
}catch(error){
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
apiProto.PUT = async function(args){
|
||||
try{
|
||||
|
||||
return await this.__fetch(
|
||||
'PUT',
|
||||
args.path,
|
||||
args.parama || {},
|
||||
args.data || {}
|
||||
);
|
||||
|
||||
}catch(error){
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
apiProto.auth = async function(authInfo){
|
||||
try{
|
||||
this.user = (await this.POST({
|
||||
path: '/access/ticket',
|
||||
data: authInfo || this.authInfo
|
||||
})).json
|
||||
|
||||
return authInfo;
|
||||
|
||||
}catch(error){
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
apiProto.__init = async function(conf){
|
||||
try{
|
||||
this.user = {};
|
||||
this.BASEURL = conf.host+'/api2/json';
|
||||
this.apiMap = await this.__makeMap();
|
||||
|
||||
if(!this.authInfo.apiToken) await this.auth();
|
||||
|
||||
return this;
|
||||
|
||||
}catch(error){
|
||||
throw(error);
|
||||
}
|
||||
};
|
||||
|
||||
async function API(conf){
|
||||
let instance = Object.create(apiProto);
|
||||
Object.assign(instance, conf);
|
||||
|
||||
return await instance.__init(conf);
|
||||
}
|
||||
|
||||
|
||||
module.exports = API;
|
||||
|
Reference in New Issue
Block a user