Skip to content

Mqe 1647 Read vault token from file system #392

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion etc/config/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ BROWSER=chrome

#*** Uncomment and set vault base url and access token if you want to use vault to manage _CREDS secrets ***#
#CREDENTIAL_VAULT_BASE_URL=
#CREDENTIAL_VAULT_TOKEN=

#*** Uncomment these properties to set up a dev environment with symlinked projects ***#
#TESTS_BP=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,9 @@ private function __construct()

// Initialize vault storage
$csBaseUrl = getenv('CREDENTIAL_VAULT_BASE_URL');
$csToken = getenv('CREDENTIAL_VAULT_TOKEN');
if ($csBaseUrl !== false && $csToken !== false) {
if ($csBaseUrl !== false) {
try {
$this->credStorage[self::ARRAY_KEY_FOR_VAULT] = new VaultStorage(
rtrim($csBaseUrl, '/'),
$csToken
);
$this->credStorage[self::ARRAY_KEY_FOR_VAULT] = new VaultStorage(rtrim($csBaseUrl, '/'));
} catch (TestFrameworkException $e) {
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,25 @@ class VaultStorage extends BaseStorage
const BASE_PATH = '/dx_magento_qe';
const KV_DATA = 'data';

/**
* Default vault token file
*/
const TOKEN_FILE = '.vault-token';
/**
* Default vault config file
*/
const CONFIG_FILE = '.vault';
/**
* Environment variable name for vault config path
*/
const CONFIG_PATH_ENV_VAR = 'VAULT_CONFIG_PATH';

/**
* Regex to grab token helper script
*/
const TOKEN_HELPER_REGEX_GROUP_NAME = 'GROUP_NAME';
const TOKEN_HELPER_REGEX = "~\s*token_helper\s*=(?<" . self::TOKEN_HELPER_REGEX_GROUP_NAME . ">.+)$~";

/**
* Vault client
*
Expand All @@ -33,23 +52,22 @@ class VaultStorage extends BaseStorage
*
* @var string
*/
private $token;
private $token = null;

/**
* CredentialVault constructor
*
* @param string $baseUrl
* @param string $token
* @throws TestFrameworkException
*/
public function __construct($baseUrl, $token)
public function __construct($baseUrl)
{
parent::__construct();
if (null === $this->client) {
// Creating the client using Guzzle6 Transport and passing a custom url
$this->client = new Client(new Guzzle6Transport(['base_uri' => $baseUrl]));
}
$this->token = $token;
$this->readVaultTokenFromFileSystem();
if (!$this->authenticated()) {
throw new TestFrameworkException("Credential vault is not used: cannot authenticate");
}
Expand Down Expand Up @@ -120,4 +138,87 @@ private function authenticated()
}
return false;
}

/**
* Read vault token from file system
*
* @return void
* @throws TestFrameworkException
*/
private function readVaultTokenFromFileSystem()
{
// Find user home directory
$homeDir = getenv('HOME');
if ($homeDir === false) {
throw new TestFrameworkException(
"HOME environment variable is not set. It's required when using vault."
);
}
$homeDir = realpath($homeDir) . DIRECTORY_SEPARATOR;

// Read .vault-token file if it is found in default location
$vaultTokenFile = $homeDir . self::TOKEN_FILE;
if (file_exists($vaultTokenFile)) {
$token = file_get_contents($vaultTokenFile);
if ($token !== false) {
$this->token = $token;
return;
}
}

// Otherwise search vault config file for custom token helper script
$vaultConfigPath = getenv(self::CONFIG_PATH_ENV_VAR);
if ($vaultConfigPath === false) {
$vaultConfigFile = $homeDir . self::CONFIG_FILE;
} else {
$vaultConfigFile = realpath($vaultConfigPath) . DIRECTORY_SEPARATOR . self::CONFIG_FILE;
}
// Get custom token helper script file from .vault config file
if (file_exists($vaultConfigFile)) {
$cmd = $this->getTokenHelperScript(file($vaultConfigFile, FILE_IGNORE_NEW_LINES));
if (!empty($cmd)) {
$this->token = $this->execVaultTokenHelper($cmd . ' get');
return;
}
}
throw new TestFrameworkException(
'Unable to read .vault-token file. Please authenticate to vault through vault CLI first.'
);
}

/**
* Get vault token helper script by parsing lines in vault config file
*
* @param array $lines
* @return string
*/
private function getTokenHelperScript($lines)
{
$tokenHelper = '';
foreach ($lines as $line) {
preg_match(self::TOKEN_HELPER_REGEX, $line, $matches);
if (isset($matches[self::TOKEN_HELPER_REGEX_GROUP_NAME])) {
$tokenHelper = trim(trim(trim($matches[self::TOKEN_HELPER_REGEX_GROUP_NAME]), '"'));
}
}
return $tokenHelper;
}

/**
* Execute vault token helper script and return the token it contains
*
* @param string $cmd
* @return string
* @throws TestFrameworkException
*/
private function execVaultTokenHelper($cmd)
{
exec($cmd, $out, $status);
if ($status === 0 && isset($out[0]) && !empty($out[0])) {
return $out[0];
}
throw new TestFrameworkException(
'Error running custom vault token helper script. Please make sure vault CLI works in your environment.'
);
}
}