Implement functionality to store DNS deployment

This commit is contained in:
IshaVenikar 2025-01-31 15:37:31 +05:30
parent 38e10187e7
commit d28a270e7b
3 changed files with 92 additions and 71 deletions

View File

@ -105,24 +105,15 @@ export class Deployment {
@Column('varchar', { nullable: true }) @Column('varchar', { nullable: true })
applicationDeploymentRequestId!: string | null; applicationDeploymentRequestId!: string | null;
@Column('varchar', { nullable: true })
dnsDeploymentRequestId!: string | null;
@Column('simple-json', { nullable: true }) @Column('simple-json', { nullable: true })
applicationDeploymentRequestData!: ApplicationDeploymentRequest | null; applicationDeploymentRequestData!: ApplicationDeploymentRequest | null;
@Column('varchar', { nullable: true }) @Column('varchar', { nullable: true })
applicationDeploymentRecordId!: string | null; applicationDeploymentRecordId!: string | null;
@Column('varchar', { nullable: true })
dnsDeploymentRecordId!: string | null;
@Column('simple-json', { nullable: true }) @Column('simple-json', { nullable: true })
applicationDeploymentRecordData!: AppDeploymentRecordAttributes | null; applicationDeploymentRecordData!: AppDeploymentRecordAttributes | null;
@Column('simple-json', { nullable: true })
dnsDeploymentRecordData!: AppDeploymentRecordAttributes | null;
@Column('varchar', { nullable: true }) @Column('varchar', { nullable: true })
applicationDeploymentRemovalRequestId!: string | null; applicationDeploymentRemovalRequestId!: string | null;
@ -150,6 +141,9 @@ export class Deployment {
@Column('boolean', { default: false }) @Column('boolean', { default: false })
isCurrent!: boolean; isCurrent!: boolean;
@Column('boolean', { default: false })
isDNS!: boolean;
@Column({ @Column({
enum: DeploymentStatus enum: DeploymentStatus
}) })

View File

@ -376,8 +376,8 @@ export class Registry {
return records.filter((record: AppDeploymentRecord) => return records.filter((record: AppDeploymentRecord) =>
deployments.some( deployments.some(
(deployment) => (deployment) =>
deployment.applicationDeploymentRequestId === record.attributes.request || deployment.applicationDeploymentRequestId === record.attributes.request &&
deployment.dnsDeploymentRequestId === record.attributes.request record.attributes.url.includes(deployment.id)
) )
); );
} }

View File

@ -185,28 +185,23 @@ export class Service {
}, },
}); });
const requestIdToRecordsMap = records.reduce( const recordToDeploymentsMap = deployments.reduce(
(acc: { [key: string]: AppDeploymentRecord }, record) => { (acc: { [key: string]: Deployment }, deployment) => {
acc[record.attributes.request] = record; acc[deployment.applicationDeploymentRequestId!] = deployment;
return acc; return acc;
}, },
{}, {},
); );
// Update deployment data for ApplicationDeploymentRecords // Update deployment data for ApplicationDeploymentRecords
const deploymentUpdatePromises = deployments.map(async (deployment) => { const deploymentUpdatePromises = records.map(async (record) => {
const applicationDeploymentRecord = requestIdToRecordsMap[deployment.applicationDeploymentRequestId!] const deployment = recordToDeploymentsMap[record.attributes.request];
const dnsDeploymentRecord = requestIdToRecordsMap[deployment.dnsDeploymentRequestId!]
if (!applicationDeploymentRecord || !dnsDeploymentRecord) {
return;
}
if (!deployment.project) { if (!deployment.project) {
log(`Project ${deployment.projectId} not found`); log(`Project ${deployment.projectId} not found`);
return; return;
} else { } else {
const dnsRecords = await this.laconicRegistry.getDNSRecordById(applicationDeploymentRecord.attributes.dns); const dnsRecords = await this.laconicRegistry.getDNSRecordById(record.attributes.dns);
const dnsRecordData: DNSRecordAttributes = { const dnsRecordData: DNSRecordAttributes = {
name: dnsRecords[0].attributes.name, name: dnsRecords[0].attributes.name,
@ -216,15 +211,29 @@ export class Service {
version: dnsRecords[0].attributes.version, version: dnsRecords[0].attributes.version,
} }
deployment.applicationDeploymentRecordId = applicationDeploymentRecord.id; deployment.applicationDeploymentRecordId = record.id;
deployment.dnsDeploymentRecordId = dnsDeploymentRecord.id; deployment.applicationDeploymentRecordData = record.attributes;
deployment.applicationDeploymentRecordData = applicationDeploymentRecord.attributes; deployment.url = record.attributes.url;
deployment.dnsDeploymentRecordData = dnsDeploymentRecord.attributes;
deployment.url = applicationDeploymentRecord.attributes.url;
deployment.status = DeploymentStatus.Ready; deployment.status = DeploymentStatus.Ready;
deployment.isCurrent = deployment.environment === Environment.Production; deployment.isCurrent = deployment.environment === Environment.Production;
deployment.dnsRecordData = dnsRecordData; deployment.dnsRecordData = dnsRecordData;
if (deployment.isDNS) {
// Delete previous DNS deployment
const oldDNSDeployment = await this.db.getDeployment({
where: {
projectId: deployment.project.id,
deployer: deployment.deployer,
isDNS: true,
isCurrent: true,
}
});
if (oldDNSDeployment) {
await this.db.deleteDeploymentById(oldDNSDeployment.id);
}
}
await this.db.updateDeploymentById(deployment.id, deployment); await this.db.updateDeploymentById(deployment.id, deployment);
// Release deployer funds on successful deployment // Release deployer funds on successful deployment
@ -240,25 +249,27 @@ export class Service {
} }
log( log(
`Updated deployment ${deployment.id} with URL ${applicationDeploymentRecord.attributes.url}`, `Updated deployment ${deployment.id} with URL ${record.attributes.url}`,
); );
} }
// Set the isCurrent state to false for the old deployments
if (deployment.isCurrent) {
const projectDeployments = await this.db.getDeploymentsByProjectId(deployment.projectId);
const oldDeployments = projectDeployments
.filter(projectDeployment => projectDeployment.deployer.deployerLrn === deployment.deployer.deployerLrn && projectDeployment.id !== deployment.id);
for (const oldDeployment of oldDeployments) {
await this.db.updateDeployment(
{ id: oldDeployment.id },
{ isCurrent: false }
);
}
}
}); });
await Promise.all(deploymentUpdatePromises); await Promise.all(deploymentUpdatePromises);
// Get deployments that are in production environment
const prodDeployments = Object.values(recordToDeploymentsMap).filter(deployment => deployment.isCurrent);
// Set the isCurrent state to false for the old deployments
for (const deployment of prodDeployments) {
const projectDeployments = await this.db.getDeploymentsByProjectId(deployment.projectId);
const oldDeployments = projectDeployments
.filter(projectDeployment => projectDeployment.deployer.deployerLrn === deployment.deployer.deployerLrn && projectDeployment.id !== deployment.id);
for (const oldDeployment of oldDeployments) {
await this.db.updateDeployment(
{ id: oldDeployment.id },
{ isCurrent: false }
);
}
};
} }
/** /**
@ -658,7 +669,8 @@ export class Service {
deployer = data.deployer; deployer = data.deployer;
} }
const newDeployment = await this.createDeploymentFromData(userId, data, deployer!.deployerLrn!, applicationRecordId, applicationRecordData); const deployment = await this.createDeploymentFromData(userId, data, deployer!.deployerLrn!, applicationRecordId, applicationRecordData, false);
const dnsDeployment = await this.createDeploymentFromData(userId, data, deployer!.deployerLrn!, applicationRecordId, applicationRecordData, true);
const { repo, repoUrl } = await getRepoDetails(octokit, data.project.repository, data.commitHash); const { repo, repoUrl } = await getRepoDetails(octokit, data.project.repository, data.commitHash);
const environmentVariablesObj = await this.getEnvVariables(data.project!.id!); const environmentVariablesObj = await this.getEnvVariables(data.project!.id!);
@ -667,43 +679,47 @@ export class Service {
const domain = await this.db.getOldestDomainByProjectId(data.project!.id!); const domain = await this.db.getOldestDomainByProjectId(data.project!.id!);
// To set project DNS // To set project DNS
let dnsDeploymentRequestId = null;
if (data.environment === Environment.Production) { if (data.environment === Environment.Production) {
// On deleting deployment later, project DNS deployment is also deleted // On deleting deployment later, project DNS deployment is also deleted
// So publish project DNS deployment first so that ApplicationDeploymentRecord for the same is available when deleting deployment later // So publish project DNS deployment first so that ApplicationDeploymentRecord for the same is available when deleting deployment later
const dnsRequest = await this.laconicRegistry.createApplicationDeploymentRequest({ const { applicationDeploymentRequestData, applicationDeploymentRequestId } =
deployment: newDeployment, await this.laconicRegistry.createApplicationDeploymentRequest({
appName: repo, deployment: dnsDeployment,
repository: repoUrl, appName: repo,
environmentVariables: environmentVariablesObj, repository: repoUrl,
dns: domain?.name ?? `${newDeployment.project.name}`, environmentVariables: environmentVariablesObj,
lrn: deployer!.deployerLrn!, dns: domain?.name ?? `${dnsDeployment.project.name}`,
payment: data.project.txHash, lrn: deployer!.deployerLrn!,
auctionId: data.project.auctionId payment: data.project.txHash,
auctionId: data.project.auctionId
});
await this.db.updateDeploymentById(dnsDeployment.id, {
applicationDeploymentRequestId,
applicationDeploymentRequestData,
domainId: domain?.id ?? null
}); });
dnsDeploymentRequestId = dnsRequest.applicationDeploymentRequestId;
} }
const { applicationDeploymentRequestId, applicationDeploymentRequestData } = const { applicationDeploymentRequestId, applicationDeploymentRequestData } =
await this.laconicRegistry.createApplicationDeploymentRequest({ await this.laconicRegistry.createApplicationDeploymentRequest({
deployment: newDeployment, deployment: deployment,
appName: repo, appName: repo,
repository: repoUrl, repository: repoUrl,
lrn: deployer!.deployerLrn!, lrn: deployer!.deployerLrn!,
environmentVariables: environmentVariablesObj, environmentVariables: environmentVariablesObj,
dns: `${newDeployment.project.name}-${newDeployment.id}`, dns: `${deployment.project.name}-${deployment.id}`,
payment: data.project.txHash, payment: data.project.txHash,
auctionId: data.project.auctionId auctionId: data.project.auctionId
}); });
await this.db.updateDeploymentById(newDeployment.id, { await this.db.updateDeploymentById(deployment.id, {
applicationDeploymentRequestId, applicationDeploymentRequestId,
applicationDeploymentRequestData, applicationDeploymentRequestData,
dnsDeploymentRequestId,
domainId: domain?.id ?? null domainId: domain?.id ?? null
}); });
return newDeployment; return deployment;
} }
async createDeploymentFromAuction( async createDeploymentFromAuction(
@ -746,42 +762,49 @@ export class Service {
commitMessage: latestCommit.commit.message, commitMessage: latestCommit.commit.message,
}; };
const newDeployment = await this.createDeploymentFromData(project.ownerId!, deploymentData, deployerLrn, applicationRecordId, applicationRecordData); const deployment = await this.createDeploymentFromData(project.ownerId!, deploymentData, deployerLrn, applicationRecordId, applicationRecordData, false);
const dnsDeployment = await this.createDeploymentFromData(project.ownerId!, deploymentData, deployerLrn, applicationRecordId, applicationRecordData, true);
const environmentVariablesObj = await this.getEnvVariables(project!.id!); const environmentVariablesObj = await this.getEnvVariables(project!.id!);
// To set project DNS // To set project DNS
if (deploymentData.environment === Environment.Production) { if (deploymentData.environment === Environment.Production) {
// On deleting deployment later, project DNS deployment is also deleted // On deleting deployment later, project DNS deployment is also deleted
// So publish project DNS deployment first so that ApplicationDeploymentRecord for the same is available when deleting deployment later // So publish project DNS deployment first so that ApplicationDeploymentRecord for the same is available when deleting deployment later
await this.laconicRegistry.createApplicationDeploymentRequest({ const { applicationDeploymentRequestId, applicationDeploymentRequestData } =
deployment: newDeployment, await this.laconicRegistry.createApplicationDeploymentRequest({
appName: repo, deployment: dnsDeployment,
repository: repoUrl, appName: repo,
environmentVariables: environmentVariablesObj, repository: repoUrl,
dns: `${newDeployment.project.name}`, environmentVariables: environmentVariablesObj,
auctionId: project.auctionId!, dns: `${dnsDeployment.project.name}`,
lrn: deployerLrn, auctionId: project.auctionId!,
lrn: deployerLrn,
});
await this.db.updateDeploymentById(dnsDeployment.id, {
applicationDeploymentRequestId,
applicationDeploymentRequestData,
}); });
} }
const { applicationDeploymentRequestId, applicationDeploymentRequestData } = const { applicationDeploymentRequestId, applicationDeploymentRequestData } =
// Create requests for all the deployers // Create requests for all the deployers
await this.laconicRegistry.createApplicationDeploymentRequest({ await this.laconicRegistry.createApplicationDeploymentRequest({
deployment: newDeployment, deployment: deployment,
appName: repo, appName: repo,
repository: repoUrl, repository: repoUrl,
auctionId: project.auctionId!, auctionId: project.auctionId!,
lrn: deployerLrn, lrn: deployerLrn,
environmentVariables: environmentVariablesObj, environmentVariables: environmentVariablesObj,
dns: `${newDeployment.project.name}-${newDeployment.id}`, dns: `${deployment.project.name}-${deployment.id}`,
}); });
await this.db.updateDeploymentById(newDeployment.id, { await this.db.updateDeploymentById(deployment.id, {
applicationDeploymentRequestId, applicationDeploymentRequestId,
applicationDeploymentRequestData, applicationDeploymentRequestData,
}); });
return newDeployment; return deployment;
} }
async createDeploymentFromData( async createDeploymentFromData(
@ -790,6 +813,7 @@ export class Service {
deployerLrn: string, deployerLrn: string,
applicationRecordId: string, applicationRecordId: string,
applicationRecordData: ApplicationRecord, applicationRecordData: ApplicationRecord,
isDNS: boolean,
): Promise<Deployment> { ): Promise<Deployment> {
const newDeployment = await this.db.addDeployment({ const newDeployment = await this.db.addDeployment({
project: data.project, project: data.project,
@ -807,6 +831,7 @@ export class Service {
deployer: Object.assign(new Deployer(), { deployer: Object.assign(new Deployer(), {
deployerLrn, deployerLrn,
}), }),
isDNS
}); });
log(`Created deployment ${newDeployment.id}`); log(`Created deployment ${newDeployment.id}`);
@ -1183,6 +1208,8 @@ export class Service {
}, },
}); });
// Compare deployer in DNS while deleting
if (deployment && deployment.applicationDeploymentRecordId) { if (deployment && deployment.applicationDeploymentRecordId) {
// If deployment is current, remove deployment for project subdomain as well // If deployment is current, remove deployment for project subdomain as well
if (deployment.isCurrent) { if (deployment.isCurrent) {