-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEditCommand.php
More file actions
139 lines (121 loc) · 3.46 KB
/
Copy pathEditCommand.php
File metadata and controls
139 lines (121 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<?php
namespace Neuron\Cli\Commands\Secrets;
use Neuron\Cli\Commands\Command;
use Neuron\Data\Settings\SecretManager;
/**
* Edit encrypted secrets command
*
* Opens encrypted credentials in an editor for secure editing.
* Automatically re-encrypts the file when the editor is closed.
*
* Usage:
* neuron secrets:edit # Edit default secrets
* neuron secrets:edit --env=production # Edit production secrets
* neuron secrets:edit --editor="code --wait" # Use VS Code
*
* @package Neuron\Cli\Commands\Secrets
*/
class EditCommand extends Command
{
private SecretManager $secretManager;
/**
* @inheritDoc
*/
public function getName(): string
{
return 'secrets:edit';
}
/**
* @inheritDoc
*/
public function getDescription(): string
{
return 'Edit encrypted secrets file';
}
/**
* @inheritDoc
*/
public function configure(): void
{
$this->addOption( 'env', 'e', true, 'Environment to edit (default: base secrets)' );
$this->addOption( 'editor', null, true, 'Editor to use (default: vi)' );
$this->addOption( 'config', 'c', true, 'Config directory path (default: config)' );
$this->addOption( 'verbose', 'v', false, 'Verbose output' );
}
/**
* @inheritDoc
*/
public function execute(): int
{
$configPath = $this->input->getOption( 'config', 'config' );
$env = $this->input->getOption( 'env' );
$editor = $this->input->getOption( 'editor' ) ?? $_ENV['EDITOR'] ?? 'vi';
// Determine paths based on environment
if( $env )
{
$credentialsPath = $configPath . '/secrets/' . $env . '.yml.enc';
$keyPath = $configPath . '/secrets/' . $env . '.key';
$this->output->info( "Editing {$env} environment secrets..." );
}
else
{
$credentialsPath = $configPath . '/secrets.yml.enc';
$keyPath = $configPath . '/master.key';
$this->output->info( "Editing base secrets..." );
}
// Create SecretManager
$this->secretManager = new SecretManager();
try
{
// Ensure key exists
if( !file_exists( $keyPath ) )
{
$this->output->warning( "Key file not found at: {$keyPath}" );
$this->output->info( "Generating new encryption key..." );
// Ensure directory exists
$dir = dirname( $keyPath );
if( !is_dir( $dir ) )
{
if( !mkdir( $dir, 0755, true ) )
{
$this->output->error( "Failed to create directory: {$dir}" );
return 1;
}
}
$key = $this->secretManager->generateKey( $keyPath );
$this->output->success( "Generated new key at: {$keyPath}" );
$this->output->warning( "IMPORTANT: Add {$keyPath} to .gitignore!" );
}
// Edit the secrets
$result = $this->secretManager->edit( $credentialsPath, $keyPath, $editor );
if( $result )
{
$this->output->success( "Secrets saved to: {$credentialsPath}" );
// First time setup reminder
if( !$env && !file_exists( $configPath . '/.gitignore' ) )
{
$this->output->newLine();
$this->output->warning( "Remember to:" );
$this->output->write( "1. Add {$keyPath} to .gitignore" );
$this->output->write( "2. Commit {$credentialsPath} to version control" );
$this->output->write( "3. Share {$keyPath} securely with your team" );
}
}
else
{
$this->output->error( "Failed to save secrets" );
return 1;
}
}
catch( \Exception $e )
{
$this->output->error( "Error editing secrets: " . $e->getMessage() );
if( $this->input->hasOption( 'verbose' ) )
{
$this->output->write( $e->getTraceAsString() );
}
return 1;
}
return 0;
}
}