Skip to content

Commit

Permalink
refactor(manager/terraform): remove usages of any and use types (#19815)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
  • Loading branch information
secustor and viceice committed Jan 23, 2023
1 parent ca66ada commit 72bd0d3
Show file tree
Hide file tree
Showing 13 changed files with 157 additions and 104 deletions.
6 changes: 5 additions & 1 deletion lib/modules/manager/terraform/base.ts
Expand Up @@ -2,6 +2,7 @@ import is from '@sindresorhus/is';
import { regEx } from '../../../util/regex';
import { TerraformProviderDatasource } from '../../datasource/terraform-provider';
import type { PackageDependency } from '../types';
import type { TerraformDefinitionFile } from './hcl/types';
import type { ProviderLock } from './lockfile/types';
import { getLockedVersion, massageProviderLookupName } from './util';

Expand All @@ -17,7 +18,10 @@ export abstract class DependencyExtractor {
* @param hclRoot HCL parsing artifact.
* @param locks currently existing locks
*/
abstract extract(hclRoot: any, locks: ProviderLock[]): PackageDependency[];
abstract extract(
hclRoot: TerraformDefinitionFile,
locks: ProviderLock[]
): PackageDependency[];
}

export abstract class TerraformProviderExtractor extends DependencyExtractor {
Expand Down
4 changes: 2 additions & 2 deletions lib/modules/manager/terraform/extractors.ts
@@ -1,15 +1,15 @@
import type { DependencyExtractor } from './base';
import { ModuleExtractor } from './extractors/others/modules';
import { ProvidersExtractor } from './extractors/others/providers';
import { GenericDockerImageRef } from './extractors/resources/generic-docker-image-ref';
import { GenericDockerImageRefExtractor } from './extractors/resources/generic-docker-image-ref';
import { HelmReleaseExtractor } from './extractors/resources/helm-release';
import { TerraformWorkspaceExtractor } from './extractors/resources/terraform-workspace';
import { RequiredProviderExtractor } from './extractors/terraform-block/required-provider';
import { TerraformVersionExtractor } from './extractors/terraform-block/terraform-version';

export const resourceExtractors: DependencyExtractor[] = [
new HelmReleaseExtractor(),
new GenericDockerImageRef(),
new GenericDockerImageRefExtractor(),
new TerraformWorkspaceExtractor(),
new RequiredProviderExtractor(),
new TerraformVersionExtractor(),
Expand Down
23 changes: 10 additions & 13 deletions lib/modules/manager/terraform/extractors/others/modules.ts
Expand Up @@ -7,6 +7,7 @@ import { GithubTagsDatasource } from '../../../../datasource/github-tags';
import { TerraformModuleDatasource } from '../../../../datasource/terraform-module';
import type { PackageDependency } from '../../../types';
import { DependencyExtractor } from '../../base';
import type { TerraformDefinitionFile } from '../../hcl/types';

export const githubRefMatchRegex = regEx(
/github\.com([/:])(?<project>[^/]+\/[a-z0-9-_.]+).*\?ref=(?<tag>.*)$/i
Expand All @@ -27,25 +28,21 @@ export class ModuleExtractor extends DependencyExtractor {
return ['module'];
}

extract(hclRoot: any): PackageDependency[] {
extract(hclRoot: TerraformDefinitionFile): PackageDependency[] {
const modules = hclRoot.module;
if (is.nullOrUndefined(modules)) {
return [];
}

const dependencies = [];
for (const moduleKeys of Object.keys(modules)) {
const module = modules[moduleKeys];
for (const moduleElement of module) {
const dep = {
currentValue: moduleElement.version,
managerData: {
source: moduleElement.source,
},
};
const massagedDep = this.analyseTerraformModule(dep);
dependencies.push(massagedDep);
}
for (const moduleElement of Object.values(modules).flat()) {
const dep = {
currentValue: moduleElement.version,
managerData: {
source: moduleElement.source,
},
};
dependencies.push(this.analyseTerraformModule(dep));
}
return dependencies;
}
Expand Down
7 changes: 5 additions & 2 deletions lib/modules/manager/terraform/extractors/others/providers.ts
@@ -1,14 +1,18 @@
import is from '@sindresorhus/is';
import type { PackageDependency } from '../../../types';
import { TerraformProviderExtractor } from '../../base';
import type { TerraformDefinitionFile } from '../../hcl/types';
import type { ProviderLock } from '../../lockfile/types';

export class ProvidersExtractor extends TerraformProviderExtractor {
getCheckList(): string[] {
return ['provider'];
}

extract(hclRoot: any, locks: ProviderLock[]): PackageDependency[] {
extract(
hclRoot: TerraformDefinitionFile,
locks: ProviderLock[]
): PackageDependency[] {
const providerTypes = hclRoot?.provider;
if (is.nullOrUndefined(providerTypes)) {
return [];
Expand All @@ -22,7 +26,6 @@ export class ProvidersExtractor extends TerraformProviderExtractor {
currentValue: providerTypeElement.version,
managerData: {
moduleName: providerTypeName,
source: providerTypeElement.source,
},
},
locks,
Expand Down
@@ -1,7 +1,7 @@
import { GenericDockerImageRef } from './generic-docker-image-ref';
import { GenericDockerImageRefExtractor } from './generic-docker-image-ref';

describe('modules/manager/terraform/extractors/resources/generic-docker-image', () => {
const extractor = new GenericDockerImageRef();
describe('modules/manager/terraform/extractors/resources/generic-docker-image-ref', () => {
const extractor = new GenericDockerImageRefExtractor();

it('return empty array if no resource is found', () => {
const res = extractor.extract({});
Expand Down
Expand Up @@ -2,14 +2,15 @@ import is from '@sindresorhus/is';
import { getDep } from '../../../dockerfile/extract';
import type { PackageDependency } from '../../../types';
import { DependencyExtractor } from '../../base';
import type { TerraformDefinitionFile } from '../../hcl/types';
import { generic_image_resource } from './utils';

export class GenericDockerImageRef extends DependencyExtractor {
export class GenericDockerImageRefExtractor extends DependencyExtractor {
getCheckList(): string[] {
return generic_image_resource.map((value) => `"${value.type}"`);
}

extract(hclMap: any): PackageDependency[] {
extract(hclMap: TerraformDefinitionFile): PackageDependency[] {
const resourceTypMap = hclMap.resource;
if (is.nullOrUndefined(resourceTypMap)) {
return [];
Expand All @@ -21,18 +22,13 @@ export class GenericDockerImageRef extends DependencyExtractor {
const { type, path } = image_resource_def;
const resourceInstancesMap = resourceTypMap[type];
// is there a resource with current looked at type ( `image_resource_def` )
if (is.nullOrUndefined(resourceInstancesMap)) {
if (!is.nonEmptyObject(resourceInstancesMap)) {
continue;
}

// loop over instances of a resource type
for (const instanceName of Object.keys(resourceInstancesMap)) {
const instanceList = resourceInstancesMap[instanceName];
for (const instance of instanceList) {
dependencies.push(
...this.walkPath({ depType: type }, instance, path)
);
}
for (const instance of Object.values(resourceInstancesMap).flat()) {
dependencies.push(...this.walkPath({ depType: type }, instance, path));
}
}
return dependencies;
Expand All @@ -48,14 +44,14 @@ export class GenericDockerImageRef extends DependencyExtractor {
*/
private walkPath(
abstractDep: PackageDependency,
parentElement: any,
parentElement: unknown,
leftPath: string[]
): PackageDependency[] {
const dependencies: PackageDependency[] = [];
// if there are no path elements left, we have reached the end of the path
if (leftPath.length === 0) {
// istanbul ignore if
if (is.nullOrUndefined(parentElement)) {
if (!is.nonEmptyString(parentElement)) {
return [
{
...abstractDep,
Expand All @@ -75,7 +71,9 @@ export class GenericDockerImageRef extends DependencyExtractor {
const pathElement = leftPath[0];

// get sub element
const element = parentElement[pathElement];
const element = is.nonEmptyObject(parentElement)
? parentElement[pathElement]
: null;
if (is.nullOrUndefined(element)) {
return leftPath.length === 1 // if this is the last element assume a false defined dependency
? [
Expand Down
45 changes: 22 additions & 23 deletions lib/modules/manager/terraform/extractors/resources/helm-release.ts
Expand Up @@ -4,43 +4,42 @@ import { HelmDatasource } from '../../../../datasource/helm';
import { isOCIRegistry } from '../../../helmv3/utils';
import type { PackageDependency } from '../../../types';
import { DependencyExtractor } from '../../base';
import type { TerraformDefinitionFile } from '../../hcl/types';
import { checkIfStringIsPath } from '../../util';

export class HelmReleaseExtractor extends DependencyExtractor {
getCheckList(): string[] {
return [`"helm_release"`];
}

override extract(hclMap: any): PackageDependency[] {
override extract(hclMap: TerraformDefinitionFile): PackageDependency[] {
const dependencies = [];

const helmReleases = hclMap?.resource?.helm_release;
if (is.nullOrUndefined(helmReleases)) {
return [];
}
for (const helmReleaseName of Object.keys(helmReleases)) {
for (const helmRelease of helmReleases[helmReleaseName]) {
const dep: PackageDependency = {
currentValue: helmRelease.version,
depType: 'helm_release',
depName: helmRelease.chart,
datasource: HelmDatasource.id,
};
if (!is.nullOrUndefined(helmRelease.repository)) {
dep.registryUrls = [helmRelease.repository];
}
if (!helmRelease.chart) {
dep.skipReason = 'invalid-name';
} else if (isOCIRegistry(helmRelease.chart)) {
// For oci charts, we remove the oci:// and use the docker datasource
dep.depName = helmRelease.chart.replace('oci://', '');
dep.datasource = DockerDatasource.id;
} else if (checkIfStringIsPath(helmRelease.chart)) {
dep.skipReason = 'local-chart';
}

dependencies.push(dep);
for (const helmRelease of Object.values(helmReleases).flat()) {
const dep: PackageDependency = {
currentValue: helmRelease.version,
depType: 'helm_release',
depName: helmRelease.chart,
datasource: HelmDatasource.id,
};
if (is.nonEmptyString(helmRelease.repository)) {
dep.registryUrls = [helmRelease.repository];
}
if (!helmRelease.chart) {
dep.skipReason = 'invalid-name';
} else if (isOCIRegistry(helmRelease.chart)) {
// For oci charts, we remove the oci:// and use the docker datasource
dep.depName = helmRelease.chart.replace('oci://', '');
dep.datasource = DockerDatasource.id;
} else if (checkIfStringIsPath(helmRelease.chart)) {
dep.skipReason = 'local-chart';
}

dependencies.push(dep);
}

return dependencies;
Expand Down
@@ -1,34 +1,33 @@
import is from '@sindresorhus/is';
import type { PackageDependency } from '../../../types';
import type { TerraformDefinitionFile } from '../../hcl/types';
import { TerraformVersionExtractor } from '../terraform-block/terraform-version';

export class TerraformWorkspaceExtractor extends TerraformVersionExtractor {
override getCheckList(): string[] {
return [`"tfe_workspace"`];
}

override extract(hclMap: any): PackageDependency[] {
override extract(hclMap: TerraformDefinitionFile): PackageDependency[] {
const dependencies = [];

const workspaces = hclMap?.resource?.tfe_workspace;
if (is.nullOrUndefined(workspaces)) {
return [];
}

for (const workspaceName of Object.keys(workspaces)) {
for (const workspace of workspaces[workspaceName]) {
const dep: PackageDependency = this.analyseTerraformVersion({
currentValue: workspace.terraform_version,
});
for (const workspace of Object.values(workspaces).flat()) {
const dep: PackageDependency = this.analyseTerraformVersion({
currentValue: workspace.terraform_version,
});

if (is.nullOrUndefined(workspace.terraform_version)) {
dep.skipReason = 'no-version';
}
dependencies.push({
...dep,
depType: 'tfe_workspace',
});
if (is.nullOrUndefined(workspace.terraform_version)) {
dep.skipReason = 'no-version';
}
dependencies.push({
...dep,
depType: 'tfe_workspace',
});
}
return dependencies;
}
Expand Down
@@ -1,14 +1,21 @@
import is from '@sindresorhus/is';
import type { PackageDependency } from '../../../types';
import { TerraformProviderExtractor } from '../../base';
import type {
TerraformDefinitionFile,
TerraformRequiredProvider,
} from '../../hcl/types';
import type { ProviderLock } from '../../lockfile/types';

export class RequiredProviderExtractor extends TerraformProviderExtractor {
getCheckList(): string[] {
return ['required_providers'];
}

extract(hclRoot: any, locks: ProviderLock[]): PackageDependency[] {
extract(
hclRoot: TerraformDefinitionFile,
locks: ProviderLock[]
): PackageDependency[] {
const terraformBlocks = hclRoot?.terraform;
if (is.nullOrUndefined(terraformBlocks)) {
return [];
Expand All @@ -21,35 +28,31 @@ export class RequiredProviderExtractor extends TerraformProviderExtractor {
continue;
}

for (const requiredProvidersMap of requiredProviders) {
for (const requiredProviderName of Object.keys(requiredProvidersMap)) {
const value = requiredProvidersMap[requiredProviderName];

// name = version declaration method
let dep: PackageDependency;
if (typeof value === 'string') {
dep = {
currentValue: value,
managerData: {
moduleName: requiredProviderName,
},
};
}
const entries: [string, TerraformRequiredProvider | string][] =
requiredProviders.flatMap(Object.entries);
for (const [requiredProviderName, value] of entries) {
// name = version declaration method
let dep: PackageDependency;
if (is.string(value)) {
dep = {
currentValue: value,
managerData: {
moduleName: requiredProviderName,
},
};
} else {
// block declaration aws = { source = 'aws', version = '2.0.0' }
dep ??= {
dep = {
currentValue: value['version'],
managerData: {
moduleName: requiredProviderName,
source: value['source'],
},
};
const massagedDep = this.analyzeTerraformProvider(
dep,
locks,
'required_provider'
);
dependencies.push(massagedDep);
}
dependencies.push(
this.analyzeTerraformProvider(dep, locks, 'required_provider')
);
}
}
return dependencies;
Expand Down
Expand Up @@ -2,13 +2,14 @@ import is from '@sindresorhus/is';
import { GithubReleasesDatasource } from '../../../../datasource/github-releases';
import type { PackageDependency } from '../../../types';
import { DependencyExtractor } from '../../base';
import type { TerraformDefinitionFile } from '../../hcl/types';

export class TerraformVersionExtractor extends DependencyExtractor {
getCheckList(): string[] {
return ['required_version'];
}

extract(hclRoot: any): PackageDependency[] {
extract(hclRoot: TerraformDefinitionFile): PackageDependency[] {
const terraformBlocks = hclRoot?.terraform;
if (is.nullOrUndefined(terraformBlocks)) {
return [];
Expand Down

0 comments on commit 72bd0d3

Please sign in to comment.