Skip to content

Commit

Permalink
[LOPS-1652] Add secret:site:local-generate command. (#48)
Browse files Browse the repository at this point in the history
* Add new local-generate command.

* Add docs.
  • Loading branch information
kporras07 authored Aug 30, 2023
1 parent bccc35b commit a4610b6
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 5 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,17 @@ terminus secret:site:delete <site>.<env> <secret-name>
[notice] Success
```

#### Generate file for local development

The secrets `local-generate` command will generate a json file useful for local development emulation of secrets.

**Run the command below to get a json file:**

```
terminus secret:site:local-generate <site> --filepath=./secrets.json
[notice] Secrets file written to: ./secrets.json. Please review this file and adjust accordingly for your local usage.
```

### Organization secrets Commands

#### Set a secret
Expand Down
93 changes: 93 additions & 0 deletions src/Commands/SiteLocalGenerateCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace Pantheon\TerminusSecretsManager\Commands;

use Pantheon\Terminus\Commands\StructuredListTrait;
use Pantheon\Terminus\Site\SiteAwareTrait;
use Pantheon\Terminus\Site\SiteAwareInterface;
use Consolidation\OutputFormatters\StructuredData\RowsOfFields;
use Pantheon\Terminus\Request\RequestOperationResult;
use Pantheon\Terminus\Exceptions\TerminusException;

/**
* Class SiteLocalGenerateCommand.
*
* Generate local secrets file for usage of secrets in local environment.
*
* @package Pantheon\TerminusSecretsManager\Commands
*/
class SiteLocalGenerateCommand extends SecretBaseCommand implements SiteAwareInterface
{
use StructuredListTrait;
use SiteAwareTrait;

/**
* Generate json file for usage in local environment.
*
* @authorize
*
* @command secret:site:local-generate
* @aliases secret:local-generate
*
* @option string $filepath Output to given file path. Default is to output to ./secrets.json
*
* @usage <site> Generate json file with secrets for local usage.
* @usage <site> --filepath=/my/path/filename.json Generate json file in given location with secrets for local usage.
*
* @param string $site_id The name or UUID of a site to retrieve information on
* @param array $options
*
* @return RowsOfFields
* @throws \GuzzleHttp\Exception\GuzzleException
* @throws \Pantheon\Terminus\Exceptions\TerminusException
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
public function localGenerateSecrets($site_id, array $options = ['filepath' => 'secrets.json',])
{
$env_name = '';
if (strpos($site_id, '.') !== false) {
list($site_id, $env_name) = explode('.', $site_id, 2);
}
$site = $this->getSite($site_id);
$this->setupRequest();
$result = $this->secretsApi->fetchSecrets($site->id);
if ($result->getStatusCode() != 200) {
throw new TerminusException($result->getData());
}
$data = $result->getData();
$json_contents = json_encode($data, JSON_PRETTY_PRINT);
$filepath = $options['filepath'];
$ret = file_put_contents($filepath, $json_contents);
if ($ret === false) {
throw new TerminusException('Unable to write to file: ' . $filepath);
}
$this->log()->notice(sprintf("Secrets file written to: %s. Please review this file and adjust accordingly for your local usage.", $filepath));
}

/**
* @param array $secrets Complete secret data
* @param string $env_name Name of environment to pull secrets from
*
* @return array Secret data containing only secrets with overrides
* in the specified environment.
*/
protected function secretsForEnv(array $secrets, $env_name)
{
$result = [];

foreach ($secrets as $key => $data) {
if (array_key_exists($env_name, $data['env-values'] ?? [])) {
$result[$key] = [
'name' => $key,
'type' => $data['type'],
'value' => $data['env-values'][$env_name],
'scopes' => $data['scopes'],
];
}
}

return $result;
}

}
31 changes: 26 additions & 5 deletions src/SecretsApi/SecretsApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ private function getBaseURI()
}

/**
* List secrets for a given site.
* Fetch secrets for a given site.
*
* @param string $workspaceId
* Site/org id to get secrets for.
Expand All @@ -55,13 +55,13 @@ private function getBaseURI()
* @param string $workspaceType
* Whether to return the secrets for a site or org.
*
* @return array|Pantheon\Terminus\Request\RequestOperationResult
* Secrets for given site or the operation result in case of error.
* @return Pantheon\Terminus\Request\RequestOperationResult
* Request operation result.
*
* @throws \GuzzleHttp\Exception\GuzzleException
* @throws \Pantheon\Terminus\Exceptions\TerminusException
*/
public function listSecrets(string $workspaceId, bool $debug = false, string $workspaceType = "sites")
public function fetchSecrets(string $workspaceId, bool $debug = false, string $workspaceType = "sites")
{
if (getenv('TERMINUS_PLUGIN_TESTING_MODE')) {
if (file_exists('/tmp/secrets.json')) {
Expand All @@ -84,7 +84,28 @@ public function listSecrets(string $workspaceId, bool $debug = false, string $wo
],
'debug' => $debug,
];
$result = $this->request()->request($url, $options);
return $this->request()->request($url, $options);
}

/**
* List secrets for a given site.
*
* @param string $workspaceId
* Site/org id to get secrets for.
* @param bool $debug
* Whether to return the secrets in debug mode.
* @param string $workspaceType
* Whether to return the secrets for a site or org.
*
* @return array|Pantheon\Terminus\Request\RequestOperationResult
* Secrets for given site or the operation result in case of error.
*
* @throws \GuzzleHttp\Exception\GuzzleException
* @throws \Pantheon\Terminus\Exceptions\TerminusException
*/
public function listSecrets(string $workspaceId, bool $debug = false, string $workspaceType = "sites")
{
$result = $this->fetchSecrets($workspaceId, $debug, $workspaceType);
if ($result->getStatusCode() !== 200) {
return $result;
}
Expand Down

0 comments on commit a4610b6

Please sign in to comment.