Merge pull request #1512 from akhilmhdh/fix/delay-audit-log

feat(server): changed license service to use redis cache keystore
This commit is contained in:
Maidul Islam
2024-03-01 11:53:58 -05:00
committed by GitHub
4 changed files with 26 additions and 40 deletions
-20
View File
@@ -47,7 +47,6 @@
"lodash.isequal": "^4.5.0", "lodash.isequal": "^4.5.0",
"mysql2": "^3.9.1", "mysql2": "^3.9.1",
"nanoid": "^5.0.4", "nanoid": "^5.0.4",
"node-cache": "^5.1.2",
"nodemailer": "^6.9.9", "nodemailer": "^6.9.9",
"ora": "^7.0.1", "ora": "^7.0.1",
"passport-github": "^1.1.0", "passport-github": "^1.1.0",
@@ -5706,14 +5705,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/clone": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
"engines": {
"node": ">=0.8"
}
},
"node_modules/cluster-key-slot": { "node_modules/cluster-key-slot": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
@@ -9258,17 +9249,6 @@
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
"integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA=="
}, },
"node_modules/node-cache": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz",
"integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==",
"dependencies": {
"clone": "2.x"
},
"engines": {
"node": ">= 8.0.0"
}
},
"node_modules/node-fetch": { "node_modules/node-fetch": {
"version": "2.7.0", "version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
-1
View File
@@ -108,7 +108,6 @@
"lodash.isequal": "^4.5.0", "lodash.isequal": "^4.5.0",
"mysql2": "^3.9.1", "mysql2": "^3.9.1",
"nanoid": "^5.0.4", "nanoid": "^5.0.4",
"node-cache": "^5.1.2",
"nodemailer": "^6.9.9", "nodemailer": "^6.9.9",
"ora": "^7.0.1", "ora": "^7.0.1",
"passport-github": "^1.1.0", "passport-github": "^1.1.0",
@@ -5,8 +5,8 @@
// TODO(akhilmhdh): With tony find out the api structure and fill it here // TODO(akhilmhdh): With tony find out the api structure and fill it here
import { ForbiddenError } from "@casl/ability"; import { ForbiddenError } from "@casl/ability";
import NodeCache from "node-cache";
import { TKeyStoreFactory } from "@app/keystore/keystore";
import { getConfig } from "@app/lib/config/env"; import { getConfig } from "@app/lib/config/env";
import { BadRequestError } from "@app/lib/errors"; import { BadRequestError } from "@app/lib/errors";
import { logger } from "@app/lib/logger"; import { logger } from "@app/lib/logger";
@@ -39,6 +39,7 @@ type TLicenseServiceFactoryDep = {
orgDAL: Pick<TOrgDALFactory, "findOrgById">; orgDAL: Pick<TOrgDALFactory, "findOrgById">;
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">; permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
licenseDAL: TLicenseDALFactory; licenseDAL: TLicenseDALFactory;
keyStore: Pick<TKeyStoreFactory, "setItemWithExpiry" | "getItem" | "deleteItem">;
}; };
export type TLicenseServiceFactory = ReturnType<typeof licenseServiceFactory>; export type TLicenseServiceFactory = ReturnType<typeof licenseServiceFactory>;
@@ -46,12 +47,18 @@ export type TLicenseServiceFactory = ReturnType<typeof licenseServiceFactory>;
const LICENSE_SERVER_CLOUD_LOGIN = "/api/auth/v1/license-server-login"; const LICENSE_SERVER_CLOUD_LOGIN = "/api/auth/v1/license-server-login";
const LICENSE_SERVER_ON_PREM_LOGIN = "/api/auth/v1/license-login"; const LICENSE_SERVER_ON_PREM_LOGIN = "/api/auth/v1/license-login";
const FEATURE_CACHE_KEY = (orgId: string, projectId?: string) => `${orgId}-${projectId || ""}`; const LICENSE_SERVER_CLOUD_PLAN_TTL = 60; // 60s
export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }: TLicenseServiceFactoryDep) => { const FEATURE_CACHE_KEY = (orgId: string) => `infisical-cloud-plan-${orgId}`;
export const licenseServiceFactory = ({
orgDAL,
permissionService,
licenseDAL,
keyStore
}: TLicenseServiceFactoryDep) => {
let isValidLicense = false; let isValidLicense = false;
let instanceType = InstanceType.OnPrem; let instanceType = InstanceType.OnPrem;
let onPremFeatures: TFeatureSet = getDefaultOnPremFeatures(); let onPremFeatures: TFeatureSet = getDefaultOnPremFeatures();
const featureStore = new NodeCache({ stdTTL: 60 });
const appCfg = getConfig(); const appCfg = getConfig();
const licenseServerCloudApi = setupLicenceRequestWithStore( const licenseServerCloudApi = setupLicenceRequestWithStore(
@@ -75,6 +82,7 @@ export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }:
isValidLicense = true; isValidLicense = true;
return; return;
} }
if (appCfg.LICENSE_KEY) { if (appCfg.LICENSE_KEY) {
const token = await licenseServerOnPremApi.refreshLicence(); const token = await licenseServerOnPremApi.refreshLicence();
if (token) { if (token) {
@@ -100,22 +108,21 @@ export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }:
logger.info(`getPlan: attempting to fetch plan for [orgId=${orgId}] [projectId=${projectId}]`); logger.info(`getPlan: attempting to fetch plan for [orgId=${orgId}] [projectId=${projectId}]`);
try { try {
if (instanceType === InstanceType.Cloud) { if (instanceType === InstanceType.Cloud) {
const cachedPlan = featureStore.get<TFeatureSet>(FEATURE_CACHE_KEY(orgId, projectId)); const cachedPlan = await keyStore.getItem(FEATURE_CACHE_KEY(orgId));
if (cachedPlan) return cachedPlan; if (cachedPlan) return JSON.parse(cachedPlan) as TFeatureSet;
const org = await orgDAL.findOrgById(orgId); const org = await orgDAL.findOrgById(orgId);
if (!org) throw new BadRequestError({ message: "Org not found" }); if (!org) throw new BadRequestError({ message: "Org not found" });
const { const {
data: { currentPlan } data: { currentPlan }
} = await licenseServerCloudApi.request.get<{ currentPlan: TFeatureSet }>( } = await licenseServerCloudApi.request.get<{ currentPlan: TFeatureSet }>(
`/api/license-server/v1/customers/${org.customerId}/cloud-plan`, `/api/license-server/v1/customers/${org.customerId}/cloud-plan`
{ );
params: { await keyStore.setItemWithExpiry(
workspaceId: projectId FEATURE_CACHE_KEY(org.id),
} LICENSE_SERVER_CLOUD_PLAN_TTL,
} JSON.stringify(currentPlan)
); );
featureStore.set(FEATURE_CACHE_KEY(org.id, projectId), currentPlan);
return currentPlan; return currentPlan;
} }
} catch (error) { } catch (error) {
@@ -128,10 +135,10 @@ export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }:
return onPremFeatures; return onPremFeatures;
}; };
const refreshPlan = async (orgId: string, projectId?: string) => { const refreshPlan = async (orgId: string) => {
if (instanceType === InstanceType.Cloud) { if (instanceType === InstanceType.Cloud) {
featureStore.del(FEATURE_CACHE_KEY(orgId, projectId)); await keyStore.deleteItem(FEATURE_CACHE_KEY(orgId));
await getPlan(orgId, projectId); await getPlan(orgId);
} }
}; };
@@ -166,7 +173,7 @@ export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }:
quantity: count quantity: count
}); });
} }
featureStore.del(orgId); await keyStore.deleteItem(FEATURE_CACHE_KEY(orgId));
} else if (instanceType === InstanceType.EnterpriseOnPrem) { } else if (instanceType === InstanceType.EnterpriseOnPrem) {
const usedSeats = await licenseDAL.countOfOrgMembers(null); const usedSeats = await licenseDAL.countOfOrgMembers(null);
await licenseServerOnPremApi.request.patch(`/api/license/v1/license`, { usedSeats }); await licenseServerOnPremApi.request.patch(`/api/license/v1/license`, { usedSeats });
@@ -215,7 +222,7 @@ export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }:
`/api/license-server/v1/customers/${organization.customerId}/session/trial`, `/api/license-server/v1/customers/${organization.customerId}/session/trial`,
{ success_url } { success_url }
); );
featureStore.del(FEATURE_CACHE_KEY(orgId)); await keyStore.deleteItem(FEATURE_CACHE_KEY(orgId));
return { url }; return { url };
}; };
+1 -1
View File
@@ -194,7 +194,7 @@ export const registerRoutes = async (
projectRoleDAL, projectRoleDAL,
serviceTokenDAL serviceTokenDAL
}); });
const licenseService = licenseServiceFactory({ permissionService, orgDAL, licenseDAL }); const licenseService = licenseServiceFactory({ permissionService, orgDAL, licenseDAL, keyStore });
const trustedIpService = trustedIpServiceFactory({ const trustedIpService = trustedIpServiceFactory({
licenseService, licenseService,
projectDAL, projectDAL,