242 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			242 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| const _ = require("lodash");
 | |
| const http = require("http");
 | |
| const https = require("https");
 | |
| const URI = require("uri-js");
 | |
| const { axios_request, stringify } = require("../../../utils/general");
 | |
| const USER_AGENT = "democratic-csi-driver";
 | |
| 
 | |
| class Client {
 | |
|   constructor(options = {}) {
 | |
|     this.options = JSON.parse(JSON.stringify(options));
 | |
|     this.logger = console;
 | |
|     this.options.apiVersion = 2;
 | |
|   }
 | |
| 
 | |
|   getHttpAgent() {
 | |
|     if (!this.httpAgent) {
 | |
|       this.httpAgent = new http.Agent({
 | |
|         keepAlive: true,
 | |
|         maxSockets: Infinity,
 | |
|         rejectUnauthorized: !!!this.options.allowInsecure,
 | |
|       });
 | |
|     }
 | |
| 
 | |
|     return this.httpAgent;
 | |
|   }
 | |
| 
 | |
|   getHttpsAgent() {
 | |
|     if (!this.httpsAgent) {
 | |
|       this.httpsAgent = new https.Agent({
 | |
|         keepAlive: true,
 | |
|         maxSockets: Infinity,
 | |
|         rejectUnauthorized: !!!this.options.allowInsecure,
 | |
|       });
 | |
|     }
 | |
| 
 | |
|     return this.httpsAgent;
 | |
|   }
 | |
| 
 | |
|   getBaseURL() {
 | |
|     const server = this.options;
 | |
|     if (!server.protocol) {
 | |
|       if (server.port) {
 | |
|         if (String(server.port).includes("80")) {
 | |
|           server.protocol = "http";
 | |
|         }
 | |
|         if (String(server.port).includes("443")) {
 | |
|           server.protocol = "https";
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     if (!server.protocol) {
 | |
|       server.protocol = "http";
 | |
|     }
 | |
| 
 | |
|     const options = {
 | |
|       scheme: server.protocol,
 | |
|       host: server.host,
 | |
|       port: server.port,
 | |
|       //userinfo: server.username + ":" + server.password,
 | |
|       path: server.apiVersion == 1 ? "/api/v1.0" : "/api/v2.0",
 | |
|     };
 | |
|     return URI.serialize(options);
 | |
|   }
 | |
| 
 | |
|   setApiVersion(apiVersion) {
 | |
|     this.options.apiVersion = apiVersion;
 | |
|   }
 | |
| 
 | |
|   getApiVersion() {
 | |
|     return this.options.apiVersion;
 | |
|   }
 | |
| 
 | |
|   getRequestCommonOptions() {
 | |
|     const client = this;
 | |
|     const options = {
 | |
|       headers: {
 | |
|         Accept: "application/json",
 | |
|         "User-Agent": USER_AGENT,
 | |
|         "Content-Type": "application/json",
 | |
|       },
 | |
|       responseType: "json",
 | |
|       httpAgent: this.getHttpAgent(),
 | |
|       httpsAgent: this.getHttpsAgent(),
 | |
|       timeout: 60 * 1000,
 | |
|       validateStatus: function (status) {
 | |
|         if (status >= 500) {
 | |
|           return false;
 | |
|         }
 | |
|         return true;
 | |
|       },
 | |
|     };
 | |
| 
 | |
|     if (client.options.apiKey) {
 | |
|       options.headers.Authorization = `Bearer ${client.options.apiKey}`;
 | |
|     } else if (client.options.username && client.options.password) {
 | |
|       options.auth = {
 | |
|         username: client.options.username,
 | |
|         password: client.options.password,
 | |
|       };
 | |
|     }
 | |
| 
 | |
|     return options;
 | |
|   }
 | |
| 
 | |
|   log_repsonse(error, response, body, options) {
 | |
|     let prop;
 | |
|     let val;
 | |
| 
 | |
|     prop = "auth.username";
 | |
|     val = _.get(options, prop, false);
 | |
|     if (val) {
 | |
|       _.set(options, prop, "redacted");
 | |
|     }
 | |
| 
 | |
|     prop = "auth.password";
 | |
|     val = _.get(options, prop, false);
 | |
|     if (val) {
 | |
|       _.set(options, prop, "redacted");
 | |
|     }
 | |
| 
 | |
|     prop = "headers.Authorization";
 | |
|     val = _.get(options, prop, false);
 | |
|     if (val) {
 | |
|       _.set(options, prop, "redacted");
 | |
|     }
 | |
| 
 | |
|     delete options.httpAgent;
 | |
|     delete options.httpsAgent;
 | |
| 
 | |
|     let duration = parseFloat(
 | |
|       Math.round((_.get(response, "duration", 0) + Number.EPSILON) * 100) /
 | |
|         100 /
 | |
|         1000
 | |
|     ).toFixed(2);
 | |
| 
 | |
|     this.logger.debug("FREENAS HTTP REQUEST DETAILS: " + stringify(options));
 | |
|     this.logger.debug("FREENAS HTTP REQUEST DURATION: " + duration + "s");
 | |
|     this.logger.debug("FREENAS HTTP ERROR: " + error);
 | |
|     this.logger.debug(
 | |
|       "FREENAS HTTP RESPONSE STATUS CODE: " + _.get(response, "statusCode", "")
 | |
|     );
 | |
|     this.logger.debug(
 | |
|       "FREENAS HTTP RESPONSE HEADERS: " +
 | |
|         stringify(_.get(response, "headers", ""))
 | |
|     );
 | |
|     this.logger.debug("FREENAS HTTP RESPONSE BODY: " + stringify(body));
 | |
|   }
 | |
| 
 | |
|   async get(endpoint, data, options = {}) {
 | |
|     const client = this;
 | |
|     if (this.options.apiVersion == 1 && !endpoint.endsWith("/")) {
 | |
|       endpoint += "/";
 | |
|     }
 | |
| 
 | |
|     return new Promise((resolve, reject) => {
 | |
|       options = { ...client.getRequestCommonOptions(), ...options };
 | |
|       options.method = "GET";
 | |
|       options.url = this.getBaseURL() + endpoint;
 | |
|       options.params = data;
 | |
| 
 | |
|       axios_request(options, function (err, res, body) {
 | |
|         client.log_repsonse(...arguments, options);
 | |
|         if (err) {
 | |
|           reject(err);
 | |
|         }
 | |
|         resolve(res);
 | |
|       });
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   async post(endpoint, data, options = {}) {
 | |
|     const client = this;
 | |
|     if (this.options.apiVersion == 1 && !endpoint.endsWith("/")) {
 | |
|       endpoint += "/";
 | |
|     }
 | |
| 
 | |
|     return new Promise((resolve, reject) => {
 | |
|       options = { ...client.getRequestCommonOptions(), ...options };
 | |
|       options.method = "POST";
 | |
|       options.url = this.getBaseURL() + endpoint;
 | |
|       options.data = data;
 | |
| 
 | |
|       axios_request(options, function (err, res, body) {
 | |
|         client.log_repsonse(...arguments, options);
 | |
|         if (err) {
 | |
|           reject(err);
 | |
|         }
 | |
| 
 | |
|         resolve(res);
 | |
|       });
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   async put(endpoint, data, options = {}) {
 | |
|     const client = this;
 | |
|     if (this.options.apiVersion == 1 && !endpoint.endsWith("/")) {
 | |
|       endpoint += "/";
 | |
|     }
 | |
| 
 | |
|     return new Promise((resolve, reject) => {
 | |
|       options = { ...client.getRequestCommonOptions(), ...options };
 | |
|       options.method = "PUT";
 | |
|       options.url = this.getBaseURL() + endpoint;
 | |
|       options.data = data;
 | |
| 
 | |
|       axios_request(options, function (err, res, body) {
 | |
|         client.log_repsonse(...arguments, options);
 | |
|         if (err) {
 | |
|           reject(err);
 | |
|         }
 | |
| 
 | |
|         resolve(res);
 | |
|       });
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   async delete(endpoint, data, options = {}) {
 | |
|     const client = this;
 | |
|     if (this.options.apiVersion == 1 && !endpoint.endsWith("/")) {
 | |
|       endpoint += "/";
 | |
|     }
 | |
| 
 | |
|     return new Promise((resolve, reject) => {
 | |
|       options = { ...client.getRequestCommonOptions(), ...options };
 | |
|       options.method = "DELETE";
 | |
|       options.url = this.getBaseURL() + endpoint;
 | |
|       options.data = data;
 | |
| 
 | |
|       axios_request(options, function (err, res, body) {
 | |
|         client.log_repsonse(...arguments, options);
 | |
|         if (err) {
 | |
|           reject(err);
 | |
|         }
 | |
| 
 | |
|         resolve(res);
 | |
|       });
 | |
|     });
 | |
|   }
 | |
| }
 | |
| 
 | |
| module.exports.Client = Client;
 |