Skip to content
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

Added Drush PolicyCommands #137

Merged
Merged
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
59 changes: 52 additions & 7 deletions drush/Commands/PolicyCommands.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,81 @@
namespace Drush\Commands;

use Consolidation\AnnotatedCommand\CommandData;
use Drush\Drush;

/**
* Edit this file to reflect your organization's needs.
*/
class PolicyCommands extends DrushCommands {

/**
* Prevent catastrophic braino. Note that this file has to be local to the
* machine that initiates the sql:sync command.
* Parameter to set the instance is protected.
*/
const PROTECTED_PARAMETER = "protected-instance";

/**
* Not execute the rsync if the instance is protected.
*
* @hook validate sql:sync
*
* @throws \Exception
*/
public function sqlSyncValidate(CommandData $commandData) {
if ($commandData->input()->getArgument('target') == '@prod') {
throw new \Exception(dt('Per !file, you may never overwrite the production database.', ['!file' => __FILE__]));
$target_alias = $commandData->input()->getArgument('target');
if ($this->isInstanceProtected($target_alias)) {
throw new \Exception(dt('Alias: !alias. You can not overwrite the database.', ['!alias' => $target_alias]));
}
}

/**
* Limit rsync operations to production site.
* Not execute the rsync if the instance is protected.
*
* @hook validate core:rsync
*
* @throws \Exception
*/
public function rsyncValidate(CommandData $commandData) {
if (preg_match("/^@prod/", $commandData->input()->getArgument('target'))) {
throw new \Exception(dt('Per !file, you may never rsync to the production site.', ['!file' => __FILE__]));
$target_alias = $commandData->input()->getArgument('target');
if ($this->isInstanceProtected($target_alias)) {
throw new \Exception(dt('Alias: !alias. You can not overwrite the code or the files.', ['!alias' => $target_alias]));
}
}

/**
* Not execute the sql:drop if the instance is protected.
*
* @hook validate sql:drop
*
* @throws \Exception
*/
public function dropValidate(CommandData $commandData) {
if ($this->isInstanceProtected('@self')) {
throw new \Exception(dt('You are not allowed to delete the database.'));
}
}

/**
* Determine if an instance is protected.
*
* @param string $alias
* Alias of drush. Self if it is local.
*
* @return bool
* If it is protected.
*/
protected function isInstanceProtected(string $alias): bool {
// If alias is local, check the user context configuration.
if ($alias === "@self") {
$user_context = $this->getConfig()->getContext('user');
return $user_context->get(PolicyCommands::PROTECTED_PARAMETER, NULL) ?? FALSE;
}

// Check the alias configuration.
$alias_configuration = Drush::aliasManager()->getAlias($alias);
if (empty($alias_configuration)) {
return FALSE;
}
return $alias_configuration->get(PolicyCommands::PROTECTED_PARAMETER, NULL) ?? FALSE;
}

}
6 changes: 6 additions & 0 deletions drush/Commands/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Drush command policies have been implemented to prevent the execution of certain drush commands: 'core:sync',
'sql:sync', and 'sql:drop' in production or other environment instances.

To apply these policies, two actions must be taken:
- In the definition of the alias for the environment where you want these policies to be applied you have to add the parameter: "protected-instance: true"
- On the server of the environment, copy the 'drush/Commands/drush.yml.dist' to the user's .drush folder of the user used for SSH connections to the server.
3 changes: 3 additions & 0 deletions drush/Commands/drush.yml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# This configuration file must be copied to the user's .drush folder in the environment where we want to enable
# protection for commands that may drop or overwrite the database.
protected-instance: true
Loading