Skip to content

Commit

Permalink
feat(terraform): Fetch ziphash for lock refreshes (#25059)
Browse files Browse the repository at this point in the history
Co-authored-by: Rhys Arkins <rhys@arkins.net>
Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
  • Loading branch information
4 people committed Oct 30, 2023
1 parent 14c7eaf commit 16be3cf
Show file tree
Hide file tree
Showing 8 changed files with 416 additions and 7 deletions.
88 changes: 84 additions & 4 deletions lib/modules/datasource/terraform-provider/index.spec.ts
Expand Up @@ -9,7 +9,7 @@ const hashicorpGoogleBetaReleases = Fixtures.get(
'releaseBackendIndexGoogleBeta.json'
);
const serviceDiscoveryResult = Fixtures.get('service-discovery.json');
const telmateProxmocVersions = Fixtures.get(
const telmateProxmoxVersions = Fixtures.get(
'telmate-proxmox-versions-response.json'
);

Expand Down Expand Up @@ -282,7 +282,7 @@ describe('modules/datasource/terraform-provider/index', () => {
httpMock
.scope(primaryUrl)
.get('/v1/providers/Telmate/proxmox/versions')
.reply(200, telmateProxmocVersions)
.reply(200, telmateProxmoxVersions)
.get('/.well-known/terraform.json')
.reply(200, serviceDiscoveryResult);
const result = await terraformProviderDatasource.getBuilds(
Expand All @@ -297,7 +297,7 @@ describe('modules/datasource/terraform-provider/index', () => {
httpMock
.scope(primaryUrl)
.get('/v1/providers/Telmate/proxmox/versions')
.reply(200, telmateProxmocVersions)
.reply(200, telmateProxmoxVersions)
.get('/.well-known/terraform.json')
.reply(200, serviceDiscoveryResult)
.get('/v1/providers/Telmate/proxmox/2.6.1/download/darwin/arm64')
Expand Down Expand Up @@ -377,7 +377,7 @@ describe('modules/datasource/terraform-provider/index', () => {
httpMock
.scope(primaryUrl)
.get('/v1/providers/Telmate/proxmox/versions')
.reply(200, telmateProxmocVersions)
.reply(200, telmateProxmoxVersions)
.get('/.well-known/terraform.json')
.reply(200, serviceDiscoveryResult)
.get('/v1/providers/Telmate/proxmox/2.6.1/download/darwin/arm64')
Expand Down Expand Up @@ -411,4 +411,84 @@ describe('modules/datasource/terraform-provider/index', () => {
expect(res).toBeNull();
});
});

describe('getZipHashes', () => {
it('can fetch zip hashes', async () => {
httpMock
.scope(secondaryUrl)
.get(
'/terraform-provider-azurerm/2.56.0/terraform-provider-azurerm_2.56.0_SHA256SUMS'
)
.reply(
200,
'500d4e787bf046bbe64c4853530aff3dfddee2fdbff0087d7b1e7a8c24388628 terraform-provider-azurerm_2.56.0_darwin_amd64.zip\n' +
'766ff42596d643f9945b3aab2e83e306fe77c3020a5196366bbbb77eeea13b71 terraform-provider-azurerm_2.56.0_linux_amd64.zip\n' +
'fbdb892d9822ed0e4cb60f2fedbdbb556e4da0d88d3b942ae963ed6ff091e48f terraform-provider-azurerm_2.56.0_manifest.json'
);

const res = await terraformProviderDatasource.getZipHashes([
{
name: 'azurerm',
version: '2.56.0',
os: 'linux',
arch: 'amd64',
filename: 'terraform-provider-azurerm_2.56.0_linux_amd64.zip',
url: 'https://releases.hashicorp.com/terraform-provider-azurerm/2.56.0/terraform-provider-azurerm_2.56.0_linux_amd64.zip',
shasums_url:
'https://releases.hashicorp.com/terraform-provider-azurerm/2.56.0/terraform-provider-azurerm_2.56.0_SHA256SUMS',
},
]);

expect(res).toMatchObject([
'500d4e787bf046bbe64c4853530aff3dfddee2fdbff0087d7b1e7a8c24388628',
'766ff42596d643f9945b3aab2e83e306fe77c3020a5196366bbbb77eeea13b71',
'fbdb892d9822ed0e4cb60f2fedbdbb556e4da0d88d3b942ae963ed6ff091e48f',
]);
});

it('does not fetch anything when there are no builds passed in', async () => {
const res = await terraformProviderDatasource.getZipHashes([]);

expect(res).toBeEmptyArray();
});

it('does not fetch anything when there is no shasums_url defined', async () => {
const res = await terraformProviderDatasource.getZipHashes([
{
name: 'azurerm',
version: '2.56.0',
os: 'linux',
arch: 'amd64',
filename: 'terraform-provider-azurerm_2.56.0_linux_amd64.zip',
url: 'https://releases.hashicorp.com/terraform-provider-azurerm/2.56.0/terraform-provider-azurerm_2.56.0_linux_amd64.zip',
},
]);

expect(res).toBeEmptyArray();
});

it('does not hard fail when the ziphashes endpoint is not available', async () => {
httpMock
.scope(secondaryUrl)
.get(
'/terraform-provider-azurerm/2.56.0/terraform-provider-azurerm_2.56.0_SHA256SUMS'
)
.reply(404);

const res = await terraformProviderDatasource.getZipHashes([
{
name: 'azurerm',
version: '2.56.0',
os: 'linux',
arch: 'amd64',
filename: 'terraform-provider-azurerm_2.56.0_linux_amd64.zip',
url: 'https://releases.hashicorp.com/terraform-provider-azurerm/2.56.0/terraform-provider-azurerm_2.56.0_linux_amd64.zip',
shasums_url:
'https://releases.hashicorp.com/terraform-provider-azurerm/2.56.0/terraform-provider-azurerm_2.56.0_SHA256SUMS',
},
]);

expect(res).toBeUndefined();
});
});
});
38 changes: 38 additions & 0 deletions lib/modules/datasource/terraform-provider/index.ts
Expand Up @@ -282,6 +282,44 @@ export class TerraformProviderDatasource extends TerraformDatasource {
return filteredResult.length === result.length ? filteredResult : null;
}

@cache({
namespace: `datasource-${TerraformProviderDatasource.id}-zip-hashes`,
key: (registryURL: string, repository: string, version: string) =>
`${registryURL}/${repository}/${version}`,
})
async getZipHashes(builds: TerraformBuild[]): Promise<string[] | undefined> {
if (builds.length === 0) {
return [];
}

const zipHashUrl = builds[0].shasums_url;

if (!zipHashUrl) {
return [];
}

// The hashes are formatted as the result of sha256sum in plain text, each line: <hash>\t<filename>
let rawHashData: string;
try {
rawHashData = (await this.http.get(zipHashUrl)).body;
} catch (err) {
/* istanbul ignore next */
if (err instanceof ExternalHostError) {
throw err;
}
logger.debug(
{ err, zipHashUrl },
`Failed to retrieve zip hashes from ${zipHashUrl}`
);
return undefined;
}

return rawHashData
.trimEnd()
.split('\n')
.map((line) => line.split(/\s/)[0]);
}

@cache({
namespace: `datasource-${TerraformProviderDatasource.id}-releaseBackendIndex`,
key: (backendLookUpName: string, version: string) =>
Expand Down
2 changes: 2 additions & 0 deletions lib/modules/datasource/terraform-provider/types.ts
Expand Up @@ -11,6 +11,7 @@ export interface TerraformBuild {
arch: string;
filename: string;
url: string;
shasums_url?: string;
}

export interface TerraformProvider {
Expand Down Expand Up @@ -57,4 +58,5 @@ export interface TerraformRegistryBuildResponse {
arch: string;
filename: string;
download_url: string;
shasums_url?: string;
}
@@ -0,0 +1,3 @@
1d47d00730fab764bddb6d548fed7e124739b0bcebb9f3b3c6aa247de55fb804 terraform-provider-google_4.84.0_linux_amd64.zip
29bff92b4375a35a7729248b3bc5db8991ca1b9ba640fc25b13700e12f99c195 terraform-provider-google_4.84.0_darwin_amd64.zip
f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c terraform-provider-google_4.84.0_manifest.json
@@ -0,0 +1,39 @@
{
"id": "hashicorp/azurerm",
"versions": [
{
"version": "2.56.0",
"protocols": [
"5.0"
],
"platforms": [
{
"os": "linux",
"arch": "amd64"
},
{
"os": "darwin",
"arch": "amd64"
}
]
},
{
"version": "1.33.0",
"protocols": [
"4.0",
"5.0"
],
"platforms": [
{
"os": "linux",
"arch": "amd64"
},
{
"os": "darwin",
"arch": "amd64"
}
]
}
],
"warnings": null
}
@@ -0,0 +1,39 @@
{
"id": "hashicorp/google",
"versions": [
{
"version": "4.84.0",
"protocols": [
"5.0"
],
"platforms": [
{
"os": "linux",
"arch": "amd64"
},
{
"os": "darwin",
"arch": "amd64"
}
]
},
{
"version": "1.33.0",
"protocols": [
"4.0",
"5.0"
],
"platforms": [
{
"os": "linux",
"arch": "amd64"
},
{
"os": "darwin",
"arch": "amd64"
}
]
}
],
"warnings": null
}

0 comments on commit 16be3cf

Please sign in to comment.