@datadog/datadog-ci-plugin-terraform 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -0
- package/dist/api.d.ts +8 -0
- package/dist/api.js +66 -0
- package/dist/api.js.map +1 -0
- package/dist/commands/upload.d.ts +11 -0
- package/dist/commands/upload.js +170 -0
- package/dist/commands/upload.js.map +1 -0
- package/dist/interfaces.d.ts +14 -0
- package/dist/interfaces.js +3 -0
- package/dist/interfaces.js.map +1 -0
- package/dist/renderer.d.ts +8 -0
- package/dist/renderer.js +41 -0
- package/dist/renderer.js.map +1 -0
- package/dist/utils.d.ts +11 -0
- package/dist/utils.js +54 -0
- package/dist/utils.js.map +1 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Terraform command
|
|
2
|
+
|
|
3
|
+
This command lets you upload Terraform runtime artifacts (plan and state JSON files) to the Datadog CI intake endpoint for enhanced cloud-to-code mapping and policy evaluation.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
datadog-ci terraform upload [plan|state] <path/to/terraform-file.json> [additional-files...]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Arguments
|
|
12
|
+
|
|
13
|
+
- `plan` or `state`: The type of Terraform artifact being uploaded
|
|
14
|
+
- `<path>`: Path to one or more Terraform JSON files (space-separated)
|
|
15
|
+
|
|
16
|
+
### Optional arguments
|
|
17
|
+
|
|
18
|
+
- `--repo-id` (optional): Repository identifier override (e.g., github.com/datadog/my-repo)
|
|
19
|
+
- `--dry-run` (default: `false`): Run the command without uploading any data to Datadog
|
|
20
|
+
- `--verbose` (default: `false`): Enable verbose logging
|
|
21
|
+
- `--skip-git-metadata-upload` (default: `false`): Skip the upload of git metadata
|
|
22
|
+
|
|
23
|
+
### Environment variables
|
|
24
|
+
|
|
25
|
+
The following environment variables are required:
|
|
26
|
+
|
|
27
|
+
- `DD_API_KEY`: the API key to use
|
|
28
|
+
|
|
29
|
+
Optional environment variables:
|
|
30
|
+
|
|
31
|
+
- `DD_SITE`: the [Datadog site](https://docs.datadoghq.com/getting_started/site/#access-the-datadog-site) (default: `datadoghq.com`)
|
|
32
|
+
- `DD_GIT_REPOSITORY_URL`: Override for repository URL
|
|
33
|
+
- `DD_REPOSITORY_URL`: Alternative override for repository URL
|
|
34
|
+
|
|
35
|
+
### Examples
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Upload a single Terraform plan file
|
|
39
|
+
datadog-ci terraform upload plan ./terraform-plan.json
|
|
40
|
+
|
|
41
|
+
# Upload multiple Terraform plan files
|
|
42
|
+
datadog-ci terraform upload plan ./plan1.json ./plan2.json ./plan3.json
|
|
43
|
+
|
|
44
|
+
# Upload multiple plan files using glob expansion
|
|
45
|
+
datadog-ci terraform upload plan ./plans/*.json
|
|
46
|
+
|
|
47
|
+
# Upload a Terraform state file
|
|
48
|
+
datadog-ci terraform upload state ./terraform.tfstate
|
|
49
|
+
|
|
50
|
+
# Upload with manual repo-id override
|
|
51
|
+
datadog-ci terraform upload plan ./terraform-plan.json --repo-id "github.com/my-org/my-repo"
|
|
52
|
+
|
|
53
|
+
# Dry run mode
|
|
54
|
+
datadog-ci terraform upload plan ./terraform-plan.json --dry-run
|
|
55
|
+
|
|
56
|
+
# Upload multiple files with verbose logging
|
|
57
|
+
datadog-ci terraform upload plan ./plan1.json ./plan2.json --verbose
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Git context resolution
|
|
61
|
+
|
|
62
|
+
The Git context is resolved in the following order of priority:
|
|
63
|
+
|
|
64
|
+
1. CI environment variables
|
|
65
|
+
2. Current Git repository metadata
|
|
66
|
+
3. Override environment variables (`DD_GIT_*` variables)
|
|
67
|
+
|
|
68
|
+
The repository identifier (`repo_id`) is resolved in this order:
|
|
69
|
+
|
|
70
|
+
1. `--repo-id` flag value
|
|
71
|
+
2. `DD_GIT_REPOSITORY_URL` or `DD_REPOSITORY_URL` environment variable
|
|
72
|
+
3. Git metadata from the current repository
|
|
73
|
+
|
|
74
|
+
## Development
|
|
75
|
+
|
|
76
|
+
To test locally, run:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
yarn launch terraform upload plan /path/to/terraform-plan.json
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Notes
|
|
83
|
+
|
|
84
|
+
- The command accepts one or more files per invocation. All files must be of the same artifact type (plan or state).
|
|
85
|
+
- Files are automatically gzipped before upload.
|
|
86
|
+
- The command computes a SHA256 hash of each file's content.
|
|
87
|
+
- No client-side validation or filtering of file content is performed (as per RFC requirements).
|
|
88
|
+
- Git metadata is synced only once per invocation, even when uploading multiple files.
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AxiosPromise, AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
2
|
+
import { TerraformArtifactPayload } from './interfaces';
|
|
3
|
+
export declare const intakeUrl: string;
|
|
4
|
+
export declare const apiUrl: string;
|
|
5
|
+
export declare const uploadTerraformArtifact: (request: (args: AxiosRequestConfig) => AxiosPromise<AxiosResponse>) => (payload: TerraformArtifactPayload) => Promise<AxiosResponse<AxiosResponse<any, any, {}>, any, {}>>;
|
|
6
|
+
export declare const apiConstructor: (baseIntakeUrl: string, apiKey: string) => {
|
|
7
|
+
uploadTerraformArtifact: (payload: TerraformArtifactPayload) => Promise<AxiosResponse<AxiosResponse<any, any, {}>, any, {}>>;
|
|
8
|
+
};
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.apiConstructor = exports.uploadTerraformArtifact = exports.apiUrl = exports.intakeUrl = void 0;
|
|
16
|
+
const zlib_1 = require("zlib");
|
|
17
|
+
const api_1 = require("@datadog/datadog-ci-base/helpers/api");
|
|
18
|
+
const utils_1 = require("@datadog/datadog-ci-base/helpers/utils");
|
|
19
|
+
const form_data_1 = __importDefault(require("form-data"));
|
|
20
|
+
const maxBodyLength = Infinity;
|
|
21
|
+
exports.intakeUrl = (0, api_1.getIntakeUrl)('ci-intake');
|
|
22
|
+
exports.apiUrl = (0, api_1.getApiUrl)();
|
|
23
|
+
const uploadTerraformArtifact = (request) => (payload) => __awaiter(void 0, void 0, void 0, function* () {
|
|
24
|
+
const form = new form_data_1.default();
|
|
25
|
+
// Build event envelope according to RFC spec
|
|
26
|
+
const event = Object.assign({ type: 'terraform_artifact', track_type: 'ciiac', schema_version: '1.0', artifact_type: payload.artifactType, artifact_format: 'terraform-json', artifact_sha256: payload.artifactSha256, artifact_size_bytes: payload.artifactSizeBytes }, payload.spanTags);
|
|
27
|
+
// Add repo_id if available
|
|
28
|
+
if (payload.repoId) {
|
|
29
|
+
event.repo_id = payload.repoId;
|
|
30
|
+
}
|
|
31
|
+
// Append event JSON
|
|
32
|
+
form.append('event', JSON.stringify(event), { filename: 'event.json' });
|
|
33
|
+
// Append gzipped file content
|
|
34
|
+
const gzippedContent = yield gzipContent(payload.fileContent);
|
|
35
|
+
form.append('iac_file', gzippedContent, {
|
|
36
|
+
filename: `${payload.artifactType}.json.gz`,
|
|
37
|
+
contentType: 'application/gzip',
|
|
38
|
+
});
|
|
39
|
+
return request({
|
|
40
|
+
data: form,
|
|
41
|
+
headers: form.getHeaders(),
|
|
42
|
+
maxBodyLength,
|
|
43
|
+
method: 'POST',
|
|
44
|
+
url: 'api/v2/ciiac',
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
exports.uploadTerraformArtifact = uploadTerraformArtifact;
|
|
48
|
+
const gzipContent = (content) => {
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
const chunks = [];
|
|
51
|
+
const gzip = (0, zlib_1.createGzip)();
|
|
52
|
+
gzip.on('data', (chunk) => chunks.push(chunk));
|
|
53
|
+
gzip.on('end', () => resolve(Buffer.concat(chunks)));
|
|
54
|
+
gzip.on('error', reject);
|
|
55
|
+
gzip.write(content);
|
|
56
|
+
gzip.end();
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
const apiConstructor = (baseIntakeUrl, apiKey) => {
|
|
60
|
+
const requestIntake = (0, utils_1.getRequestBuilder)({ baseUrl: baseIntakeUrl, apiKey });
|
|
61
|
+
return {
|
|
62
|
+
uploadTerraformArtifact: (0, exports.uploadTerraformArtifact)(requestIntake),
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
exports.apiConstructor = apiConstructor;
|
|
66
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,+BAA+B;AAI/B,8DAA4E;AAC5E,kEAAwE;AACxE,0DAAgC;AAIhC,MAAM,aAAa,GAAG,QAAQ,CAAA;AAEjB,QAAA,SAAS,GAAG,IAAA,kBAAY,EAAC,WAAW,CAAC,CAAA;AACrC,QAAA,MAAM,GAAG,IAAA,eAAS,GAAE,CAAA;AAE1B,MAAM,uBAAuB,GAClC,CAAC,OAAkE,EAAE,EAAE,CAAC,CAAO,OAAiC,EAAE,EAAE;IAClH,MAAM,IAAI,GAAG,IAAI,mBAAQ,EAAE,CAAA;IAE3B,6CAA6C;IAC7C,MAAM,KAAK,mBACT,IAAI,EAAE,oBAAoB,EAC1B,UAAU,EAAE,OAAO,EACnB,cAAc,EAAE,KAAK,EACrB,aAAa,EAAE,OAAO,CAAC,YAAY,EACnC,eAAe,EAAE,gBAAgB,EACjC,eAAe,EAAE,OAAO,CAAC,cAAc,EACvC,mBAAmB,EAAE,OAAO,CAAC,iBAAiB,IAC3C,OAAO,CAAC,QAAQ,CACpB,CAAA;IAED,2BAA2B;IAC3B,IAAI,OAAO,CAAC,MAAM,EAAE;QAClB,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAA;KAC/B;IAED,oBAAoB;IACpB,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAC,QAAQ,EAAE,YAAY,EAAC,CAAC,CAAA;IAErE,8BAA8B;IAC9B,MAAM,cAAc,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;IAC7D,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,cAAc,EAAE;QACtC,QAAQ,EAAE,GAAG,OAAO,CAAC,YAAY,UAAU;QAC3C,WAAW,EAAE,kBAAkB;KAChC,CAAC,CAAA;IAEF,OAAO,OAAO,CAAC;QACb,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE;QAC1B,aAAa;QACb,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,cAAc;KACpB,CAAC,CAAA;AACJ,CAAC,CAAA,CAAA;AAtCU,QAAA,uBAAuB,2BAsCjC;AAEH,MAAM,WAAW,GAAG,CAAC,OAAe,EAAmB,EAAE;IACvD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAa,EAAE,CAAA;QAC3B,MAAM,IAAI,GAAG,IAAA,iBAAU,GAAE,CAAA;QAEzB,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QAC9C,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QACpD,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;QAExB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACnB,IAAI,CAAC,GAAG,EAAE,CAAA;IACZ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAEM,MAAM,cAAc,GAAG,CAAC,aAAqB,EAAE,MAAc,EAAE,EAAE;IACtE,MAAM,aAAa,GAAG,IAAA,yBAAiB,EAAC,EAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAC,CAAC,CAAA;IAEzE,OAAO;QACL,uBAAuB,EAAE,IAAA,+BAAuB,EAAC,aAAa,CAAC;KAChE,CAAA;AACH,CAAC,CAAA;AANY,QAAA,cAAc,kBAM1B"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { TerraformUploadCommand } from '@datadog/datadog-ci-base/commands/terraform/upload';
|
|
2
|
+
export declare class PluginCommand extends TerraformUploadCommand {
|
|
3
|
+
private config;
|
|
4
|
+
private logger;
|
|
5
|
+
private git;
|
|
6
|
+
execute(): Promise<1 | 0>;
|
|
7
|
+
private syncGitMetadata;
|
|
8
|
+
private uploadToGitDB;
|
|
9
|
+
private uploadTerraformArtifact;
|
|
10
|
+
private getSpanTags;
|
|
11
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.PluginCommand = void 0;
|
|
16
|
+
const fs_1 = __importDefault(require("fs"));
|
|
17
|
+
const git_1 = require("@datadog/datadog-ci-base/commands/git-metadata/git");
|
|
18
|
+
const gitdb_1 = require("@datadog/datadog-ci-base/commands/git-metadata/gitdb");
|
|
19
|
+
const library_1 = require("@datadog/datadog-ci-base/commands/git-metadata/library");
|
|
20
|
+
const upload_1 = require("@datadog/datadog-ci-base/commands/terraform/upload");
|
|
21
|
+
const constants_1 = require("@datadog/datadog-ci-base/constants");
|
|
22
|
+
const ci_1 = require("@datadog/datadog-ci-base/helpers/ci");
|
|
23
|
+
const env_1 = require("@datadog/datadog-ci-base/helpers/env");
|
|
24
|
+
const fips_1 = require("@datadog/datadog-ci-base/helpers/fips");
|
|
25
|
+
const format_git_span_data_1 = require("@datadog/datadog-ci-base/helpers/git/format-git-span-data");
|
|
26
|
+
const id_1 = __importDefault(require("@datadog/datadog-ci-base/helpers/id"));
|
|
27
|
+
const logger_1 = require("@datadog/datadog-ci-base/helpers/logger");
|
|
28
|
+
const retry_1 = require("@datadog/datadog-ci-base/helpers/retry");
|
|
29
|
+
const user_provided_git_1 = require("@datadog/datadog-ci-base/helpers/user-provided-git");
|
|
30
|
+
const utils_1 = require("@datadog/datadog-ci-base/helpers/utils");
|
|
31
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
32
|
+
const api_1 = require("../api");
|
|
33
|
+
const renderer_1 = require("../renderer");
|
|
34
|
+
const utils_2 = require("../utils");
|
|
35
|
+
class PluginCommand extends upload_1.TerraformUploadCommand {
|
|
36
|
+
constructor() {
|
|
37
|
+
var _a, _b;
|
|
38
|
+
super(...arguments);
|
|
39
|
+
this.config = {
|
|
40
|
+
apiKey: process.env.DATADOG_API_KEY || process.env.DD_API_KEY,
|
|
41
|
+
fips: (_a = (0, env_1.toBoolean)(process.env[constants_1.FIPS_ENV_VAR])) !== null && _a !== void 0 ? _a : false,
|
|
42
|
+
fipsIgnoreError: (_b = (0, env_1.toBoolean)(process.env[constants_1.FIPS_IGNORE_ERROR_ENV_VAR])) !== null && _b !== void 0 ? _b : false,
|
|
43
|
+
};
|
|
44
|
+
this.logger = new logger_1.Logger((s) => this.context.stdout.write(s), logger_1.LogLevel.INFO);
|
|
45
|
+
this.git = undefined;
|
|
46
|
+
}
|
|
47
|
+
execute() {
|
|
48
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
+
(0, fips_1.enableFips)(this.fips || this.config.fips, this.fipsIgnoreError || this.config.fipsIgnoreError);
|
|
50
|
+
this.logger.setLogLevel(this.verbose ? logger_1.LogLevel.DEBUG : logger_1.LogLevel.INFO);
|
|
51
|
+
this.logger.setShouldIncludeTime(this.verbose);
|
|
52
|
+
// Validate API key
|
|
53
|
+
if (!this.config.apiKey) {
|
|
54
|
+
this.logger.error(`Neither ${chalk_1.default.red.bold('DATADOG_API_KEY')} nor ${chalk_1.default.red.bold('DD_API_KEY')} is in your environment.`);
|
|
55
|
+
return 1;
|
|
56
|
+
}
|
|
57
|
+
// Initialize git if in a repository
|
|
58
|
+
const isGitRepository = yield (0, library_1.isGitRepo)();
|
|
59
|
+
if (isGitRepository) {
|
|
60
|
+
this.git = yield (0, git_1.newSimpleGit)();
|
|
61
|
+
}
|
|
62
|
+
// Sync git metadata if needed (only once for all files)
|
|
63
|
+
if (!this.skipGitMetadataUpload && isGitRepository) {
|
|
64
|
+
yield this.syncGitMetadata();
|
|
65
|
+
}
|
|
66
|
+
// Upload terraform artifacts
|
|
67
|
+
let hasFailures = false;
|
|
68
|
+
for (const filePath of this.filePaths) {
|
|
69
|
+
const exitCode = yield this.uploadTerraformArtifact(filePath);
|
|
70
|
+
if (exitCode !== 0) {
|
|
71
|
+
hasFailures = true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return hasFailures ? 1 : 0;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
syncGitMetadata() {
|
|
78
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
const traceId = (0, id_1.default)();
|
|
80
|
+
const requestBuilder = (0, utils_1.getRequestBuilder)({
|
|
81
|
+
baseUrl: api_1.apiUrl,
|
|
82
|
+
apiKey: this.config.apiKey,
|
|
83
|
+
headers: new Map([
|
|
84
|
+
['x-datadog-trace-id', traceId],
|
|
85
|
+
['x-datadog-parent-id', traceId],
|
|
86
|
+
]),
|
|
87
|
+
});
|
|
88
|
+
try {
|
|
89
|
+
this.logger.info(`${this.dryRun ? '[DRYRUN] ' : ''}Syncing git metadata...`);
|
|
90
|
+
let elapsed = 0;
|
|
91
|
+
if (!this.dryRun) {
|
|
92
|
+
elapsed = yield (0, utils_1.timedExecAsync)(this.uploadToGitDB.bind(this), { requestBuilder });
|
|
93
|
+
}
|
|
94
|
+
this.logger.info((0, renderer_1.renderSuccessfulGitDBSync)(this.dryRun, elapsed));
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
this.logger.info((0, renderer_1.renderFailedGitDBSync)(err));
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
uploadToGitDB(opts) {
|
|
102
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
103
|
+
if (!this.git) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
yield (0, gitdb_1.uploadToGitDB)(this.logger, opts.requestBuilder, this.git, this.dryRun);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
uploadTerraformArtifact(filePath) {
|
|
110
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
this.logger.info((0, renderer_1.renderCommandInfo)(this.artifactType, filePath, this.dryRun));
|
|
112
|
+
// Validate file exists and is readable
|
|
113
|
+
if (!(0, utils_2.validateFilePath)(filePath)) {
|
|
114
|
+
this.context.stderr.write((0, renderer_1.renderInvalidFile)(filePath, 'File not found or not readable'));
|
|
115
|
+
return 1;
|
|
116
|
+
}
|
|
117
|
+
// Read and validate JSON structure
|
|
118
|
+
const fileContent = fs_1.default.readFileSync(filePath, 'utf8');
|
|
119
|
+
if (!(0, utils_2.validateJsonStructure)(fileContent)) {
|
|
120
|
+
this.context.stderr.write((0, renderer_1.renderInvalidFile)(filePath, 'Invalid JSON structure'));
|
|
121
|
+
return 1;
|
|
122
|
+
}
|
|
123
|
+
// Compute file hash and size
|
|
124
|
+
const artifactSha256 = (0, utils_2.computeFileHash)(fileContent);
|
|
125
|
+
const artifactSizeBytes = Buffer.byteLength(fileContent, 'utf8');
|
|
126
|
+
const spanTags = yield this.getSpanTags();
|
|
127
|
+
const api = (0, api_1.apiConstructor)(api_1.intakeUrl, this.config.apiKey);
|
|
128
|
+
// Build payload
|
|
129
|
+
const payload = {
|
|
130
|
+
artifactType: this.artifactType,
|
|
131
|
+
filePath,
|
|
132
|
+
fileContent,
|
|
133
|
+
artifactSha256,
|
|
134
|
+
artifactSizeBytes,
|
|
135
|
+
spanTags,
|
|
136
|
+
repoId: (0, utils_2.resolveRepoId)(this.repoId, spanTags),
|
|
137
|
+
};
|
|
138
|
+
try {
|
|
139
|
+
// Upload
|
|
140
|
+
if (this.dryRun) {
|
|
141
|
+
this.logger.info((0, renderer_1.renderDryRunUpload)(payload));
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
yield (0, retry_1.retryRequest)(() => api.uploadTerraformArtifact(payload), {
|
|
145
|
+
onRetry: (e, attempt) => {
|
|
146
|
+
this.logger.warn(`Retry attempt ${attempt} for ${filePath}: ${e.message}`);
|
|
147
|
+
},
|
|
148
|
+
retries: 5,
|
|
149
|
+
});
|
|
150
|
+
this.logger.info((0, renderer_1.renderSuccessfulUpload)(filePath));
|
|
151
|
+
}
|
|
152
|
+
return 0;
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
this.context.stderr.write((0, renderer_1.renderFailedUpload)(filePath, error));
|
|
156
|
+
return 1;
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
getSpanTags() {
|
|
161
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
162
|
+
const ciSpanTags = (0, ci_1.getCISpanTags)();
|
|
163
|
+
const gitSpanTags = yield (0, format_git_span_data_1.getGitMetadata)();
|
|
164
|
+
const userGitSpanTags = (0, user_provided_git_1.getUserGitSpanTags)();
|
|
165
|
+
return Object.assign(Object.assign(Object.assign({}, gitSpanTags), ciSpanTags), userGitSpanTags);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
exports.PluginCommand = PluginCommand;
|
|
170
|
+
//# sourceMappingURL=upload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,4CAAmB;AAEnB,4EAA+E;AAC/E,gFAAkF;AAClF,oFAAgF;AAChF,+EAAyF;AACzF,kEAA0F;AAC1F,4DAAiE;AACjE,8DAA8D;AAC9D,gEAAgE;AAChE,oGAAwF;AACxF,6EAAoD;AAEpD,oEAAwE;AACxE,kEAAmE;AACnE,0FAAqF;AACrF,kEAAwF;AACxF,kDAAyB;AAGzB,gCAAwD;AAExD,0CAQoB;AACpB,oCAAgG;AAEhG,MAAa,aAAc,SAAQ,+BAAsB;IAAzD;;;QACU,WAAM,GAAG;YACf,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU;YAC7D,IAAI,EAAE,MAAA,IAAA,eAAS,EAAC,OAAO,CAAC,GAAG,CAAC,wBAAY,CAAC,CAAC,mCAAI,KAAK;YACnD,eAAe,EAAE,MAAA,IAAA,eAAS,EAAC,OAAO,CAAC,GAAG,CAAC,qCAAyB,CAAC,CAAC,mCAAI,KAAK;SAC5E,CAAA;QAEO,WAAM,GAAW,IAAI,eAAM,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,iBAAQ,CAAC,IAAI,CAAC,CAAA;QAEvF,QAAG,GAAoC,SAAS,CAAA;IA4I1D,CAAC;IA1Ic,OAAO;;YAClB,IAAA,iBAAU,EAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAA;YAE9F,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,iBAAQ,CAAC,IAAI,CAAC,CAAA;YACtE,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAE9C,mBAAmB;YACnB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;gBACvB,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,WAAW,eAAK,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,eAAK,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,0BAA0B,CAC3G,CAAA;gBAED,OAAO,CAAC,CAAA;aACT;YAED,oCAAoC;YACpC,MAAM,eAAe,GAAG,MAAM,IAAA,mBAAS,GAAE,CAAA;YACzC,IAAI,eAAe,EAAE;gBACnB,IAAI,CAAC,GAAG,GAAG,MAAM,IAAA,kBAAY,GAAE,CAAA;aAChC;YAED,wDAAwD;YACxD,IAAI,CAAC,IAAI,CAAC,qBAAqB,IAAI,eAAe,EAAE;gBAClD,MAAM,IAAI,CAAC,eAAe,EAAE,CAAA;aAC7B;YAED,6BAA6B;YAC7B,IAAI,WAAW,GAAG,KAAK,CAAA;YACvB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE;gBACrC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAA;gBAC7D,IAAI,QAAQ,KAAK,CAAC,EAAE;oBAClB,WAAW,GAAG,IAAI,CAAA;iBACnB;aACF;YAED,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC5B,CAAC;KAAA;IAEa,eAAe;;YAC3B,MAAM,OAAO,GAAG,IAAA,YAAE,GAAE,CAAA;YACpB,MAAM,cAAc,GAAG,IAAA,yBAAiB,EAAC;gBACvC,OAAO,EAAE,YAAM;gBACf,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAO;gBAC3B,OAAO,EAAE,IAAI,GAAG,CAAC;oBACf,CAAC,oBAAoB,EAAE,OAAO,CAAC;oBAC/B,CAAC,qBAAqB,EAAE,OAAO,CAAC;iBACjC,CAAC;aACH,CAAC,CAAA;YAEF,IAAI;gBACF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,yBAAyB,CAAC,CAAA;gBAC5E,IAAI,OAAO,GAAG,CAAC,CAAA;gBACf,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;oBAChB,OAAO,GAAG,MAAM,IAAA,sBAAc,EAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAC,cAAc,EAAC,CAAC,CAAA;iBAChF;gBACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAA,oCAAyB,EAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;aAClE;YAAC,OAAO,GAAG,EAAE;gBACZ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAA,gCAAqB,EAAC,GAAG,CAAC,CAAC,CAAA;aAC7C;QACH,CAAC;KAAA;IAEa,aAAa,CAAC,IAA2B;;YACrD,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;gBACb,OAAM;aACP;YAED,MAAM,IAAA,qBAAa,EAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAC9E,CAAC;KAAA;IAEa,uBAAuB,CAAC,QAAgB;;YACpD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAA,4BAAiB,EAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;YAE7E,uCAAuC;YACvC,IAAI,CAAC,IAAA,wBAAgB,EAAC,QAAQ,CAAC,EAAE;gBAC/B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAA,4BAAiB,EAAC,QAAQ,EAAE,gCAAgC,CAAC,CAAC,CAAA;gBAExF,OAAO,CAAC,CAAA;aACT;YAED,mCAAmC;YACnC,MAAM,WAAW,GAAG,YAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;YACrD,IAAI,CAAC,IAAA,6BAAqB,EAAC,WAAW,CAAC,EAAE;gBACvC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAA,4BAAiB,EAAC,QAAQ,EAAE,wBAAwB,CAAC,CAAC,CAAA;gBAEhF,OAAO,CAAC,CAAA;aACT;YAED,6BAA6B;YAC7B,MAAM,cAAc,GAAG,IAAA,uBAAe,EAAC,WAAW,CAAC,CAAA;YACnD,MAAM,iBAAiB,GAAG,MAAM,CAAC,UAAU,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;YAEhE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAA;YACzC,MAAM,GAAG,GAAG,IAAA,oBAAc,EAAC,eAAS,EAAE,IAAI,CAAC,MAAM,CAAC,MAAO,CAAC,CAAA;YAE1D,gBAAgB;YAChB,MAAM,OAAO,GAA6B;gBACxC,YAAY,EAAE,IAAI,CAAC,YAAY;gBAC/B,QAAQ;gBACR,WAAW;gBACX,cAAc;gBACd,iBAAiB;gBACjB,QAAQ;gBACR,MAAM,EAAE,IAAA,qBAAa,EAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC;aAC7C,CAAA;YAED,IAAI;gBACF,SAAS;gBACT,IAAI,IAAI,CAAC,MAAM,EAAE;oBACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAA,6BAAkB,EAAC,OAAO,CAAC,CAAC,CAAA;iBAC9C;qBAAM;oBACL,MAAM,IAAA,oBAAY,EAAC,GAAG,EAAE,CAAC,GAAG,CAAC,uBAAuB,CAAC,OAAO,CAAC,EAAE;wBAC7D,OAAO,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE;4BACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,OAAO,QAAQ,QAAQ,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;wBAC5E,CAAC;wBACD,OAAO,EAAE,CAAC;qBACX,CAAC,CAAA;oBACF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAA,iCAAsB,EAAC,QAAQ,CAAC,CAAC,CAAA;iBACnD;gBAED,OAAO,CAAC,CAAA;aACT;YAAC,OAAO,KAAK,EAAE;gBACd,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAA,6BAAkB,EAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAA;gBAE9D,OAAO,CAAC,CAAA;aACT;QACH,CAAC;KAAA;IAEa,WAAW;;YACvB,MAAM,UAAU,GAAG,IAAA,kBAAa,GAAE,CAAA;YAClC,MAAM,WAAW,GAAG,MAAM,IAAA,qCAAc,GAAE,CAAA;YAC1C,MAAM,eAAe,GAAG,IAAA,sCAAkB,GAAE,CAAA;YAE5C,qDACK,WAAW,GACX,UAAU,GACV,eAAe,EACnB;QACH,CAAC;KAAA;CACF;AArJD,sCAqJC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AxiosPromise, AxiosResponse } from 'axios';
|
|
2
|
+
import { SpanTags } from '@datadog/datadog-ci-base/helpers/interfaces';
|
|
3
|
+
export interface TerraformArtifactPayload {
|
|
4
|
+
artifactType: 'plan' | 'state';
|
|
5
|
+
filePath: string;
|
|
6
|
+
fileContent: string;
|
|
7
|
+
artifactSha256: string;
|
|
8
|
+
artifactSizeBytes: number;
|
|
9
|
+
spanTags: SpanTags;
|
|
10
|
+
repoId?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface APIHelper {
|
|
13
|
+
uploadTerraformArtifact(payload: TerraformArtifactPayload): AxiosPromise<AxiosResponse>;
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { TerraformArtifactPayload } from './interfaces';
|
|
2
|
+
export declare const renderCommandInfo: (artifactType: string, filePath: string, dryRun: boolean) => string;
|
|
3
|
+
export declare const renderDryRunUpload: (payload: TerraformArtifactPayload) => string;
|
|
4
|
+
export declare const renderSuccessfulUpload: (filePath: string) => string;
|
|
5
|
+
export declare const renderFailedUpload: (filePath: string, error: any) => string;
|
|
6
|
+
export declare const renderInvalidFile: (filePath: string, reason: string) => string;
|
|
7
|
+
export declare const renderSuccessfulGitDBSync: (dryRun: boolean, elapsed: number) => string;
|
|
8
|
+
export declare const renderFailedGitDBSync: (error: any) => string;
|
package/dist/renderer.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.renderFailedGitDBSync = exports.renderSuccessfulGitDBSync = exports.renderInvalidFile = exports.renderFailedUpload = exports.renderSuccessfulUpload = exports.renderDryRunUpload = exports.renderCommandInfo = void 0;
|
|
7
|
+
const renderer_1 = require("@datadog/datadog-ci-base/helpers/renderer");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const renderCommandInfo = (artifactType, filePath, dryRun) => {
|
|
10
|
+
const prefix = dryRun ? `${renderer_1.dryRunTag} ` : '';
|
|
11
|
+
return `${prefix}Uploading Terraform ${artifactType} file: ${filePath}\n`;
|
|
12
|
+
};
|
|
13
|
+
exports.renderCommandInfo = renderCommandInfo;
|
|
14
|
+
const renderDryRunUpload = (payload) => {
|
|
15
|
+
return `${renderer_1.dryRunTag} Would upload: ${payload.filePath}\n`;
|
|
16
|
+
};
|
|
17
|
+
exports.renderDryRunUpload = renderDryRunUpload;
|
|
18
|
+
const renderSuccessfulUpload = (filePath) => {
|
|
19
|
+
return `${renderer_1.successCheckmarkTag} Successfully uploaded: ${filePath}\n`;
|
|
20
|
+
};
|
|
21
|
+
exports.renderSuccessfulUpload = renderSuccessfulUpload;
|
|
22
|
+
const renderFailedUpload = (filePath, error) => {
|
|
23
|
+
const message = (error === null || error === void 0 ? void 0 : error.message) || 'Unknown error';
|
|
24
|
+
return `${renderer_1.failCrossTag} Failed to upload ${filePath}: ${message}\n`;
|
|
25
|
+
};
|
|
26
|
+
exports.renderFailedUpload = renderFailedUpload;
|
|
27
|
+
const renderInvalidFile = (filePath, reason) => {
|
|
28
|
+
return `${renderer_1.failCrossTag} Invalid file ${filePath}: ${reason}\n`;
|
|
29
|
+
};
|
|
30
|
+
exports.renderInvalidFile = renderInvalidFile;
|
|
31
|
+
const renderSuccessfulGitDBSync = (dryRun, elapsed) => {
|
|
32
|
+
const prefix = dryRun ? `${renderer_1.dryRunTag} ` : '';
|
|
33
|
+
return `${prefix}${renderer_1.successCheckmarkTag} Git metadata synced (${elapsed}ms)\n`;
|
|
34
|
+
};
|
|
35
|
+
exports.renderSuccessfulGitDBSync = renderSuccessfulGitDBSync;
|
|
36
|
+
const renderFailedGitDBSync = (error) => {
|
|
37
|
+
const message = (error === null || error === void 0 ? void 0 : error.message) || 'Unknown error';
|
|
38
|
+
return chalk_1.default.yellow(`⚠ Failed to sync git metadata: ${message}\n`);
|
|
39
|
+
};
|
|
40
|
+
exports.renderFailedGitDBSync = renderFailedGitDBSync;
|
|
41
|
+
//# sourceMappingURL=renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":";;;;;;AAAA,wEAAsG;AACtG,kDAAyB;AAIlB,MAAM,iBAAiB,GAAG,CAAC,YAAoB,EAAE,QAAgB,EAAE,MAAe,EAAU,EAAE;IACnG,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,oBAAS,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;IAE5C,OAAO,GAAG,MAAM,uBAAuB,YAAY,UAAU,QAAQ,IAAI,CAAA;AAC3E,CAAC,CAAA;AAJY,QAAA,iBAAiB,qBAI7B;AAEM,MAAM,kBAAkB,GAAG,CAAC,OAAiC,EAAU,EAAE;IAC9E,OAAO,GAAG,oBAAS,kBAAkB,OAAO,CAAC,QAAQ,IAAI,CAAA;AAC3D,CAAC,CAAA;AAFY,QAAA,kBAAkB,sBAE9B;AAEM,MAAM,sBAAsB,GAAG,CAAC,QAAgB,EAAU,EAAE;IACjE,OAAO,GAAG,8BAAmB,2BAA2B,QAAQ,IAAI,CAAA;AACtE,CAAC,CAAA;AAFY,QAAA,sBAAsB,0BAElC;AAEM,MAAM,kBAAkB,GAAG,CAAC,QAAgB,EAAE,KAAU,EAAU,EAAE;IACzE,MAAM,OAAO,GAAG,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,eAAe,CAAA;IAEjD,OAAO,GAAG,uBAAY,qBAAqB,QAAQ,KAAK,OAAO,IAAI,CAAA;AACrE,CAAC,CAAA;AAJY,QAAA,kBAAkB,sBAI9B;AAEM,MAAM,iBAAiB,GAAG,CAAC,QAAgB,EAAE,MAAc,EAAU,EAAE;IAC5E,OAAO,GAAG,uBAAY,iBAAiB,QAAQ,KAAK,MAAM,IAAI,CAAA;AAChE,CAAC,CAAA;AAFY,QAAA,iBAAiB,qBAE7B;AAEM,MAAM,yBAAyB,GAAG,CAAC,MAAe,EAAE,OAAe,EAAU,EAAE;IACpF,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,oBAAS,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;IAE5C,OAAO,GAAG,MAAM,GAAG,8BAAmB,yBAAyB,OAAO,OAAO,CAAA;AAC/E,CAAC,CAAA;AAJY,QAAA,yBAAyB,6BAIrC;AAEM,MAAM,qBAAqB,GAAG,CAAC,KAAU,EAAU,EAAE;IAC1D,MAAM,OAAO,GAAG,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,eAAe,CAAA;IAEjD,OAAO,eAAK,CAAC,MAAM,CAAC,kCAAkC,OAAO,IAAI,CAAC,CAAA;AACpE,CAAC,CAAA;AAJY,QAAA,qBAAqB,yBAIjC"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SpanTags } from '@datadog/datadog-ci-base/helpers/interfaces';
|
|
2
|
+
export declare const validateFilePath: (filePath: string) => boolean;
|
|
3
|
+
export declare const validateJsonStructure: (content: string) => boolean;
|
|
4
|
+
export declare const computeFileHash: (content: string) => string;
|
|
5
|
+
/**
|
|
6
|
+
* Resolve repo_id with the following priority:
|
|
7
|
+
* 1. Explicit flag value (--repo-id)
|
|
8
|
+
* 2. Environment variable (DD_GIT_REPOSITORY_URL or similar)
|
|
9
|
+
* 3. Git metadata extracted from spanTags
|
|
10
|
+
*/
|
|
11
|
+
export declare const resolveRepoId: (flagValue: string | undefined, spanTags: SpanTags) => string | undefined;
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resolveRepoId = exports.computeFileHash = exports.validateJsonStructure = exports.validateFilePath = void 0;
|
|
7
|
+
const crypto_1 = require("crypto");
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const tags_1 = require("@datadog/datadog-ci-base/helpers/tags");
|
|
10
|
+
const validateFilePath = (filePath) => {
|
|
11
|
+
try {
|
|
12
|
+
return fs_1.default.existsSync(filePath) && fs_1.default.statSync(filePath).isFile();
|
|
13
|
+
}
|
|
14
|
+
catch (_a) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
exports.validateFilePath = validateFilePath;
|
|
19
|
+
const validateJsonStructure = (content) => {
|
|
20
|
+
try {
|
|
21
|
+
JSON.parse(content);
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
catch (_a) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
exports.validateJsonStructure = validateJsonStructure;
|
|
29
|
+
const computeFileHash = (content) => {
|
|
30
|
+
const hash = (0, crypto_1.createHash)('sha256');
|
|
31
|
+
hash.update(content);
|
|
32
|
+
return hash.digest('hex');
|
|
33
|
+
};
|
|
34
|
+
exports.computeFileHash = computeFileHash;
|
|
35
|
+
/**
|
|
36
|
+
* Resolve repo_id with the following priority:
|
|
37
|
+
* 1. Explicit flag value (--repo-id)
|
|
38
|
+
* 2. Environment variable (DD_GIT_REPOSITORY_URL or similar)
|
|
39
|
+
* 3. Git metadata extracted from spanTags
|
|
40
|
+
*/
|
|
41
|
+
const resolveRepoId = (flagValue, spanTags) => {
|
|
42
|
+
if (flagValue) {
|
|
43
|
+
return flagValue;
|
|
44
|
+
}
|
|
45
|
+
// Try environment variables
|
|
46
|
+
const envRepoId = process.env.DD_GIT_REPOSITORY_URL || process.env.DD_REPOSITORY_URL;
|
|
47
|
+
if (envRepoId) {
|
|
48
|
+
return envRepoId;
|
|
49
|
+
}
|
|
50
|
+
// Fall back to git metadata
|
|
51
|
+
return spanTags[tags_1.GIT_REPOSITORY_URL];
|
|
52
|
+
};
|
|
53
|
+
exports.resolveRepoId = resolveRepoId;
|
|
54
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;;;;AAAA,mCAAiC;AACjC,4CAAmB;AAGnB,gEAAwE;AAEjE,MAAM,gBAAgB,GAAG,CAAC,QAAgB,EAAW,EAAE;IAC5D,IAAI;QACF,OAAO,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,YAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAA;KACjE;IAAC,WAAM;QACN,OAAO,KAAK,CAAA;KACb;AACH,CAAC,CAAA;AANY,QAAA,gBAAgB,oBAM5B;AAEM,MAAM,qBAAqB,GAAG,CAAC,OAAe,EAAW,EAAE;IAChE,IAAI;QACF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAEnB,OAAO,IAAI,CAAA;KACZ;IAAC,WAAM;QACN,OAAO,KAAK,CAAA;KACb;AACH,CAAC,CAAA;AARY,QAAA,qBAAqB,yBAQjC;AAEM,MAAM,eAAe,GAAG,CAAC,OAAe,EAAU,EAAE;IACzD,MAAM,IAAI,GAAG,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAA;IACjC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAEpB,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC3B,CAAC,CAAA;AALY,QAAA,eAAe,mBAK3B;AAED;;;;;GAKG;AACI,MAAM,aAAa,GAAG,CAAC,SAA6B,EAAE,QAAkB,EAAsB,EAAE;IACrG,IAAI,SAAS,EAAE;QACb,OAAO,SAAS,CAAA;KACjB;IAED,4BAA4B;IAC5B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAA;IACpF,IAAI,SAAS,EAAE;QACb,OAAO,SAAS,CAAA;KACjB;IAED,4BAA4B;IAC5B,OAAO,QAAQ,CAAC,yBAAkB,CAAC,CAAA;AACrC,CAAC,CAAA;AAbY,QAAA,aAAa,iBAazB"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@datadog/datadog-ci-plugin-terraform",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Datadog CI plugin for `terraform` commands",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"datadog",
|
|
8
|
+
"datadog-ci",
|
|
9
|
+
"iac",
|
|
10
|
+
"plugin",
|
|
11
|
+
"terraform"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/DataDog/datadog-ci/tree/master/packages/plugin-terraform",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/DataDog/datadog-ci.git",
|
|
17
|
+
"directory": "packages/plugin-terraform"
|
|
18
|
+
},
|
|
19
|
+
"exports": {
|
|
20
|
+
"./package.json": "./package.json",
|
|
21
|
+
"./commands/*": {
|
|
22
|
+
"development": "./src/commands/*.ts",
|
|
23
|
+
"default": "./dist/commands/*.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist/**/*",
|
|
28
|
+
"README",
|
|
29
|
+
"LICENSE"
|
|
30
|
+
],
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "yarn package:clean; yarn package:build",
|
|
36
|
+
"lint": "yarn package:lint",
|
|
37
|
+
"prepack": "yarn package:clean-dist"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"@datadog/datadog-ci-base": "5.9.0"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"axios": "^1.13.5",
|
|
44
|
+
"chalk": "3.0.0",
|
|
45
|
+
"form-data": "^4.0.4",
|
|
46
|
+
"simple-git": "3.16.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/jest": "29.5.3",
|
|
50
|
+
"upath": "^2.0.1"
|
|
51
|
+
}
|
|
52
|
+
}
|