@@ -21,6 +21,21 @@ class VaultStorage extends BaseStorage
21
21
const BASE_PATH = '/dx_magento_qe ' ;
22
22
const KV_DATA = 'data ' ;
23
23
24
+ /**
25
+ * Default vault token file
26
+ */
27
+ const TOKEN_FILE = '.vault-token ' ;
28
+ /**
29
+ * Default vault config file
30
+ */
31
+ const CONFIG_FILE = '.vault ' ;
32
+ /**
33
+ * Environment variable name for vault config path
34
+ */
35
+ const CONFIG_PATH_ENV_VAR = 'VAULT_CONFIG_PATH ' ;
36
+
37
+ const TOKEN_HELPER_REGEX = "~\s*token_helper\s*=(.+)$~ " ;
38
+
24
39
/**
25
40
* Vault client
26
41
*
@@ -33,23 +48,22 @@ class VaultStorage extends BaseStorage
33
48
*
34
49
* @var string
35
50
*/
36
- private $ token ;
51
+ private $ token = null ;
37
52
38
53
/**
39
54
* CredentialVault constructor
40
55
*
41
56
* @param string $baseUrl
42
- * @param string $token
43
57
* @throws TestFrameworkException
44
58
*/
45
- public function __construct ($ baseUrl, $ token )
59
+ public function __construct ($ baseUrl )
46
60
{
47
61
parent ::__construct ();
48
62
if (null === $ this ->client ) {
49
63
// Creating the client using Guzzle6 Transport and passing a custom url
50
64
$ this ->client = new Client (new Guzzle6Transport (['base_uri ' => $ baseUrl ]));
51
65
}
52
- $ this ->token = $ token ;
66
+ $ this ->readVaultTokenFromFileSystem () ;
53
67
if (!$ this ->authenticated ()) {
54
68
throw new TestFrameworkException ("Credential vault is not used: cannot authenticate " );
55
69
}
@@ -120,4 +134,80 @@ private function authenticated()
120
134
}
121
135
return false ;
122
136
}
137
+
138
+ /**
139
+ * Read vault token from file system
140
+ *
141
+ * @return void
142
+ * @throws TestFrameworkException
143
+ */
144
+ private function readVaultTokenFromFileSystem ()
145
+ {
146
+ // Find user home directory
147
+ $ homeDir = getenv ('HOME ' );
148
+ if ($ homeDir === false ) {
149
+ // If HOME is not set, don't fail right away
150
+ $ homeDir = '~/ ' ;
151
+ } else {
152
+ $ homeDir = rtrim ($ homeDir , '/ ' ) . '/ ' ;
153
+ }
154
+
155
+ $ vaultTokenFile = $ homeDir . self ::TOKEN_FILE ;
156
+ if (file_exists ($ vaultTokenFile )) {
157
+ // Found .vault-token file in default location, construct command
158
+ $ cmd = 'cat ' . $ vaultTokenFile ;
159
+ } else {
160
+ // Otherwise search vault config file for custom token helper script
161
+ $ vaultConfigPath = getenv (self ::CONFIG_PATH_ENV_VAR );
162
+ if ($ vaultConfigPath === false ) {
163
+ $ vaultConfigFile = $ homeDir . self ::CONFIG_FILE ;
164
+ } else {
165
+ $ vaultConfigFile = rtrim ($ vaultConfigPath , '/ ' ) . '/ ' . self ::CONFIG_FILE ;
166
+ }
167
+ // Found .vault config file, read custom token helper script and construct command
168
+ if (file_exists ($ vaultConfigFile )
169
+ && !empty ($ cmd = $ this ->getTokenHelperScript (file ($ vaultConfigFile , FILE_IGNORE_NEW_LINES )))) {
170
+ $ cmd = $ cmd . ' get ' ;
171
+ } else {
172
+ throw new TestFrameworkException (
173
+ 'Unable to read .vault-token file. Please authenticate to vault through vault CLI first. '
174
+ );
175
+ }
176
+ }
177
+ $ this ->token = $ this ->execVaultTokenHelper ($ cmd );
178
+ }
179
+
180
+ /**
181
+ * Get vault token helper script by parsing lines in vault config file
182
+ *
183
+ * @param array $lines
184
+ * @return array
185
+ */
186
+ private function getTokenHelperScript ($ lines )
187
+ {
188
+ $ tokenHelper = '' ;
189
+ foreach ($ lines as $ line ) {
190
+ preg_match (self ::TOKEN_HELPER_REGEX , $ line , $ matches );
191
+ if (isset ($ matches [1 ])) {
192
+ $ tokenHelper = trim (trim (trim ($ matches [1 ]), '" ' ));
193
+ }
194
+ }
195
+ return $ tokenHelper ;
196
+ }
197
+
198
+ /**
199
+ * Execute vault token helper script and return the token it contains
200
+ *
201
+ * @param string $cmd
202
+ * @return string
203
+ */
204
+ private function execVaultTokenHelper ($ cmd )
205
+ {
206
+ $ output = '' ;
207
+ exec ($ cmd , $ out , $ status );
208
+ if ($ status === 0 && isset ($ out [0 ])) {
209
+ $ output = $ out [0 ];
210
+ }
211
+ return $ output ;
212
+ }
123
213
}
0 commit comments