@ibm-cloud/cd-tools 1.2.2 → 1.2.3
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/cmd/check-secrets.js
CHANGED
|
@@ -49,11 +49,15 @@ async function main(options) {
|
|
|
49
49
|
for (let i = 0; i < getToolsRes.tools.length; i++) {
|
|
50
50
|
const tool = getToolsRes.tools[i];
|
|
51
51
|
|
|
52
|
+
// Skip iff it's GitHub/GitLab/GRIT integration with OAuth
|
|
53
|
+
if (['githubconsolidated', 'github_integrated', 'gitlab', 'hostedgit'].includes(tool.tool_type_id) && (tool.parameters?.auth_type === '' || tool.parameters?.auth_type === 'oauth'))
|
|
54
|
+
continue;
|
|
55
|
+
|
|
52
56
|
// Check tool integrations for any plain text secret values
|
|
53
57
|
if (SECRET_KEYS_MAP[tool.tool_type_id]) {
|
|
54
58
|
SECRET_KEYS_MAP[tool.tool_type_id].forEach((entry) => {
|
|
55
59
|
const updateableSecretParam = entry.key;
|
|
56
|
-
if (tool.parameters[updateableSecretParam] && !isSecretReference(tool.parameters[updateableSecretParam])) {
|
|
60
|
+
if (tool.parameters[updateableSecretParam] && !isSecretReference(tool.parameters[updateableSecretParam]) && tool.parameters[updateableSecretParam].length > 0) {
|
|
57
61
|
toolResults.push({
|
|
58
62
|
'Tool ID': tool.id,
|
|
59
63
|
'Tool Type': tool.tool_type_id,
|
|
@@ -68,7 +72,7 @@ async function main(options) {
|
|
|
68
72
|
const pipelineData = await getPipelineData(token, tool.id, region);
|
|
69
73
|
|
|
70
74
|
pipelineData?.properties.forEach((prop) => {
|
|
71
|
-
if (prop.type === 'secure' && !isSecretReference(prop.value)) {
|
|
75
|
+
if (prop.type === 'secure' && !isSecretReference(prop.value) && prop.value.length > 0) {
|
|
72
76
|
pipelineResults.push({
|
|
73
77
|
'Pipeline ID': pipelineData.id,
|
|
74
78
|
'Trigger Name': '-',
|
|
@@ -79,7 +83,7 @@ async function main(options) {
|
|
|
79
83
|
|
|
80
84
|
pipelineData?.triggers.forEach((trigger) => {
|
|
81
85
|
trigger.properties?.forEach((prop) => {
|
|
82
|
-
if (prop.type === 'secure' && !isSecretReference(prop.value)) {
|
|
86
|
+
if (prop.type === 'secure' && !isSecretReference(prop.value) && prop.value.length > 0) {
|
|
83
87
|
pipelineResults.push({
|
|
84
88
|
'Pipeline ID': pipelineData.id,
|
|
85
89
|
'Trigger Name': trigger.name,
|
package/cmd/copy-toolchain.js
CHANGED
|
@@ -106,7 +106,7 @@ async function main(options) {
|
|
|
106
106
|
|
|
107
107
|
// check for existing .tf files in output directory
|
|
108
108
|
if (fs.existsSync(outputDir)) {
|
|
109
|
-
let files = readdirSync(outputDir, { recursive: true });
|
|
109
|
+
let files = fs.readdirSync(outputDir, { recursive: true });
|
|
110
110
|
files = files.filter((f) => f.endsWith('.tf'));
|
|
111
111
|
if (files.length > 0) throw Error(`Output directory already has ${files.length} '.tf' files, please specify a different output directory`);
|
|
112
112
|
}
|
|
@@ -249,7 +249,8 @@ async function main(options) {
|
|
|
249
249
|
LOG_STAGES.import
|
|
250
250
|
);
|
|
251
251
|
|
|
252
|
-
if (nonSecretRefs.length > 0) logger.warn(`\nWarning! The following generated terraform resource contains
|
|
252
|
+
if (nonSecretRefs.length > 0) logger.warn(`\nWarning! The following generated terraform resource contains hashed secret(s) that cannot be migrated, applying without changes may result in error(s):`);
|
|
253
|
+
logger.table(nonSecretRefs);
|
|
253
254
|
|
|
254
255
|
} catch (err) {
|
|
255
256
|
if (err.message && err.stack) {
|
|
@@ -70,8 +70,15 @@ export async function importTerraform(token, apiKey, region, toolchainId, toolch
|
|
|
70
70
|
if (isSecretReference(tool.parameters[key])) {
|
|
71
71
|
additionalProps[block.name].push({ param: tfKey, value: tool.parameters[key] });
|
|
72
72
|
} else {
|
|
73
|
-
|
|
74
|
-
if (required)
|
|
73
|
+
const newFileName = SUPPORTED_TOOLS_MAP[tool.tool_type_id].split('ibm_')[1];
|
|
74
|
+
if (required) {
|
|
75
|
+
nonSecretRefs.push({
|
|
76
|
+
resource_name: block.name,
|
|
77
|
+
property_name: tfKey,
|
|
78
|
+
file_name: isCompact ? 'resources.tf' : `${newFileName}.tf`
|
|
79
|
+
});
|
|
80
|
+
additionalProps[block.name].push({ param: tfKey, value: `<${tfKey}>` });
|
|
81
|
+
}
|
|
75
82
|
}
|
|
76
83
|
});
|
|
77
84
|
}
|
package/cmd/utils/validate.js
CHANGED
|
@@ -11,7 +11,7 @@ import { execSync } from 'child_process';
|
|
|
11
11
|
import { logger, LOG_STAGES } from './logger.js'
|
|
12
12
|
import { RESERVED_GRIT_PROJECT_NAMES, RESERVED_GRIT_GROUP_NAMES, RESERVED_GRIT_SUBGROUP_NAME, TERRAFORM_REQUIRED_VERSION, SECRET_KEYS_MAP } from '../../config.js';
|
|
13
13
|
import { getToolchainsByName, getToolchainTools, getPipelineData, getAppConfigHealthcheck, getSecretsHealthcheck, getGitOAuth, getGritUserProject, getGritGroup, getGritGroupProject } from './requests.js';
|
|
14
|
-
import { promptUserConfirmation, promptUserInput } from './utils.js';
|
|
14
|
+
import { promptUserConfirmation, promptUserInput, isSecretReference } from './utils.js';
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
function validatePrereqsVersions() {
|
|
@@ -146,7 +146,6 @@ async function validateTools(token, tcId, region, skipPrompt) {
|
|
|
146
146
|
const toolsWithHashedParams = [];
|
|
147
147
|
const patTools = [];
|
|
148
148
|
const classicPipelines = [];
|
|
149
|
-
const secretPattern = /^hash:SHA3-512:[a-zA-Z0-9]{128}$/;
|
|
150
149
|
|
|
151
150
|
for (const tool of allTools.tools) {
|
|
152
151
|
const toolName = (tool.name || tool.parameters?.name || tool.parameters?.label || '').replace(/\s+/g, '+');
|
|
@@ -203,7 +202,7 @@ async function validateTools(token, tcId, region, skipPrompt) {
|
|
|
203
202
|
url: toolUrl
|
|
204
203
|
});
|
|
205
204
|
}
|
|
206
|
-
else if (['githubconsolidated', 'github_integrated', 'gitlab'].includes(tool.tool_type_id) && (tool.parameters?.auth_type === '' || tool.parameters?.auth_type === 'oauth')) {
|
|
205
|
+
else if (['githubconsolidated', 'github_integrated', 'gitlab', 'hostedgit'].includes(tool.tool_type_id) && (tool.parameters?.auth_type === '' || tool.parameters?.auth_type === 'oauth')) { // Skip secret check iff it's GitHub/GitLab/GRIT integration with OAuth
|
|
207
206
|
continue;
|
|
208
207
|
}
|
|
209
208
|
else {
|
|
@@ -212,20 +211,23 @@ async function validateTools(token, tcId, region, skipPrompt) {
|
|
|
212
211
|
const pipelineData = await getPipelineData(token, tool.id, region);
|
|
213
212
|
|
|
214
213
|
pipelineData.properties.forEach((prop) => {
|
|
215
|
-
if (prop.type === 'secure' &&
|
|
214
|
+
if (prop.type === 'secure' && !isSecretReference(prop.value) && prop.value.length > 0)
|
|
215
|
+
secrets.push(['properties', prop.name].join('.').replace(/\s+/g, '+'));
|
|
216
216
|
});
|
|
217
217
|
|
|
218
218
|
pipelineData.triggers.forEach((trigger) => {
|
|
219
|
-
if ((trigger?.secret?.type === 'token_matches' || trigger?.secret?.type === 'digest_matches') &&
|
|
219
|
+
if ((trigger?.secret?.type === 'token_matches' || trigger?.secret?.type === 'digest_matches') && !isSecretReference(trigger.secret.value) && trigger.secret.value.length > 0)
|
|
220
|
+
secrets.push([trigger.name, trigger.secret.key_name].join('.').replace(/\s+/g, '+'));
|
|
220
221
|
trigger.properties.forEach((prop) => {
|
|
221
|
-
if (prop.type === 'secure' &&
|
|
222
|
+
if (prop.type === 'secure' && !isSecretReference(prop.value) && prop.value.length > 0)
|
|
223
|
+
secrets.push([trigger.name, 'properties', prop.name].join('.').replace(/\s+/g, '+'));
|
|
222
224
|
});
|
|
223
225
|
});
|
|
224
226
|
}
|
|
225
227
|
else {
|
|
226
228
|
const secretsToCheck = (SECRET_KEYS_MAP[tool.tool_type_id] || []).map((entry) => entry.key); // Check for secrets in the rest of the tools
|
|
227
229
|
Object.entries(tool.parameters).forEach(([key, value]) => {
|
|
228
|
-
if (
|
|
230
|
+
if (!isSecretReference(value) && value.length > 0 && secretsToCheck.includes(key)) secrets.push(key);
|
|
229
231
|
});
|
|
230
232
|
}
|
|
231
233
|
if (secrets.length > 0) {
|
|
@@ -260,7 +262,7 @@ async function validateTools(token, tcId, region, skipPrompt) {
|
|
|
260
262
|
}
|
|
261
263
|
|
|
262
264
|
if (toolsWithHashedParams.length > 0) {
|
|
263
|
-
logger.warn('Warning! The following tools contain secrets that cannot be migrated, please use the \'check-
|
|
265
|
+
logger.warn('Warning! The following tools contain secrets that cannot be migrated, please use the \'check-secrets\' command to export the secrets: \n', LOG_STAGES.setup, true);
|
|
264
266
|
logger.table(toolsWithHashedParams);
|
|
265
267
|
}
|
|
266
268
|
|