88
99class Processor
1010{
11+ const VAULT_KEYWORD = 'vault ' ;
12+ const VAULT_URL_KEYWORD = 'url ' ;
13+ const VAULT_API_TOKEN_KEYWORD = 'token ' ;
1114
1215 /**
1316 * @var array
@@ -31,16 +34,27 @@ class Processor
3134
3235 private $ useAggregator ;
3336
37+ /**
38+ * @var VaultRepository
39+ */
40+ private $ vaultRepository ;
41+ /**
42+ * @var array
43+ */
44+ private $ vaultVariables ;
45+
46+
3447 /**
3548 * Processor constructor.
3649 * @param $path
3750 * @param $section
51+ * @param $useAggregator
3852 */
3953 public function __construct ($ path , $ section , $ useAggregator )
4054 {
41- $ this ->path = $ path ;
42- $ this ->section = $ section ;
43- $ this ->useAggregator = $ useAggregator ;
55+ $ this ->path = $ path ;
56+ $ this ->section = $ section ;
57+ $ this ->useAggregator = $ useAggregator ;
4458 }
4559
4660 public function process ()
@@ -53,21 +67,31 @@ public function process()
5367 ? $ this ->getSection ($ this ->section )
5468 : $ this ->mergeSections ();
5569
70+ $ this ->getVaultVariables ();
71+
72+ if (empty ($ this ->vaultVariables )) {
73+ return $ this ->data ;
74+ }
75+
76+ $ this ->setVaultRepo ();
77+
78+ $ this ->replaceVaultVariablesWithData ($ this ->data , $ this ->getValuesFromVault ());
79+
5680 return $ this ->data ;
5781 }
5882
5983 private function getSection ($ name )
6084 {
6185 $ this ->processSections ();
6286
63- if (!array_key_exists ($ name , $ this ->sections )) {
87+ if (!array_key_exists ($ name , $ this ->sections )) {
6488 throw new \Exception ("Section ' {$ name }' missing " );
6589 }
6690
6791 $ extends = false ;
6892 $ parentData = array ();
6993
70- if ($ this ->sections [$ name ] !== null ) {
94+ if ($ this ->sections [$ name ] !== null ) {
7195 $ extends = true ;
7296 $ func = __FUNCTION__ ;
7397 $ parentData = $ this ->$ func ($ this ->sections [$ name ]);
@@ -96,7 +120,7 @@ private function getSectionName($item)
96120 private function mergeSections ()
97121 {
98122 $ tmpData = [];
99- foreach ($ this ->data as $ sectionName => $ data ){
123+ foreach ($ this ->data as $ sectionName => $ data ) {
100124 $ name = $ this ->getSectionName ($ sectionName );
101125 $ tmpData [$ name ] = $ this ->getSection ($ name );
102126 }
@@ -107,8 +131,9 @@ private function processSections()
107131 {
108132 $ tmp = array_keys ($ this ->data );
109133
110- foreach ($ tmp as $ item ) {
111- if (substr_count ($ item , ": " ) > 1 ) { }
134+ foreach ($ tmp as $ item ) {
135+ if (substr_count ($ item , ": " ) > 1 ) {
136+ }
112137
113138 $ segments = explode (': ' , $ item );
114139
@@ -136,11 +161,91 @@ private function readFromFile()
136161 {
137162 $ path = realpath ($ this ->path );
138163
139- if (false === $ path || !is_readable ($ path )) {
164+ if (false === $ path || !is_readable ($ path )) {
140165 throw new \Exception ('Configuration file is not readable ' );
141166 }
142167
143168 $ reader = new Reader ();
144169 $ this ->data = $ reader ->fromFile ($ path );
145170 }
171+
172+ private function getVaultVariables ()
173+ {
174+ $ this ->vaultVariables = $ this ->filterMultiArray ($ this ->data );
175+ }
176+
177+ public function filterMultiArray (array $ data )
178+ {
179+ $ filteredArray = [];
180+ foreach ($ data as $ value ) {
181+ if (is_array ($ value )) {
182+ $ filteredSubArray = $ this ->filterMultiArray ($ value );
183+ $ filteredArray = array_merge ($ filteredArray , $ filteredSubArray );
184+ } elseif (substr ($ value , 0 , strlen (self ::VAULT_KEYWORD )) === self ::VAULT_KEYWORD ) {
185+ $ filteredArray [] = $ value ;
186+ }
187+ }
188+
189+ return $ filteredArray ;
190+ }
191+
192+ private function sortVariablesByRouteAndKey ()
193+ {
194+ //todo maybe remove strtolower when variables are stored in apper case in vault.
195+ $ sorted = [];
196+ foreach ($ this ->vaultVariables as $ vaultVariable ) {
197+ $ array = explode ('/ ' , strtolower ($ vaultVariable ));
198+ $ secretKey = array_pop ($ array );
199+ array_shift ($ array );
200+ $ secretRoute = implode ('/ ' , $ array );
201+ $ sorted [$ secretRoute ][] = $ secretKey ;
202+ }
203+
204+ return $ sorted ;
205+ }
206+
207+ private function getValuesFromVault ()
208+ {
209+ $ sorted = $ this ->sortVariablesByRouteAndKey ();
210+
211+ $ data = [];
212+
213+ foreach ($ sorted as $ section => $ secretKeys ) {
214+ $ valuesForSection = $ this ->vaultRepository ->getValueBySection ($ section );
215+ foreach ($ secretKeys as $ secretKey ) {
216+ $ data [self ::VAULT_KEYWORD . '/ ' . $ section . '/ ' . $ secretKey ] = $ valuesForSection [$ secretKey ] ?? '' ;
217+ }
218+ }
219+
220+ return $ data ;
221+ }
222+
223+ public function replaceVaultVariablesWithData (&$ array , $ searchArray )
224+ {
225+ foreach ($ array as &$ value ) {
226+ if (is_array ($ value )) {
227+ $ this ->replaceVaultVariablesWithData ($ value , $ searchArray );
228+ } else {
229+ if (array_key_exists ($ value , $ searchArray )) {
230+ $ value = $ searchArray [$ value ];
231+ }
232+ }
233+ }
234+ }
235+
236+ private function setVaultRepo ()
237+ {
238+ $ message = 'No config found for Vault %s ' ;
239+
240+ if (!isset ($ this ->data [self ::VAULT_KEYWORD ][self ::VAULT_URL_KEYWORD ])){
241+ throw new \RuntimeException (sprintf ($ message , self ::VAULT_URL_KEYWORD ));
242+ }
243+ if (!isset ($ this ->data [self ::VAULT_KEYWORD ][self ::VAULT_API_TOKEN_KEYWORD ])){
244+ throw new \RuntimeException (sprintf ($ message , self ::VAULT_API_TOKEN_KEYWORD ));
245+ }
246+
247+ $ this ->vaultRepository = new VaultRepository (
248+ $ this ->data [self ::VAULT_KEYWORD ][self ::VAULT_URL_KEYWORD ],
249+ $ this ->data [self ::VAULT_KEYWORD ][self ::VAULT_API_TOKEN_KEYWORD ]);
250+ }
146251}
0 commit comments