feat(deployment): add command_hidden flag to hide command text in logs
Add support for hiding sensitive command text while preserving output logs. When command_hidden is true, the command text is set to null in the main log entry but logged separately to the deployment queue with proper redaction. - Add command_hidden parameter to execute_remote_command and executeCommandWithProcess - When enabled, separates command visibility from output visibility - Fix operator precedence in type ternary expression
This commit is contained in:
parent
fbdcf0de51
commit
333cc9589d
2 changed files with 16 additions and 11 deletions
|
|
@ -783,7 +783,7 @@ private function deploy_docker_compose_buildpack()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
[executeInDocker($this->deployment_uuid, "cd {$this->workdir} && {$start_command}"), 'hidden' => true],
|
[executeInDocker($this->deployment_uuid, "cd {$this->workdir} && {$start_command}"), 'hidden' => false, 'type' => 'stdout', 'command_hidden' => true],
|
||||||
);
|
);
|
||||||
} catch (\RuntimeException $e) {
|
} catch (\RuntimeException $e) {
|
||||||
if (str_contains($e->getMessage(), "matching `'") || str_contains($e->getMessage(), 'unexpected EOF')) {
|
if (str_contains($e->getMessage(), "matching `'") || str_contains($e->getMessage(), 'unexpected EOF')) {
|
||||||
|
|
@ -801,7 +801,7 @@ private function deploy_docker_compose_buildpack()
|
||||||
$command .= " --env-file {$server_workdir}/.env";
|
$command .= " --env-file {$server_workdir}/.env";
|
||||||
$command .= " --project-directory {$server_workdir} -f {$server_workdir}{$this->docker_compose_location} up -d";
|
$command .= " --project-directory {$server_workdir} -f {$server_workdir}{$this->docker_compose_location} up -d";
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
['command' => $command, 'hidden' => true],
|
['command' => $command, 'hidden' => false, 'type' => 'stdout', 'command_hidden' => true],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -818,11 +818,11 @@ private function deploy_docker_compose_buildpack()
|
||||||
$this->write_deployment_configurations();
|
$this->write_deployment_configurations();
|
||||||
if ($this->preserveRepository) {
|
if ($this->preserveRepository) {
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
['command' => "cd {$server_workdir} && {$start_command}", 'hidden' => true],
|
['command' => "cd {$server_workdir} && {$start_command}", 'hidden' => false, 'type' => 'stdout', 'command_hidden' => true],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
[executeInDocker($this->deployment_uuid, "cd {$this->basedir} && {$start_command}"), 'hidden' => true],
|
[executeInDocker($this->deployment_uuid, "cd {$this->basedir} && {$start_command}"), 'hidden' => false, 'type' => 'stdout', 'command_hidden' => true],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -834,14 +834,14 @@ private function deploy_docker_compose_buildpack()
|
||||||
$this->write_deployment_configurations();
|
$this->write_deployment_configurations();
|
||||||
|
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
['command' => $command, 'hidden' => true],
|
['command' => $command, 'hidden' => false, 'type' => 'stdout', 'command_hidden' => true],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// Always use .env file
|
// Always use .env file
|
||||||
$command .= " --env-file {$this->workdir}/.env";
|
$command .= " --env-file {$this->workdir}/.env";
|
||||||
$command .= " --project-name {$this->application->uuid} --project-directory {$this->workdir} -f {$this->workdir}{$this->docker_compose_location} up -d";
|
$command .= " --project-name {$this->application->uuid} --project-directory {$this->workdir} -f {$this->workdir}{$this->docker_compose_location} up -d";
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
[executeInDocker($this->deployment_uuid, $command), 'hidden' => true],
|
[executeInDocker($this->deployment_uuid, $command), 'hidden' => false, 'type' => 'stdout', 'command_hidden' => true],
|
||||||
);
|
);
|
||||||
$this->write_deployment_configurations();
|
$this->write_deployment_configurations();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ public function execute_remote_command(...$commands)
|
||||||
$customType = data_get($single_command, 'type');
|
$customType = data_get($single_command, 'type');
|
||||||
$ignore_errors = data_get($single_command, 'ignore_errors', false);
|
$ignore_errors = data_get($single_command, 'ignore_errors', false);
|
||||||
$append = data_get($single_command, 'append', true);
|
$append = data_get($single_command, 'append', true);
|
||||||
|
$command_hidden = data_get($single_command, 'command_hidden', false);
|
||||||
$this->save = data_get($single_command, 'save');
|
$this->save = data_get($single_command, 'save');
|
||||||
if ($this->server->isNonRoot()) {
|
if ($this->server->isNonRoot()) {
|
||||||
if (str($command)->startsWith('docker exec')) {
|
if (str($command)->startsWith('docker exec')) {
|
||||||
|
|
@ -102,7 +103,7 @@ public function execute_remote_command(...$commands)
|
||||||
|
|
||||||
while ($attempt < $maxRetries && ! $commandExecuted) {
|
while ($attempt < $maxRetries && ! $commandExecuted) {
|
||||||
try {
|
try {
|
||||||
$this->executeCommandWithProcess($command, $hidden, $customType, $append, $ignore_errors);
|
$this->executeCommandWithProcess($command, $hidden, $customType, $append, $ignore_errors, $command_hidden);
|
||||||
$commandExecuted = true;
|
$commandExecuted = true;
|
||||||
} catch (\RuntimeException|DeploymentException $e) {
|
} catch (\RuntimeException|DeploymentException $e) {
|
||||||
$lastError = $e;
|
$lastError = $e;
|
||||||
|
|
@ -152,10 +153,14 @@ public function execute_remote_command(...$commands)
|
||||||
/**
|
/**
|
||||||
* Execute the actual command with process handling
|
* Execute the actual command with process handling
|
||||||
*/
|
*/
|
||||||
private function executeCommandWithProcess($command, $hidden, $customType, $append, $ignore_errors)
|
private function executeCommandWithProcess($command, $hidden, $customType, $append, $ignore_errors, $command_hidden = false)
|
||||||
{
|
{
|
||||||
|
if ($command_hidden && isset($this->application_deployment_queue)) {
|
||||||
|
$this->application_deployment_queue->addLogEntry('[CMD]: '.$this->redact_sensitive_info($command), hidden: true);
|
||||||
|
}
|
||||||
|
|
||||||
$remote_command = SshMultiplexingHelper::generateSshCommand($this->server, $command);
|
$remote_command = SshMultiplexingHelper::generateSshCommand($this->server, $command);
|
||||||
$process = Process::timeout(config('constants.ssh.command_timeout'))->idleTimeout(3600)->start($remote_command, function (string $type, string $output) use ($command, $hidden, $customType, $append) {
|
$process = Process::timeout(config('constants.ssh.command_timeout'))->idleTimeout(3600)->start($remote_command, function (string $type, string $output) use ($command, $hidden, $customType, $append, $command_hidden) {
|
||||||
$output = str($output)->trim();
|
$output = str($output)->trim();
|
||||||
if ($output->startsWith('╔')) {
|
if ($output->startsWith('╔')) {
|
||||||
$output = "\n".$output;
|
$output = "\n".$output;
|
||||||
|
|
@ -165,9 +170,9 @@ private function executeCommandWithProcess($command, $hidden, $customType, $appe
|
||||||
$sanitized_output = sanitize_utf8_text($output);
|
$sanitized_output = sanitize_utf8_text($output);
|
||||||
|
|
||||||
$new_log_entry = [
|
$new_log_entry = [
|
||||||
'command' => $this->redact_sensitive_info($command),
|
'command' => $command_hidden ? null : $this->redact_sensitive_info($command),
|
||||||
'output' => $this->redact_sensitive_info($sanitized_output),
|
'output' => $this->redact_sensitive_info($sanitized_output),
|
||||||
'type' => $customType ?? $type === 'err' ? 'stderr' : 'stdout',
|
'type' => $customType ?? ($type === 'err' ? 'stderr' : 'stdout'),
|
||||||
'timestamp' => Carbon::now('UTC'),
|
'timestamp' => Carbon::now('UTC'),
|
||||||
'hidden' => $hidden,
|
'hidden' => $hidden,
|
||||||
'batch' => static::$batch_counter,
|
'batch' => static::$batch_counter,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue