UNPKG

egnyte-resellers

Version:

Library for managing things against the undocumented egnyte resellers API.

233 lines (232 loc) 10.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Customers = void 0; const index_1 = require("../../index"); const base_1 = require("../base/base"); class Customers extends base_1.Base { constructor(plans, _config) { super(_config); this.plans = plans; } async getAllCustomers() { var _a; const { authCookie, csrfToken } = await this.authenticate(); const cookie = `${authCookie}; csrftoken=${csrfToken};`; const planIds = await this.plans._getAllPlanIds(cookie); const customers = []; let processedCount = 0; for (const planId of planIds) { processedCount++; let usageStats; try { const res = await this.http.get(`/msp/usage_stats/${this.resellerId}/${planId}/`, { headers: { cookie: cookie, 'X-CSRFToken': csrfToken, }, }); usageStats = Array.isArray(res.data) ? res.data : []; } catch (error) { continue; } for (const customer of usageStats) { const entries = Object.entries(customer); if (entries.length === 0) { continue; } const [customerEgnyteId, ref] = entries[0]; const obj = { customerEgnyteId, planId, powerUsers: this.extractResourceStats(ref.power_user_stats), storageGB: this.extractResourceStats(ref.storage_stats), features: this.processFeatures(ref.feature_stats), }; customers.push(obj); } const delay = this.calculateBackoff(processedCount, (_a = this.config.backoffDelay) !== null && _a !== void 0 ? _a : 1000); await this.delay(delay); } return customers; } extractResourceStats(stats) { return { total: stats.Used + stats.Unused, used: stats.Used, available: stats.Available, free: stats.Unused, }; } processFeatures(featureStats) { const features = {}; for (const [key, value] of Object.entries(featureStats)) { const typedKey = key; const mappedKey = index_1.FeatureMap.get(typedKey); const targetKey = mappedKey || this.toCamelCase(typedKey); features[targetKey] = value; } features.totalStandardUserPacks = Math.ceil((featureStats.additional_su - featureStats.total_power_users) / 5); return features; } calculateBackoff(attempt, baseDelay) { const maxDelay = 10000; const calculatedDelay = Math.min(baseDelay * Math.pow(1.5, attempt - 1), maxDelay); return calculatedDelay; } delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } async getOneCustomer(customerId) { const allCustomers = await this.getAllCustomers(); const customer = allCustomers.find((customer) => customer.customerEgnyteId === customerId); if (!customer) throw new Error(`unable to find egnyte customer: ${customerId}`); return customer; } async updateCustomer(customerId, data) { var _a, _b; const allCustomers = await this.getAllCustomers(); const customer = allCustomers.find((customer) => customer.customerEgnyteId === customerId); if (!customer) throw new Error(`unable to find egnyte customer: ${customerId}`); if (((_a = data === null || data === void 0 ? void 0 : data.powerUsers) === null || _a === void 0 ? void 0 : _a.total) && data.powerUsers.total !== customer.powerUsers.total) { await this.updateCustomerPowerUsers(customerId, data.powerUsers.total); customer.powerUsers.total = data.powerUsers.total; customer.powerUsers.free = data.powerUsers.total - customer.powerUsers.used; } if (((_b = data === null || data === void 0 ? void 0 : data.storageGB) === null || _b === void 0 ? void 0 : _b.total) && data.storageGB.total !== customer.storageGB.total) { await this.updateCustomerStorage(customerId, data.storageGB.total); customer.storageGB.total = data.storageGB.total; customer.storageGB.free = data.storageGB.total - customer.storageGB.used; } return customer; } async updateCustomerStorage(customerId, storageSizeGB) { customerId = customerId.toLowerCase(); const customer = await this.getOneCustomer(customerId); if (storageSizeGB < customer.storageGB.used) { const response = { result: 'NO_CHANGE', message: `customerId ${customerId} currently has ${customer.storageGB.used}GB storage in use. Refusing to set to ${storageSizeGB}GB storage.`, }; return response; } else if (storageSizeGB === customer.storageGB.total) { const response = { result: 'NO_CHANGE', message: `customerId ${customerId} is already set to ${storageSizeGB}GB storage. Did not modify.`, }; return response; } const { authCookie, csrfToken } = await this.authenticate(); const response = await this.http.post(`/msp/change_storage/${this.resellerId}/`, { domain: customerId, storage: storageSizeGB.toString(), }, { headers: { Cookie: `${authCookie}; csrftoken=${csrfToken}`, 'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest', 'X-CSRFToken': csrfToken, }, }); const result = response.data; if (result.msg === 'Plan updated successfully!') { return { result: 'SUCCESS', message: `Updated customerId ${customerId} from ${customer.storageGB.total}GB to ${storageSizeGB}GB storage successfully.`, }; } else { throw new Error(result.msg); } } async updateCustomerPowerUsers(customerId, numOfUsers, autoAddToPool) { customerId = customerId.toLowerCase(); const customer = await this.getOneCustomer(customerId); if (numOfUsers === customer.powerUsers.total) { return { result: 'NO_CHANGE', message: `customerId ${customerId} is already set to ${numOfUsers} power users. Did not modify.`, }; } if (numOfUsers < customer.powerUsers.used && this.config.forceLicenseChange !== true) { return { result: 'NO_CHANGE', message: `customerId ${customerId} currently has ${customer.powerUsers.used} power users in use. Refusing to set to ${numOfUsers} power users.`, }; } const licensesNeeded = numOfUsers - customer.powerUsers.total; if (licensesNeeded > 0 && customer.powerUsers.available < licensesNeeded && !autoAddToPool) { throw new Error(`Not enough available licenses on customers reseller plan. Need ${licensesNeeded} but only ${customer.powerUsers.available} are available.`); } if (autoAddToPool && licensesNeeded > 0) { await this.ensureSufficientLicensesInPool(customer.planId, licensesNeeded, customer.powerUsers.available); } const { authCookie, csrfToken } = await this.authenticate(); const res = await this.http.post(`/msp/change_power_users/${this.resellerId}/`, { domain: customerId, power_users: numOfUsers.toString(), }, { headers: { Cookie: `${authCookie}; csrftoken=${csrfToken}`, 'X-Requested-With': 'XMLHttpRequest', 'X-CSRFToken': csrfToken, Referer: 'https://resellers.egnyte.com', }, validateStatus: (status) => (status >= 200 && status <= 303) || status === 400, }); const result = res.data; if (result.msg === 'Plan updated successfully!') { return { result: 'SUCCESS', message: `Updated customerId ${customerId} from ${customer.powerUsers.total} to ${numOfUsers} power users successfully.`, }; } else if (result.msg === 'CFS plan upgrade failed. Please contact support.' && this.config.forceLicenseChange && res.status === 400) { return { result: 'SUCCESS', message: `Updated customerId ${customerId} from ${customer.powerUsers.total} to ${numOfUsers} power users successfully with force option.`, }; } else { throw new Error(result.msg || 'Unknown error updating power users'); } } async ensureSufficientLicensesInPool(planId, licensesNeeded, availableLicenses) { if (licensesNeeded <= availableLicenses) { return; } const plans = await this.plans.getPlans(); const plan = plans.find((e) => e.planId === planId); if (!plan) { throw new Error(`Could not find plan with ID ${planId}`); } const additionalLicensesNeeded = licensesNeeded - availableLicenses; const licensesToAdd = Math.ceil(additionalLicensesNeeded / 5) * 5; const updatedLicensesTotal = licensesToAdd + plan.totalPowerUsers; await this.plans.UpdatePowerUserLicensing(planId, updatedLicensesTotal); } async getCustomerProtectPlanUsage(egnyteTenantId) { const { authCookie, csrfToken } = await this.authenticate(); const { data: protectUsage } = await this.http.get(`/msp/usage_stats/${this.resellerId}/${this.config.protectPlanId}/`, { headers: { cookie: authCookie, 'X-CSRFToken': csrfToken }, }); const id = `protect${egnyteTenantId.toLowerCase()}`; for (const entry of protectUsage) { if (Object.keys(entry)[0] === id) { return entry[id].storage_stats; } } return null; } toCamelCase(str) { return str.toLowerCase().replace(/[-_][a-z]/g, (group) => group.slice(-1).toUpperCase()); } } exports.Customers = Customers;