mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 10:27:26 +00:00
Merge pull request #4204 from Infisical/revert-4114-fix/improveLicenseApiCache
Revert "Removed cloud plan cache as it is handled on the license api"
This commit is contained in:
@@ -8,6 +8,7 @@ import { ForbiddenError } from "@casl/ability";
|
|||||||
import { CronJob } from "cron";
|
import { CronJob } from "cron";
|
||||||
import { Knex } from "knex";
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TKeyStoreFactory } from "@app/keystore/keystore";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { verifyOfflineLicense } from "@app/lib/crypto";
|
import { verifyOfflineLicense } from "@app/lib/crypto";
|
||||||
import { NotFoundError } from "@app/lib/errors";
|
import { NotFoundError } from "@app/lib/errors";
|
||||||
@@ -46,6 +47,7 @@ type TLicenseServiceFactoryDep = {
|
|||||||
orgDAL: Pick<TOrgDALFactory, "findOrgById" | "countAllOrgMembers">;
|
orgDAL: Pick<TOrgDALFactory, "findOrgById" | "countAllOrgMembers">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
||||||
licenseDAL: TLicenseDALFactory;
|
licenseDAL: TLicenseDALFactory;
|
||||||
|
keyStore: Pick<TKeyStoreFactory, "setItemWithExpiry" | "getItem" | "deleteItem">;
|
||||||
identityOrgMembershipDAL: TIdentityOrgDALFactory;
|
identityOrgMembershipDAL: TIdentityOrgDALFactory;
|
||||||
projectDAL: TProjectDALFactory;
|
projectDAL: TProjectDALFactory;
|
||||||
};
|
};
|
||||||
@@ -55,10 +57,14 @@ 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 LICENSE_SERVER_CLOUD_PLAN_TTL = 5 * 60; // 5 mins
|
||||||
|
const FEATURE_CACHE_KEY = (orgId: string) => `infisical-cloud-plan-${orgId}`;
|
||||||
|
|
||||||
export const licenseServiceFactory = ({
|
export const licenseServiceFactory = ({
|
||||||
orgDAL,
|
orgDAL,
|
||||||
permissionService,
|
permissionService,
|
||||||
licenseDAL,
|
licenseDAL,
|
||||||
|
keyStore,
|
||||||
identityOrgMembershipDAL,
|
identityOrgMembershipDAL,
|
||||||
projectDAL
|
projectDAL
|
||||||
}: TLicenseServiceFactoryDep) => {
|
}: TLicenseServiceFactoryDep) => {
|
||||||
@@ -172,6 +178,12 @@ export const licenseServiceFactory = ({
|
|||||||
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 = await keyStore.getItem(FEATURE_CACHE_KEY(orgId));
|
||||||
|
if (cachedPlan) {
|
||||||
|
logger.info(`getPlan: plan fetched from cache [orgId=${orgId}] [projectId=${projectId}]`);
|
||||||
|
return JSON.parse(cachedPlan) as TFeatureSet;
|
||||||
|
}
|
||||||
|
|
||||||
const org = await orgDAL.findOrgById(orgId);
|
const org = await orgDAL.findOrgById(orgId);
|
||||||
if (!org) throw new NotFoundError({ message: `Organization with ID '${orgId}' not found` });
|
if (!org) throw new NotFoundError({ message: `Organization with ID '${orgId}' not found` });
|
||||||
const {
|
const {
|
||||||
@@ -187,12 +199,23 @@ export const licenseServiceFactory = ({
|
|||||||
const identityUsed = await licenseDAL.countOrgUsersAndIdentities(orgId);
|
const identityUsed = await licenseDAL.countOrgUsersAndIdentities(orgId);
|
||||||
currentPlan.identitiesUsed = identityUsed;
|
currentPlan.identitiesUsed = identityUsed;
|
||||||
|
|
||||||
|
await keyStore.setItemWithExpiry(
|
||||||
|
FEATURE_CACHE_KEY(org.id),
|
||||||
|
LICENSE_SERVER_CLOUD_PLAN_TTL,
|
||||||
|
JSON.stringify(currentPlan)
|
||||||
|
);
|
||||||
|
|
||||||
return currentPlan;
|
return currentPlan;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
error,
|
error,
|
||||||
`getPlan: encountered an error when fetching plan [orgId=${orgId}] [projectId=${projectId}] [error]`
|
`getPlan: encountered an error when fetching pan [orgId=${orgId}] [projectId=${projectId}] [error]`
|
||||||
|
);
|
||||||
|
await keyStore.setItemWithExpiry(
|
||||||
|
FEATURE_CACHE_KEY(orgId),
|
||||||
|
LICENSE_SERVER_CLOUD_PLAN_TTL,
|
||||||
|
JSON.stringify(onPremFeatures)
|
||||||
);
|
);
|
||||||
return onPremFeatures;
|
return onPremFeatures;
|
||||||
} finally {
|
} finally {
|
||||||
@@ -203,6 +226,7 @@ export const licenseServiceFactory = ({
|
|||||||
|
|
||||||
const refreshPlan = async (orgId: string) => {
|
const refreshPlan = async (orgId: string) => {
|
||||||
if (instanceType === InstanceType.Cloud) {
|
if (instanceType === InstanceType.Cloud) {
|
||||||
|
await keyStore.deleteItem(FEATURE_CACHE_KEY(orgId));
|
||||||
await getPlan(orgId);
|
await getPlan(orgId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -240,6 +264,7 @@ export const licenseServiceFactory = ({
|
|||||||
quantityIdentities
|
quantityIdentities
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
await keyStore.deleteItem(FEATURE_CACHE_KEY(orgId));
|
||||||
} else if (instanceType === InstanceType.EnterpriseOnPrem) {
|
} else if (instanceType === InstanceType.EnterpriseOnPrem) {
|
||||||
const usedSeats = await licenseDAL.countOfOrgMembers(null, tx);
|
const usedSeats = await licenseDAL.countOfOrgMembers(null, tx);
|
||||||
const usedIdentitySeats = await licenseDAL.countOrgUsersAndIdentities(null, tx);
|
const usedIdentitySeats = await licenseDAL.countOrgUsersAndIdentities(null, tx);
|
||||||
@@ -303,6 +328,7 @@ export const licenseServiceFactory = ({
|
|||||||
`/api/license-server/v1/customers/${organization.customerId}/session/trial`,
|
`/api/license-server/v1/customers/${organization.customerId}/session/trial`,
|
||||||
{ success_url }
|
{ success_url }
|
||||||
);
|
);
|
||||||
|
await keyStore.deleteItem(FEATURE_CACHE_KEY(orgId));
|
||||||
return { url };
|
return { url };
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -679,6 +705,10 @@ export const licenseServiceFactory = ({
|
|||||||
return licenses;
|
return licenses;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const invalidateGetPlan = async (orgId: string) => {
|
||||||
|
await keyStore.deleteItem(FEATURE_CACHE_KEY(orgId));
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
generateOrgCustomerId,
|
generateOrgCustomerId,
|
||||||
removeOrgCustomer,
|
removeOrgCustomer,
|
||||||
@@ -693,6 +723,7 @@ export const licenseServiceFactory = ({
|
|||||||
return onPremFeatures;
|
return onPremFeatures;
|
||||||
},
|
},
|
||||||
getPlan,
|
getPlan,
|
||||||
|
invalidateGetPlan,
|
||||||
updateSubscriptionOrgMemberCount,
|
updateSubscriptionOrgMemberCount,
|
||||||
refreshPlan,
|
refreshPlan,
|
||||||
getOrgPlan,
|
getOrgPlan,
|
||||||
|
|||||||
@@ -500,6 +500,7 @@ export const registerRoutes = async (
|
|||||||
permissionService,
|
permissionService,
|
||||||
orgDAL,
|
orgDAL,
|
||||||
licenseDAL,
|
licenseDAL,
|
||||||
|
keyStore,
|
||||||
identityOrgMembershipDAL,
|
identityOrgMembershipDAL,
|
||||||
projectDAL
|
projectDAL
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -161,8 +161,8 @@ type TProjectServiceFactoryDep = {
|
|||||||
sshHostGroupDAL: Pick<TSshHostGroupDALFactory, "find" | "findSshHostGroupsWithLoginMappings">;
|
sshHostGroupDAL: Pick<TSshHostGroupDALFactory, "find" | "findSshHostGroupsWithLoginMappings">;
|
||||||
permissionService: TPermissionServiceFactory;
|
permissionService: TPermissionServiceFactory;
|
||||||
orgService: Pick<TOrgServiceFactory, "addGhostUser">;
|
orgService: Pick<TOrgServiceFactory, "addGhostUser">;
|
||||||
|
licenseService: Pick<TLicenseServiceFactory, "getPlan" | "invalidateGetPlan">;
|
||||||
queueService: Pick<TQueueServiceFactory, "stopRepeatableJob">;
|
queueService: Pick<TQueueServiceFactory, "stopRepeatableJob">;
|
||||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
|
||||||
smtpService: Pick<TSmtpService, "sendMail">;
|
smtpService: Pick<TSmtpService, "sendMail">;
|
||||||
orgDAL: Pick<TOrgDALFactory, "findOne">;
|
orgDAL: Pick<TOrgDALFactory, "findOne">;
|
||||||
keyStore: Pick<TKeyStoreFactory, "deleteItem">;
|
keyStore: Pick<TKeyStoreFactory, "deleteItem">;
|
||||||
@@ -489,6 +489,10 @@ export const projectServiceFactory = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no need to invalidate if there was no limit
|
||||||
|
if (plan.workspaceLimit) {
|
||||||
|
await licenseService.invalidateGetPlan(organization.id);
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...project,
|
...project,
|
||||||
environments: envs,
|
environments: envs,
|
||||||
|
|||||||
Reference in New Issue
Block a user