Newer
Older
import URL from 'url';
import { logger } from '../../logger';
import * as packageCache from '../../util/cache/package';
import { Http } from '../../util/http';
import { GetReleasesConfig, ReleaseResult } from '../common';
export const id = 'terraform-provider';
export const defaultRegistryUrls = [
'https://registry.terraform.io',
'https://releases.hashicorp.com',
];
export const registryStrategy = 'hunt';
interface TerraformProvider {
namespace: string;
name: string;
provider: string;
source?: string;
versions: string[];
}
interface TerraformProviderReleaseBackend {
[key: string]: {
name: string;
versions: VersionsReleaseBackend;
};
}
interface VersionsReleaseBackend {
[key: string]: Record<string, any>;
}
async function queryRegistry(
lookupName: string,
registryURL: string,
repository: string
): Promise<ReleaseResult> {
const backendURL = `${registryURL}/v1/providers/${repository}`;
const res = (await http.getJson<TerraformProvider>(backendURL)).body;
const dep: ReleaseResult = {
name: repository,
versions: {},
releases: null,
};
if (res.source) {
dep.sourceUrl = res.source;
dep.releases = res.versions.map((version) => ({
version,
}));
dep.homepage = `${registryURL}/providers/${repository}`;
logger.trace({ dep }, 'dep');
return dep;
}
async function queryReleaseBackend(
lookupName: string,
registryURL: string,
repository: string
): Promise<ReleaseResult> {
const backendLookUpName = `terraform-provider-${lookupName}`;
const backendURL = registryURL + `/index.json`;
const res = (await http.getJson<TerraformProviderReleaseBackend>(backendURL))
.body;
const dep: ReleaseResult = {
name: repository,
versions: {},
releases: null,
};
dep.releases = Object.keys(res[backendLookUpName].versions).map(
(version) => ({
version,
})
);
logger.trace({ dep }, 'dep');
return dep;
/**
* terraform-provider.getReleases
*
* This function will fetch a provider from the public Terraform registry and return all semver versions.
*/
export async function getReleases({
lookupName,
registryUrl,
}: GetReleasesConfig): Promise<ReleaseResult | null> {
const repository = `hashicorp/${lookupName}`;
const cacheNamespace = 'terraform-provider';
const pkgUrl = `${registryUrl}/${repository}`;
const cachedResult = await packageCache.get<ReleaseResult>(
cacheNamespace,
pkgUrl
);
// istanbul ignore if
if (cachedResult) {
return cachedResult;
}
logger.debug({ lookupName }, 'terraform-provider.getDependencies()');
let dep: ReleaseResult = null;
const registryHost = URL.parse(registryUrl).host;
if (registryHost === 'registry.terraform.io') {
dep = await queryRegistry(lookupName, registryUrl, repository);
} else if (registryHost === 'releases.hashicorp.com') {
dep = await queryReleaseBackend(lookupName, registryUrl, repository);
}
const cacheMinutes = 30;
await packageCache.set(cacheNamespace, pkgUrl, dep, cacheMinutes);
return dep;
}