terrac
Version:
A minimal private module registry for Terraform and OpenTofu
115 lines (114 loc) • 4.92 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BackendAzure = exports.configSchemaAzure = void 0;
const shared_1 = require("./shared");
const errors_1 = require("../errors");
const storage_blob_1 = require("@azure/storage-blob");
const identity_1 = require("@azure/identity");
const lodash_1 = require("lodash");
const Joi = require("joi");
exports.configSchemaAzure = Joi.object({
type: Joi.string().allow('azure').required().description('Backend type'),
account: Joi.string().required().description('Account name'),
container: Joi.string().required().description('Container name'),
fileNamePrefix: Joi.string().optional().allow('').description('File name prefix'),
});
class BackendAzure {
constructor(config) {
this.config = config;
this.serviceUrl = process.env.TERRAC_BACKEND_AZURE_SERVICE_URL || `https://${this.config.account}.blob.core.windows.net`;
const serviceClient = process.env.AZURITE_ACCOUNT_NAME && process.env.AZURITE_ACCOUNT_KEY ?
new storage_blob_1.BlobServiceClient(this.serviceUrl, new storage_blob_1.StorageSharedKeyCredential(process.env.AZURITE_ACCOUNT_NAME, process.env.AZURITE_ACCOUNT_KEY)) :
new storage_blob_1.BlobServiceClient(this.serviceUrl, new identity_1.DefaultAzureCredential());
this.containerClient = serviceClient.getContainerClient(this.config.container);
}
async upload(name, version, packagePath) {
await this.uploadFile(this.getPackageFileName(name, version), packagePath);
}
async getSourceUrl(name, version) {
let targetVersion = version;
if (!targetVersion) {
const meta = await this.getMeta(name);
targetVersion = meta.version;
}
const fileName = this.getPackageFileName(name, targetVersion);
if (!this.fileNameExists(fileName)) {
throw new errors_1.ModuleNotFoundError();
}
const blobClient = await this.containerClient.getBlobClient(fileName);
return blobClient.url;
}
async list(name) {
const moduleList = [];
const prefix = this.config.fileNamePrefix || '';
if (name) {
if (!(await this.fileNameExists(this.getMetaFileName(name)))) {
throw new errors_1.ModuleNotFoundError();
}
const meta = await this.getMeta(name);
for (const release of meta.releases) {
moduleList.push({
name,
version: release.version,
});
}
}
else {
const keys = await this.listFileNames(prefix);
const names = (0, lodash_1.uniq)(keys.map(key => key.replace(prefix, '').split('/').shift()));
for (const name of names) {
moduleList.push({
name,
});
}
}
return moduleList;
}
async exists(name, version) {
const fileName = version ? this.getPackageFileName(name, version) : this.getMetaFileName(name);
return this.fileNameExists(fileName);
}
async getMeta(name) {
const fileName = this.getMetaFileName(name);
if (await this.fileNameExists(fileName)) {
const bolbClient = this.containerClient.getBlobClient(fileName);
const result = await bolbClient.downloadToBuffer();
return JSON.parse(result.toString());
}
return (0, shared_1.getNewMeta)(name);
}
async saveMeta(meta) {
const metaKey = this.getMetaFileName(meta.name);
await this.uploadObject(metaKey, JSON.stringify(meta));
}
async uploadFile(fileName, localFilePath) {
const blockBlobClient = await this.containerClient.getBlockBlobClient(fileName);
await blockBlobClient.uploadFile(localFilePath);
}
async uploadObject(fileName, data) {
const blockBlobClient = await this.containerClient.getBlockBlobClient(fileName);
await blockBlobClient.uploadData(Buffer.from(data));
}
async fileNameExists(fileName) {
const blobClient = this.containerClient.getBlobClient(fileName);
return blobClient.exists();
}
async listFileNames(prefix) {
const fileNames = [];
for await (const blob of this.containerClient.listBlobsFlat({ prefix })) {
fileNames.push(blob.name);
}
return fileNames;
}
getMetaFileName(name) {
const basePath = `${name}/meta.json`;
return this.config.fileNamePrefix ? `${this.config.fileNamePrefix}${basePath}` : basePath;
}
getPackageFileName(name, version) {
var _a;
const basePath = `${name}/${version}/module.zip`;
const prefix = (_a = this.config.fileNamePrefix) !== null && _a !== void 0 ? _a : '';
return `${prefix}${basePath}`;
}
}
exports.BackendAzure = BackendAzure;