Skip to content

Commit

Permalink
feat(terraform-provider): renovate required_providers (#6550)
Browse files Browse the repository at this point in the history
  • Loading branch information
secustor committed Jun 28, 2020
1 parent 1a31dc1 commit db62294
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 35 deletions.
13 changes: 13 additions & 0 deletions lib/manager/terraform/__fixtures__/1.tf
Expand Up @@ -159,3 +159,16 @@ module "gittags_http" {
module "gittags_ssh" {
source = "git::ssh://git@bitbucket.com/hashicorp/example?ref=v1.0.3"
}

terraform {
required_providers {
aws = ">= 2.7.0"
}
}

terraform {
required_providers {
aws = ">= 2.5.0"
azurerm = ">= 2.0.0"
}
}
23 changes: 22 additions & 1 deletion lib/manager/terraform/__snapshots__/extract.spec.ts.snap
Expand Up @@ -140,7 +140,7 @@ Object {
"depName": "helm",
"depNameShort": "helm",
"depType": "terraform",
"skipReason": "no-version",
"skipReason": "unsupported-version",
},
Object {
"currentValue": "V1.9",
Expand Down Expand Up @@ -192,6 +192,27 @@ Object {
"depType": "gitTags",
"lookupName": "ssh://git@bitbucket.com/hashicorp/example",
},
Object {
"currentValue": ">= 2.7.0",
"datasource": "terraform-provider",
"depName": "aws",
"depNameShort": "aws",
"depType": "terraform",
},
Object {
"currentValue": ">= 2.5.0",
"datasource": "terraform-provider",
"depName": "aws",
"depNameShort": "aws",
"depType": "terraform",
},
Object {
"currentValue": ">= 2.0.0",
"datasource": "terraform-provider",
"depName": "azurerm",
"depNameShort": "azurerm",
"depType": "terraform",
},
],
}
`;
7 changes: 6 additions & 1 deletion lib/manager/terraform/extract.spec.ts
Expand Up @@ -19,7 +19,7 @@ describe('lib/manager/terraform/extract', () => {
it('extracts', () => {
const res = extractPackageFile(tf1);
expect(res).toMatchSnapshot();
expect(res.deps).toHaveLength(27);
expect(res.deps).toHaveLength(30);
expect(res.deps.filter((dep) => dep.skipReason)).toHaveLength(6);
});
it('returns null if only local deps', () => {
Expand All @@ -42,6 +42,11 @@ describe('lib/manager/terraform/extract', () => {
TerraformDependencyTypes.unknown
);
});
it('returns TerraformDependencyTypes.required_providers', () => {
expect(getTerraformDependencyType('required_providers')).toBe(
TerraformDependencyTypes.required_providers
);
});
it('returns TerraformDependencyTypes.unknown on empty string', () => {
expect(getTerraformDependencyType('')).toBe(
TerraformDependencyTypes.unknown
Expand Down
87 changes: 55 additions & 32 deletions lib/manager/terraform/extract.ts
Expand Up @@ -11,6 +11,7 @@ export enum TerraformDependencyTypes {
unknown = 'unknown',
module = 'module',
provider = 'provider',
required_providers = 'required_providers',
}

export function getTerraformDependencyType(
Expand All @@ -23,52 +24,80 @@ export function getTerraformDependencyType(
case 'provider': {
return TerraformDependencyTypes.provider;
}
case 'required_providers': {
return TerraformDependencyTypes.required_providers;
}
default: {
return TerraformDependencyTypes.unknown;
}
}
}

const dependencyBlockExtractionRegex = /^\s*(?<type>module|provider|required_providers)\s+("(?<lookupName>[^"]+)"\s+)?{\s*$/;
const keyValueExtractionRegex = /^\s*(?<key>[^\s]+)\s+=\s+"(?<value>[^"]+)"\s*$/; // extracts `exampleKey = exampleValue`

export function extractPackageFile(content: string): PackageFile | null {
logger.trace({ content }, 'terraform.extractPackageFile()');
if (!content.includes('module "') && !content.includes('provider "')) {
if (
!content.includes('module "') &&
!content.includes('provider "') &&
!content.includes('required_providers ')
) {
return null;
}
const deps: PackageDependency[] = [];
try {
const lines = content.split('\n');
for (let lineNumber = 0; lineNumber < lines.length; lineNumber += 1) {
let line = lines[lineNumber];
const terraformDependency = /^(module|provider)\s+"([^"]+)"\s+{\s*$/.exec(
line
);
const terraformDependency = dependencyBlockExtractionRegex.exec(line);
if (terraformDependency) {
logger.trace(`Matched ${terraformDependency[1]} on line ${lineNumber}`);
const tfDepType: TerraformDependencyTypes = getTerraformDependencyType(
terraformDependency[1]
logger.trace(
`Matched ${terraformDependency.groups.type} on line ${lineNumber}`
);
const tfDepType = getTerraformDependencyType(
terraformDependency.groups.type
);
const dep: PackageDependency = {
managerData: {
moduleName: terraformDependency[2],
terraformDependencyType: tfDepType,
},
};

if (tfDepType === TerraformDependencyTypes.unknown) {
/* istanbul ignore next */ logger.trace(
`Could not identify TerraformDependencyType ${terraformDependency[1]} on line ${lineNumber}.`
/* istanbul ignore next */ logger.warn(
`Could not identify TerraformDependencyType ${terraformDependency.groups.type} on line ${lineNumber}.`
);
} else if (tfDepType === TerraformDependencyTypes.required_providers) {
do {
const dep: PackageDependency = {
managerData: {
terraformDependencyType: tfDepType,
},
};

lineNumber += 1;
line = lines[lineNumber];
const kvMatch = keyValueExtractionRegex.exec(line);
if (kvMatch) {
dep.currentValue = kvMatch.groups.value;
dep.managerData.moduleName = kvMatch.groups.key;
dep.managerData.versionLine = lineNumber;
deps.push(dep);
}
} while (line.trim() !== '}');
} else {
const dep: PackageDependency = {
managerData: {
moduleName: terraformDependency.groups.lookupName,
terraformDependencyType: tfDepType,
},
};
do {
lineNumber += 1;
line = lines[lineNumber];
const kvMatch = /^\s*([^\s]+)\s+=\s+"([^"]+)"\s*$/.exec(line);
const kvMatch = keyValueExtractionRegex.exec(line);
if (kvMatch) {
const [, key, value] = kvMatch;
if (key === 'version') {
dep.currentValue = value;
if (kvMatch.groups.key === 'version') {
dep.currentValue = kvMatch.groups.value;
dep.managerData.versionLine = lineNumber;
} else if (key === 'source') {
dep.managerData.source = value;
} else if (kvMatch.groups.key === 'source') {
dep.managerData.source = kvMatch.groups.value;
dep.managerData.sourceLine = lineNumber;
}
}
Expand Down Expand Up @@ -100,7 +129,6 @@ export function extractPackageFile(content: string): PackageFile | null {
dep.currentValue = githubRefMatch[3];
dep.datasource = datasourceGithubTags.id;
dep.lookupName = depNameShort;
dep.managerData.lineNumber = dep.managerData.sourceLine;
if (!isVersion(dep.currentValue)) {
dep.skipReason = SkipReason.UnsupportedVersion;
}
Expand All @@ -119,7 +147,6 @@ export function extractPackageFile(content: string): PackageFile | null {
}
dep.currentValue = gitTagsRefMatch[4];
dep.datasource = datasourceGitTags.id;
dep.managerData.lineNumber = dep.managerData.sourceLine;
if (!isVersion(dep.currentValue)) {
dep.skipReason = SkipReason.UnsupportedVersion;
}
Expand All @@ -131,7 +158,6 @@ export function extractPackageFile(content: string): PackageFile | null {
dep.depType = 'terraform';
dep.depName = moduleParts.join('/');
dep.depNameShort = dep.depName;
dep.managerData.lineNumber = dep.managerData.versionLine;
dep.datasource = datasourceTerraformModule.id;
}
} else {
Expand All @@ -140,19 +166,16 @@ export function extractPackageFile(content: string): PackageFile | null {
}
} else if (
dep.managerData.terraformDependencyType ===
TerraformDependencyTypes.provider
TerraformDependencyTypes.provider ||
dep.managerData.terraformDependencyType ===
TerraformDependencyTypes.required_providers
) {
dep.depType = 'terraform';
dep.depName = dep.managerData.moduleName;
dep.depNameShort = dep.managerData.moduleName;
dep.managerData.lineNumber = dep.managerData.versionLine;
dep.datasource = datasourceTerraformProvider.id;
if (dep.managerData.lineNumber) {
if (!isValid(dep.currentValue)) {
dep.skipReason = SkipReason.UnsupportedVersion;
}
} else if (!dep.skipReason) {
dep.skipReason = SkipReason.NoVersion;
if (!isValid(dep.currentValue)) {
dep.skipReason = SkipReason.UnsupportedVersion;
}
}
delete dep.managerData;
Expand Down
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -95,7 +95,8 @@
"Tanuel <tanuel.mategi@gmail.com>",
"Viral Ruparel <viralruparel@gmail.com>",
"Vladimir Starkov <iamstarkov@gmail.com>",
"Mikhail Yakushin <driver733@gmail.com>"
"Mikhail Yakushin <driver733@gmail.com>",
"Sebastian Poxhofer <sebastian@poxhofer.at>"
],
"license": "AGPL-3.0",
"bugs": {
Expand Down

0 comments on commit db62294

Please sign in to comment.