├── .coveralls.yml ├── .gitattributes ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── deploy.yml │ └── test.yml ├── .gitignore ├── LICENSE.md ├── README.md ├── VERSION ├── bin ├── acquiacli └── acquiacli-robo.php ├── box.json ├── composer.json ├── composer.lock ├── default.acquiacli.yml ├── phpstan.neon ├── phpunit.xml ├── src ├── Cli │ ├── AcquiaCli.php │ ├── CloudApi.php │ └── Config.php ├── Commands │ ├── AccountCommand.php │ ├── AcquiaCommand.php │ ├── ApplicationsCommand.php │ ├── CacheClearCommand.php │ ├── CodeCommand.php │ ├── CronCommand.php │ ├── DbBackupCommand.php │ ├── DbCommand.php │ ├── DeployCommand.php │ ├── DomainCommand.php │ ├── DrushAliasesCommand.php │ ├── EnvironmentsCommand.php │ ├── FilesCommand.php │ ├── IdesCommand.php │ ├── InsightsCommand.php │ ├── LivedevCommand.php │ ├── LogForwardCommand.php │ ├── LogsCommand.php │ ├── NotificationsCommand.php │ ├── OrganizationsCommand.php │ ├── ProductionModeCommand.php │ ├── SetupCommand.php │ ├── SshCommand.php │ ├── SslCertificateCommand.php │ ├── TeamsCommand.php │ └── VariablesCommand.php └── Injector │ └── AcquiaCliInjector.php └── tests ├── AcquiaCliApplicationTest.php ├── AcquiaCliTestCase.php ├── Commands ├── AccountCommandTest.php ├── ApplicationCommandTest.php ├── CacheClearCommandTest.php ├── CodeCommandTest.php ├── CronCommandTest.php ├── DbBackupCommandTest.php ├── DbCommandTest.php ├── DeployCommandTest.php ├── DomainsCommandTest.php ├── EnvironmentCommandTest.php ├── FilesCommandTest.php ├── IdesCommandTest.php ├── InsightsCommandTest.php ├── LiveDevCommandTest.php ├── LogForwardCommandTest.php ├── LogsCommandTest.php ├── NotificationCommandTest.php ├── OrganizationsCommandTest.php ├── PermissionsCommandTest.php ├── ProductionModeCommandTest.php ├── RolesCommandTest.php ├── SetupCommandTest.php ├── SshCommandTest.php ├── SslCertificateCommandTest.php ├── TeamsCommandTest.php └── VariablesCommandTest.php └── Fixtures └── SslCertificates ├── ca.pem ├── cert.pem └── key.pem /.coveralls.yml: -------------------------------------------------------------------------------- 1 | coverage_clover: tests/logs/clover.xml 2 | json_path: tests/logs/coveralls-upload.json 3 | service_name: travis-ci 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: typhonius 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior including calling code: 15 | 1. Attempted to call backup endpoint '...' 16 | 2. Passed parameters '....' 17 | 3. See error 18 | 19 | **Expected behavior** 20 | A clear and concise description of what you expected to happen. 21 | 22 | **Screenshots** 23 | If applicable, add screenshots to help explain your problem. 24 | 25 | **Desktop (please complete the following information):** 26 | - OS: [e.g. iOS] 27 | - Code version/tag [e.g. 22] 28 | 29 | **Additional context** 30 | Add any other context about the problem here. 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Acquia Cli Deploy 2 | 3 | on: 4 | push: 5 | tags: 6 | - '[0-9]+.[0-9]+.[0-9]+' 7 | 8 | jobs: 9 | run: 10 | runs-on: ${{ matrix.operating-system }} 11 | strategy: 12 | matrix: 13 | operating-system: [ubuntu-latest] 14 | php-versions: ['7.3'] 15 | name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v2 19 | 20 | - name: Setup PHP 21 | uses: shivammathur/setup-php@v2 22 | with: 23 | php-version: ${{ matrix.php-versions }} 24 | extensions: mbstring, intl 25 | ini-values: post_max_size=256M, short_open_tag=On 26 | 27 | - name: Validate composer.json and composer.lock 28 | run: composer validate 29 | 30 | - name: Cache Composer packages 31 | id: composer-cache 32 | uses: actions/cache@v2 33 | with: 34 | path: vendor 35 | key: ${{ runner.os }}-php-${{ matrix.php-versions }}-${{ hashFiles('**/composer.lock') }} 36 | restore-keys: | 37 | ${{ runner.os }}-php-${{ matrix.php-versions }}- 38 | 39 | - name: Install dependencies 40 | if: steps.composer-cache.outputs.cache-hit != 'true' 41 | run: composer install --prefer-source --no-progress --no-suggest --no-interaction 42 | 43 | - name: Install Phar tools and build deployment artefact. 44 | run: | 45 | composer phar:install-tools 46 | rm -rf vendor/* 47 | composer install --prefer-dist --no-dev --no-interaction 48 | composer phar:build 49 | 50 | - name: Create Release 51 | id: create_release 52 | uses: actions/create-release@v1 53 | env: 54 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 55 | with: 56 | tag_name: ${{ github.ref }} 57 | release_name: ${{ github.ref }} 58 | draft: false 59 | prerelease: false 60 | 61 | - name: Upload Release Asset 62 | id: upload-release-asset 63 | uses: actions/upload-release-asset@v1 64 | env: 65 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 66 | with: 67 | upload_url: ${{ steps.create_release.outputs.upload_url }} 68 | asset_path: ./acquiacli.phar 69 | asset_name: acquiacli.phar 70 | asset_content_type: application/octet-stream 71 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Acquia Cli Test 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | run: 11 | runs-on: ${{ matrix.operating-system }} 12 | strategy: 13 | matrix: 14 | operating-system: [ubuntu-latest, macos-latest, windows-latest] 15 | php-versions: ['7.3', '7.4'] 16 | name: PHP ${{ matrix.php-versions }} build and test on ${{ matrix.operating-system }} 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v2 20 | 21 | - name: Setup PHP 22 | uses: shivammathur/setup-php@v2 23 | with: 24 | php-version: ${{ matrix.php-versions }} 25 | extensions: mbstring, intl 26 | ini-values: post_max_size=256M, short_open_tag=On 27 | 28 | 29 | - name: Setup PHP with pecl extension 30 | uses: shivammathur/setup-php@v2 31 | with: 32 | php-version: ${{ matrix.php-versions }} 33 | tools: pecl 34 | extensions: pcov 35 | 36 | - name: Validate composer.json and composer.lock 37 | run: composer validate 38 | 39 | - name: Cache Composer packages 40 | id: composer-cache 41 | uses: actions/cache@v2 42 | with: 43 | path: vendor 44 | key: ${{ runner.os }}-php-${{ matrix.php-versions }}-${{ hashFiles('**/composer.lock') }} 45 | restore-keys: | 46 | ${{ runner.os }}-php-${{ matrix.php-versions }}- 47 | 48 | - name: Install dependencies 49 | if: steps.composer-cache.outputs.cache-hit != 'true' 50 | run: composer install --prefer-source --no-progress --no-suggest --no-interaction 51 | 52 | - name: Run test suite 53 | run: composer run-script test 54 | 55 | - name: Remove requirement for pcov/clobber 56 | run: composer remove pcov/clobber 57 | 58 | - name: Install Phar tools and build deployment artefact. 59 | env: 60 | COMPOSER_DISCARD_CHANGES: true 61 | run: | 62 | composer phar:install-tools 63 | composer install --prefer-dist --no-dev --no-interaction 64 | composer phar:build 65 | 66 | - name: Run the phar 67 | run: php acquiacli.phar 68 | 69 | - name: Upload artefact 70 | uses: actions/upload-artifact@v2 71 | with: 72 | name: ${{ runner.os }}-php-${{ matrix.php-versions }}-acquiacli.phar 73 | path: acquiacli.phar 74 | if-no-files-found: error 75 | 76 | - name: Upload code coverage 77 | uses: actions/upload-artifact@v2 78 | with: 79 | name: ${{ runner.os }}-php-${{ matrix.php-versions }}-phpunit.html 80 | path: ./tests/logs/phpunit.html 81 | 82 | - name: Upload coverage to Codecov 83 | uses: codecov/codecov-action@v1 84 | with: 85 | file: ./tests/logs/clover.xml 86 | name: acquia-cli-codecov 87 | fail_ci_if_error: true% 88 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | acquiacli.yml 2 | robo.yml 3 | vendor 4 | .idea 5 | tests/logs 6 | tools 7 | *.phar 8 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Adam Malone 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 2.0.11-dev 2 | -------------------------------------------------------------------------------- /bin/acquiacli: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | run($input, $output); 39 | exit($statusCode); 40 | -------------------------------------------------------------------------------- /box.json: -------------------------------------------------------------------------------- 1 | { 2 | "chmod": "0755", 3 | "directories": [ 4 | "src" 5 | ], 6 | "files": [ 7 | "default.acquiacli.yml", 8 | "VERSION", 9 | "vendor/typhonius/acquia-php-sdk-v2/VERSION" 10 | ], 11 | "finder": [ 12 | { 13 | "name": "*.php", 14 | "exclude": ["Tests"], 15 | "in": ["vendor", "bin"] 16 | } 17 | ], 18 | "git-version": "package_version", 19 | "main": "bin/acquiacli", 20 | "output": "acquiacli.phar", 21 | "stub": true 22 | } 23 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typhonius/acquia_cli", 3 | "description": "A Robo CLI tool for integrating with Acquia CloudAPI", 4 | "authors": [ 5 | { 6 | "name": "Adam Malone", 7 | "email": "adam@adammalone.net" 8 | } 9 | ], 10 | "license": "MIT", 11 | "require": { 12 | "php": ">=7.3", 13 | "typhonius/acquia-php-sdk-v2": "^2.0.0", 14 | "typhonius/acquia-logstream": "^0.0.7", 15 | "consolidation/robo": "^2", 16 | "symfony/lock": "^5.2.0", 17 | "symfony/yaml": "^5.2.0", 18 | "symfony/cache": "^4|^5", 19 | "webmozart/path-util": "^2.3" 20 | }, 21 | "bin": ["bin/acquiacli"], 22 | "autoload":{ 23 | "psr-4":{ 24 | "AcquiaCli\\":"src" 25 | } 26 | }, 27 | "autoload-dev": { 28 | "psr-4":{ 29 | "AcquiaCli\\Tests\\": "tests/" 30 | } 31 | }, 32 | "require-dev": { 33 | "php-coveralls/php-coveralls": "^2.0.0", 34 | "squizlabs/php_codesniffer": "^3.1", 35 | "phpstan/phpstan": "^0.11.19", 36 | "phpunit/phpunit": "^9.4", 37 | "phpstan/phpstan-phpunit": "^0.11.2" 38 | }, 39 | "scripts": { 40 | "phar:install-tools": [ 41 | "mkdir -p tools", 42 | "curl -L https://github.com/humbug/box/releases/download/3.8.4/box.phar -o tools/box", 43 | "chmod +x tools/box" 44 | ], 45 | "phar:build": "php tools/box compile", 46 | "lint": [ 47 | "find src -name '*.php' -print0 | xargs -0 -n1 php -l", 48 | "find tests -name '*.php' -print0 | xargs -0 -n1 php -l" 49 | ], 50 | "cs": "phpcs --standard=PSR12 -n src tests --ignore=./tests/logs/*", 51 | "cbf": "phpcbf --standard=PSR2 -n src tests", 52 | "unit": "php -dpcov.enabled=1 -dpcov.directory=. -dpcov.exclude='~vendor~' ./vendor/bin/phpunit --configuration=phpunit.xml --testdox", 53 | "stan": "phpstan analyse --level 7 src tests", 54 | "test": [ 55 | "@lint", 56 | "@unit", 57 | "@cs", 58 | "@stan" 59 | ], 60 | "release": [ 61 | "release VERSION" 62 | ], 63 | "coveralls": "php ./vendor/bin/php-coveralls -v" 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /default.acquiacli.yml: -------------------------------------------------------------------------------- 1 | acquia: 2 | key: 'd0697bfc-7f56-4942-9205-b5686bf5b3f5' 3 | secret: 'D5UfO/4FfNBWn4+0cUwpLOoFzfP7Qqib4AoY+wYGsKE=' 4 | extraconfig: 5 | timezone: 'Australia/Sydney' 6 | format: 'Y-m-d H:i:s' 7 | taskwait: 5 8 | timeout: 300 9 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | includes: 2 | - vendor/phpstan/phpstan-phpunit/extension.neon 3 | 4 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | ./tests/ 13 | 14 | 15 | 16 | 17 | ./src/ 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/Cli/AcquiaCli.php: -------------------------------------------------------------------------------- 1 | addOption('headers', [ 54 | 'User-Agent' => sprintf("%s/%s (https://github.com/typhonius/acquia_cli)", self::NAME, $version) 55 | ]); 56 | 57 | // Create application. 58 | $this->setConfig($config); 59 | $application = new Application(self::NAME, $version); 60 | 61 | $application->getDefinition()->addOptions( 62 | [ 63 | new InputOption( 64 | '--no-wait', 65 | null, 66 | InputOption::VALUE_NONE, 67 | 'Run commands without waiting for tasks to complete (risky).' 68 | ), 69 | new InputOption( 70 | '--realm', 71 | '-r', 72 | InputOption::VALUE_REQUIRED, 73 | 'Specify an alternate realm to use for API calls.', 74 | 'prod' 75 | ), 76 | new InputOption( 77 | '--yes', 78 | '-y', 79 | InputOption::VALUE_NONE, 80 | 'Automatically respond "yes" to all confirmation questions.' 81 | ), 82 | new InputOption( 83 | '--no-lock', 84 | null, 85 | InputOption::VALUE_NONE, 86 | 'Run commands without locking. Allows multiple instances of commands to run concurrently.' 87 | ), 88 | new InputOption( 89 | '--limit', 90 | '-l', 91 | InputOption::VALUE_REQUIRED, 92 | 'The maximum number of items to return.' 93 | ), 94 | new InputOption( 95 | '--filter', 96 | '-f', 97 | InputOption::VALUE_REQUIRED, 98 | 'The filters query string parameter restricts the data 99 | returned from your request. Filtered queries restrict the rows that do 100 | (or do not) get included in the result by testing each row in the result 101 | against the filters. Not all fields are filterable.' 102 | ), 103 | new InputOption( 104 | '--sort', 105 | '-s', 106 | InputOption::VALUE_REQUIRED, 107 | 'A comma-delimited string with fields used for sorting. 108 | The order of the fields is significant. A leading - in the field indicates 109 | the field should be sorted in a descending order. Not all fields are sortable.' 110 | ), 111 | ] 112 | ); 113 | 114 | // Create and configure container. 115 | $container = $this->getContainer($input, $output, $application, $config, $client); 116 | 117 | $this->injectParameters($container); 118 | 119 | $discovery = new CommandFileDiscovery(); 120 | $discovery->setSearchPattern('*Command.php'); 121 | $commandClasses = $discovery->discover( 122 | dirname(__DIR__) . \DIRECTORY_SEPARATOR . 'Commands', 123 | '\AcquiaCli\Commands' 124 | ); 125 | 126 | // Instantiate Robo Runner. 127 | $this->runner = new RoboRunner(); 128 | $this->runner->setContainer($container); 129 | $this->runner->registerCommandClasses($application, $commandClasses); 130 | $this->runner->setSelfUpdateRepository('typhonius/acquia_cli'); 131 | } 132 | 133 | public function getContainer($input, $output, $application, $config, $client) 134 | { 135 | $container = Robo::createDefaultContainer($input, $output, $application, $config); 136 | $container->add('client', $client); 137 | 138 | $container->add('cloudApi', CloudApi::class) 139 | ->withArgument('config') 140 | ->withArgument('client'); 141 | 142 | $container->add('logstream', LogstreamManager::class) 143 | ->withArgument('input') 144 | ->withArgument('output'); 145 | 146 | return $container; 147 | } 148 | 149 | public function injectParameters($container) 150 | { 151 | $parameterInjection = $container->get('parameterInjection'); 152 | $parameterInjection->register('AcquiaCli\Cli\CloudApi', new AcquiaCliInjector()); 153 | $parameterInjection->register('AcquiaCli\Cli\Config', new AcquiaCliInjector()); 154 | $parameterInjection->register('AcquiaLogstream\LogstreamManager', new AcquiaCliInjector()); 155 | $parameterInjection->register('AcquiaCloudApi\Connector\Client', new AcquiaCliInjector()); 156 | $parameterInjection->register('AcquiaCloudApi\Endpoints\Account', new AcquiaCliInjector()); 157 | $parameterInjection->register('AcquiaCloudApi\Endpoints\Applications', new AcquiaCliInjector()); 158 | $parameterInjection->register('AcquiaCloudApi\Endpoints\Code', new AcquiaCliInjector()); 159 | $parameterInjection->register('AcquiaCloudApi\Endpoints\Crons', new AcquiaCliInjector()); 160 | $parameterInjection->register('AcquiaCloudApi\Endpoints\DatabaseBackups', new AcquiaCliInjector()); 161 | $parameterInjection->register('AcquiaCloudApi\Endpoints\Databases', new AcquiaCliInjector()); 162 | $parameterInjection->register('AcquiaCloudApi\Endpoints\Domains', new AcquiaCliInjector()); 163 | $parameterInjection->register('AcquiaCloudApi\Endpoints\Environments', new AcquiaCliInjector()); 164 | $parameterInjection->register('AcquiaCloudApi\Endpoints\Ides', new AcquiaCliInjector()); 165 | $parameterInjection->register('AcquiaCloudApi\Endpoints\Insights', new AcquiaCliInjector()); 166 | $parameterInjection->register('AcquiaCloudApi\Endpoints\LogForwardingDestinations', new AcquiaCliInjector()); 167 | $parameterInjection->register('AcquiaCloudApi\Endpoints\Logs', new AcquiaCliInjector()); 168 | $parameterInjection->register('AcquiaCloudApi\Endpoints\Notifications', new AcquiaCliInjector()); 169 | $parameterInjection->register('AcquiaCloudApi\Endpoints\Organizations', new AcquiaCliInjector()); 170 | $parameterInjection->register('AcquiaCloudApi\Endpoints\Permissions', new AcquiaCliInjector()); 171 | $parameterInjection->register('AcquiaCloudApi\Endpoints\Roles', new AcquiaCliInjector()); 172 | $parameterInjection->register('AcquiaCloudApi\Endpoints\Servers', new AcquiaCliInjector()); 173 | $parameterInjection->register('AcquiaCloudApi\Endpoints\SslCertificates', new AcquiaCliInjector()); 174 | $parameterInjection->register('AcquiaCloudApi\Endpoints\Teams', new AcquiaCliInjector()); 175 | $parameterInjection->register('AcquiaCloudApi\Endpoints\Variables', new AcquiaCliInjector()); 176 | } 177 | 178 | /** 179 | * @param InputInterface $input 180 | * @param OutputInterface $output 181 | * @return int 182 | */ 183 | public function run(InputInterface $input, OutputInterface $output) 184 | { 185 | // Obtain a lock and exit if the command is already running. 186 | if (!$input->hasParameterOption('--no-lock') && !$this->lock('acquia-cli-command')) { 187 | $output->writeln('The command is already running in another process.'); 188 | 189 | return 0; 190 | } 191 | 192 | $statusCode = $this->runner->run($input, $output); 193 | 194 | // Specifically release the lock after successful command invocation. 195 | $this->release(); 196 | 197 | return $statusCode; 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /src/Cli/CloudApi.php: -------------------------------------------------------------------------------- 1 | config = $config; 32 | $this->setClient($client); 33 | } 34 | 35 | public static function createClient(Config $config) 36 | { 37 | 38 | $acquia = $config->get('acquia'); 39 | 40 | $connector = new Connector( 41 | [ 42 | 'key' => $acquia['key'], 43 | 'secret' => $acquia['secret'], 44 | ] 45 | ); 46 | /** 47 | * @var \AcquiaCloudApi\Connector\Client $cloudapi 48 | */ 49 | $client = Client::factory($connector); 50 | 51 | return $client; 52 | } 53 | 54 | /** 55 | * @param string $name 56 | * @return mixed 57 | * @throws \Exception 58 | */ 59 | public function getApplicationUuid($name) 60 | { 61 | $cacheId = sprintf('application.%s', str_replace(':', '.', $name)); 62 | 63 | $cache = new FilesystemAdapter('acquiacli'); 64 | $cache->deleteItem($cacheId); 65 | $return = $cache->get($cacheId, function (ItemInterface $item) { 66 | $count = -1; 67 | $name = str_replace('application:', '', str_replace('.', ':', $item->getKey())); 68 | 69 | $app = new Applications($this->client); 70 | $applications = $app->getAll(); 71 | 72 | foreach ($applications as $application) { 73 | if ($name === $application->hosting->id) { 74 | return $application->uuid; 75 | } 76 | } 77 | throw new \Exception('Unable to find UUID for application'); 78 | }); 79 | 80 | return $return; 81 | } 82 | 83 | /** 84 | * @param string $uuid 85 | * @param string $environment 86 | * @return EnvironmentResponse 87 | * @throws \Exception 88 | */ 89 | public function getEnvironment($uuid, $environment) 90 | { 91 | $cacheId = sprintf('environment.%s.%s', $uuid, $environment); 92 | 93 | $cache = new FilesystemAdapter('acquiacli'); 94 | $return = $cache->get($cacheId, function (ItemInterface $item) { 95 | $split = explode('.', $item->getKey()); 96 | $uuid = $split[1]; 97 | $environment = $split[2]; 98 | 99 | $environmentsAdapter = new Environments($this->client); 100 | $environments = $environmentsAdapter->getAll($uuid); 101 | 102 | foreach ($environments as $e) { 103 | if ($environment === $e->name) { 104 | return $e; 105 | } 106 | } 107 | 108 | throw new \Exception('Unable to find environment from environment name'); 109 | }); 110 | 111 | return $return; 112 | } 113 | 114 | /** 115 | * @param string $organizationName 116 | * @return OrganizationResponse 117 | * @throws \Exception 118 | */ 119 | public function getOrganization($organizationName) 120 | { 121 | $org = new Organizations($this->client); 122 | $organizations = $org->getAll(); 123 | 124 | foreach ($organizations as $organization) { 125 | if ($organizationName === $organization->name) { 126 | return $organization; 127 | } 128 | } 129 | 130 | throw new \Exception('Unable to find organization from organization name'); 131 | } 132 | 133 | public function getClient() 134 | { 135 | if (!$this->client) { 136 | $client = self::createClient($this->config); 137 | $this->setClient($client); 138 | } 139 | return $this->client; 140 | } 141 | 142 | public function setClient($client) 143 | { 144 | $this->client = $client; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/Cli/Config.php: -------------------------------------------------------------------------------- 1 | extend($loader->load($defaultConfig)); 50 | $processor->extend($loader->load($globalConfig)); 51 | $processor->extend($loader->load($projectConfig)); 52 | $processor->add($environment); 53 | 54 | $this->import($processor->export()); 55 | $this->set('config.default', $defaultConfig); 56 | $this->set('config.global', $globalConfig); 57 | $this->set('config.project', $projectConfig); 58 | $this->set('config.environment', $environment); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Commands/AccountCommand.php: -------------------------------------------------------------------------------- 1 | get('extraconfig'); 25 | $tz = $extraConfig['timezone']; 26 | $format = $extraConfig['format']; 27 | $timezone = new \DateTimeZone($tz); 28 | 29 | $account = $accountAdapter->get(); 30 | 31 | $lastLogin = new \DateTime($account->last_login_at); 32 | $lastLogin->setTimezone($timezone); 33 | $createdAt = new \DateTime($account->created_at); 34 | $createdAt->setTimezone($timezone); 35 | 36 | $this->say(sprintf('Name: %s', $account->name)); 37 | $this->say(sprintf('Last login: %s', $lastLogin->format($format))); 38 | $this->say(sprintf('Created at: %s', $createdAt->format($format))); 39 | $this->say(sprintf('Status: %s', $account->flags->active ? '✓' : ' ')); 40 | $this->say(sprintf('TFA: %s', $account->flags->tfa ? '✓' : ' ')); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Commands/ApplicationsCommand.php: -------------------------------------------------------------------------------- 1 | getAll(); 31 | 32 | $output = $this->output(); 33 | $table = new Table($output); 34 | $table->setHeaders(['Name', 'UUID', 'Hosting ID']); 35 | foreach ($applications as $application) { 36 | $table 37 | ->addRows( 38 | [ 39 | [ 40 | $application->name, 41 | $application->uuid, 42 | $application->hosting->id, 43 | ], 44 | ] 45 | ); 46 | } 47 | $table->render(); 48 | } 49 | 50 | /** 51 | * Shows detailed information about a site. 52 | * 53 | * @param string $uuid 54 | * 55 | * @command application:info 56 | * @aliases app:info,a:i 57 | */ 58 | public function applicationInfo( 59 | OutputInterface $output, 60 | Environments $environmentsAdapter, 61 | Databases $databasesAdapter, 62 | $uuid 63 | ) { 64 | $environments = $environmentsAdapter->getAll($uuid); 65 | 66 | $table = new Table($output); 67 | $table->setHeaders(['Environment', 'ID', 'Branch/Tag', 'Domain(s)', 'Database(s)']); 68 | 69 | $databases = $databasesAdapter->getAll($uuid); 70 | 71 | $dbNames = array_map( 72 | function ($database) { 73 | return $database->name; 74 | }, 75 | $databases->getArrayCopy() 76 | ); 77 | 78 | foreach ($environments as $environment) { 79 | /** 80 | * @var EnvironmentResponse $environment 81 | */ 82 | 83 | $environmentName = sprintf('%s (%s)', $environment->label, $environment->name); 84 | if ($environment->flags->livedev) { 85 | $environmentName = sprintf('💻 %s', $environmentName); 86 | } 87 | 88 | if ($environment->flags->production_mode) { 89 | $environmentName = sprintf('🔒 %s', $environmentName); 90 | } 91 | 92 | $table 93 | ->addRows( 94 | [ 95 | [ 96 | $environmentName, 97 | $environment->uuid, 98 | $environment->vcs->path, 99 | implode("\n", $environment->domains), 100 | implode("\n", $dbNames) 101 | ], 102 | ] 103 | ); 104 | } 105 | $table->render(); 106 | 107 | if (isset($environment->vcs->url)) { 108 | $this->say(sprintf('🔧 Git URL: %s', $environment->vcs->url)); 109 | } 110 | $this->say('💻 indicates environment in livedev mode.'); 111 | $this->say('🔒 indicates environment in production mode.'); 112 | } 113 | 114 | /** 115 | * Shows a list of all tags on an application. 116 | * 117 | * @param string $uuid 118 | * 119 | * @command application:tags 120 | * @aliases app:tags 121 | */ 122 | public function applicationsTags(OutputInterface $output, Applications $applicationsAdapter, $uuid) 123 | { 124 | $tags = $applicationsAdapter->getAllTags($uuid); 125 | 126 | $table = new Table($output); 127 | $table->setHeaders(['Name', 'Color']); 128 | foreach ($tags as $tag) { 129 | $table 130 | ->addRows( 131 | [ 132 | [ 133 | $tag->name, 134 | $tag->color, 135 | ], 136 | ] 137 | ); 138 | } 139 | $table->render(); 140 | } 141 | 142 | /** 143 | * Creates an application tag. 144 | * 145 | * @param string $uuid 146 | * @param string $name 147 | * @param string $color 148 | * 149 | * @command application:tag:create 150 | * @aliases app:tag:create 151 | */ 152 | public function applicationTagCreate(Applications $applicationsAdapter, $uuid, $name, $color) 153 | { 154 | $this->say(sprintf('Creating application tag %s:%s', $name, $color)); 155 | $response = $applicationsAdapter->createTag($uuid, $name, $color); 156 | $this->waitForNotification($response); 157 | } 158 | 159 | /** 160 | * Deletes an application tag. 161 | * 162 | * @param string $uuid 163 | * @param string $name 164 | * 165 | * @command application:tag:delete 166 | * @aliases app:tag:delete 167 | */ 168 | public function applicationTagDelete(Applications $applicationsAdapter, $uuid, $name) 169 | { 170 | $this->say(sprintf('Deleting application tag %s', $name)); 171 | $response = $applicationsAdapter->deleteTag($uuid, $name); 172 | $this->waitForNotification($response); 173 | } 174 | 175 | /** 176 | * Renames an application. 177 | * 178 | * @param string $uuid 179 | * @param string $name 180 | * 181 | * @command application:rename 182 | * @aliases app:rename,a:rename 183 | */ 184 | public function applicationRename(Applications $applicationsAdapter, $uuid, $name) 185 | { 186 | $this->say(sprintf('Renaming application to %s', $name)); 187 | $environments = $applicationsAdapter->rename($uuid, $name); 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /src/Commands/CacheClearCommand.php: -------------------------------------------------------------------------------- 1 | clear()) { 32 | return $this->say('AcquiaCli cache has been cleared'); 33 | } 34 | 35 | throw new Exception('Problem clearing AcquiaCli cache.'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Commands/CodeCommand.php: -------------------------------------------------------------------------------- 1 | getAll($uuid); 31 | $client->clearQuery(); 32 | 33 | $output = $this->output(); 34 | $table = new Table($output); 35 | $table->setHeaders(['Name', 'Tag']); 36 | 37 | foreach ($branches as $branch) { 38 | /** 39 | * @var BranchResponse $branch 40 | */ 41 | $tag = $branch->flags->tag ? '✓' : ''; 42 | $table 43 | ->addRows( 44 | [ 45 | [ 46 | $branch->name, 47 | $tag, 48 | ], 49 | ] 50 | ); 51 | } 52 | 53 | $table->render(); 54 | } 55 | 56 | /** 57 | * Deploys code from one environment to another. 58 | * 59 | * @param string $uuid 60 | * @param string $environmentFrom 61 | * @param string $environmentTo 62 | * 63 | * @command code:deploy 64 | * @option no-backup Do not backup the database(s) prior to deploying code. 65 | * @aliases c:d 66 | */ 67 | public function codeDeploy( 68 | Code $codeAdapter, 69 | $uuid, 70 | $environmentFrom, 71 | $environmentTo, 72 | $options = ['no-backup'] 73 | ) { 74 | $environmentFrom = $this->cloudapiService->getEnvironment($uuid, $environmentFrom); 75 | $environmentTo = $this->cloudapiService->getEnvironment($uuid, $environmentTo); 76 | 77 | if ( 78 | !$this->confirm( 79 | sprintf( 80 | 'Are you sure you want to deploy code from %s to %s?', 81 | $environmentFrom->label, 82 | $environmentTo->label 83 | ) 84 | ) 85 | ) { 86 | return; 87 | } 88 | 89 | if (!$options['no-backup']) { 90 | $this->backupAllEnvironmentDbs($uuid, $environmentTo); 91 | } 92 | 93 | $this->say( 94 | sprintf( 95 | 'Deploying code from the %s environment to the %s environment', 96 | $environmentFrom->label, 97 | $environmentTo->label 98 | ) 99 | ); 100 | 101 | $response = $codeAdapter->deploy($environmentFrom->uuid, $environmentTo->uuid); 102 | $this->waitForNotification($response); 103 | } 104 | 105 | /** 106 | * Switches code branch on an environment. 107 | * 108 | * @param string $uuid 109 | * @param string $environment 110 | * @param string $branch 111 | * 112 | * @command code:switch 113 | * @option no-backup Do not backup the database(s) prior to switching code. 114 | * @aliases c:s 115 | */ 116 | public function codeSwitch( 117 | CloudApi $cloudapi, 118 | Code $codeAdapter, 119 | $uuid, 120 | $environment, 121 | $branch, 122 | $options = ['no-backup'] 123 | ) { 124 | $environment = $cloudapi->getEnvironment($uuid, $environment); 125 | 126 | if ( 127 | !$this->confirm( 128 | sprintf( 129 | 'Are you sure you want to switch code on the %s environment to branch: %s?', 130 | $environment->name, 131 | $branch 132 | ) 133 | ) 134 | ) { 135 | return; 136 | } 137 | 138 | if (!$options['no-backup']) { 139 | $this->backupAllEnvironmentDbs($uuid, $environment); 140 | } 141 | 142 | $this->say(sprintf('Switching %s enviroment to %s branch', $environment->label, $branch)); 143 | 144 | $response = $codeAdapter->switch($environment->uuid, $branch); 145 | $this->waitForNotification($response); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/Commands/CronCommand.php: -------------------------------------------------------------------------------- 1 | cloudapiService->getEnvironment($uuid, $environment); 29 | 30 | $crons = $cronAdapter->getAll($environment->uuid); 31 | 32 | $output = $this->output(); 33 | $table = new Table($output); 34 | $table->setHeaders(['ID', 'Command', 'Frequency']); 35 | 36 | foreach ($crons as $cron) { 37 | $frequency = $this->convertCronFrequencyToCrontab($cron); 38 | 39 | $table 40 | ->addRows( 41 | [ 42 | [ 43 | $cron->id, 44 | $cron->command, 45 | $frequency, 46 | ], 47 | ] 48 | ); 49 | } 50 | 51 | $table->render(); 52 | $this->say('Cron commands starting with "#" are disabled.'); 53 | } 54 | 55 | /** 56 | * Adds a new cron task for an environment. 57 | * 58 | * @param string $uuid 59 | * @param string $environment 60 | * @param string $commandString The command to be run on cron wrapped in quotes. 61 | * @param string $frequency The crontab format frequency wrapped in quotes 62 | * @param string $label An optional label for the cron command wrapped in quotes. 63 | * 64 | * @command cron:create 65 | * @aliases cron:add 66 | */ 67 | public function cronAdd(Crons $cronAdapter, $uuid, $environment, $commandString, $frequency, $label) 68 | { 69 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 70 | $this->say(sprintf('Adding new cron task on %s environment', $environment->name)); 71 | $response = $cronAdapter->create($environment->uuid, $commandString, $frequency, $label); 72 | $this->waitForNotification($response); 73 | } 74 | 75 | /** 76 | * Removes a cron task for an environment. 77 | * 78 | * @param string $uuid 79 | * @param string $environment 80 | * @param int $cronId 81 | * 82 | * @command cron:delete 83 | * @aliases cron:remove 84 | */ 85 | public function cronDelete(Crons $cronAdapter, $uuid, $environment, $cronId) 86 | { 87 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 88 | if ($this->confirm("Are you sure you want to delete the cron task?")) { 89 | $this->say(sprintf('Deleting cron task %s from %s', $cronId, $environment->label)); 90 | $response = $cronAdapter->delete($environment->uuid, $cronId); 91 | $this->waitForNotification($response); 92 | } 93 | } 94 | 95 | /** 96 | * Enables a disabled cron entry. 97 | * 98 | * @param string $uuid 99 | * @param string $environment 100 | * @param int $cronId 101 | * 102 | * @command cron:enable 103 | */ 104 | public function cronEnable(Crons $cronAdapter, $uuid, $environment, $cronId) 105 | { 106 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 107 | $this->say(sprintf('Enabling cron task %s on %s environment', $cronId, $environment->name)); 108 | $response = $cronAdapter->enable($environment->uuid, $cronId); 109 | $this->waitForNotification($response); 110 | } 111 | 112 | /** 113 | * Disables an enabled cron entry. 114 | * 115 | * @param string $uuid 116 | * @param string $environment 117 | * @param int $cronId 118 | * 119 | * @command cron:disable 120 | */ 121 | public function cronDisable(Crons $cronAdapter, $uuid, $environment, $cronId) 122 | { 123 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 124 | if ($this->confirm("Are you sure you want to disable the cron task?")) { 125 | $this->say(sprintf('Disabling cron task %s on %s environment', $cronId, $environment->name)); 126 | $response = $cronAdapter->disable($environment->uuid, $cronId); 127 | $this->waitForNotification($response); 128 | } 129 | } 130 | 131 | /** 132 | * Shows detailed information about a single cron command. 133 | * 134 | * @param string $uuid 135 | * @param string $environment 136 | * @param int $cronId 137 | * 138 | * @command cron:info 139 | */ 140 | public function cronInfo(Crons $cronAdapter, $uuid, $environment, $cronId) 141 | { 142 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 143 | $cron = $cronAdapter->get($environment->uuid, $cronId); 144 | 145 | $enabled = $cron->flags->enabled ? '✓' : ' '; 146 | $system = $cron->flags->system ? '✓' : ' '; 147 | $onAnyWeb = $cron->flags->on_any_web ? '✓' : ' '; 148 | 149 | $this->say(sprintf('ID: %s', $cron->id)); 150 | $this->say(sprintf('Label: %s', $cron->label)); 151 | $this->say(sprintf('Environment: %s', $cron->environment->name)); 152 | $this->say(sprintf('Command: %s', $cron->command)); 153 | $this->say(sprintf('Frequency: %s', $this->convertCronFrequencyToCrontab($cron))); 154 | $this->say(sprintf('Enabled: %s', $enabled)); 155 | $this->say(sprintf('System: %s', $system)); 156 | $this->say(sprintf('On any web: %s', $onAnyWeb)); 157 | } 158 | 159 | protected function convertCronFrequencyToCrontab(CronResponse $cron) 160 | { 161 | $frequency = [ 162 | $cron->minute, 163 | $cron->hour, 164 | $cron->dayMonth, 165 | $cron->month, 166 | $cron->dayWeek, 167 | ]; 168 | 169 | return implode(' ', $frequency); 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /src/Commands/DbCommand.php: -------------------------------------------------------------------------------- 1 | getAll($uuid); 33 | $table = new Table($this->output()); 34 | $table->setHeaders(['Databases']); 35 | foreach ($databases as $database) { 36 | $table 37 | ->addRows( 38 | [ 39 | [ 40 | $database->name, 41 | ] 42 | ] 43 | ); 44 | } 45 | $table->render(); 46 | } 47 | 48 | /** 49 | * Creates a database. 50 | * 51 | * @param string $uuid 52 | * @param string $dbName 53 | * 54 | * @command database:create 55 | * @aliases database:add,db:create,db:add 56 | */ 57 | public function dbCreate(Databases $databaseAdapter, $uuid, $dbName) 58 | { 59 | $response = $databaseAdapter->create($uuid, $dbName); 60 | $this->say(sprintf('Creating database (%s)', $dbName)); 61 | $this->waitForNotification($response); 62 | } 63 | 64 | /** 65 | * Deletes a database. 66 | * 67 | * @param string $uuid 68 | * @param string $dbName 69 | * 70 | * @command database:delete 71 | * @aliases database:remove,db:remove,db:delete 72 | */ 73 | public function dbDelete(Databases $databaseAdapter, $uuid, $dbName) 74 | { 75 | if ($this->confirm('Are you sure you want to delete this database?')) { 76 | $this->say(sprintf('Deleting database (%s)', $dbName)); 77 | $response = $databaseAdapter->delete($uuid, $dbName); 78 | $this->waitForNotification($response); 79 | } 80 | } 81 | 82 | /** 83 | * Truncates a database (only applicable to Acquia free tier). 84 | * 85 | * @param string $uuid 86 | * @param string $dbName 87 | * 88 | * @command database:truncate 89 | * @aliases db:truncate 90 | */ 91 | public function dbTruncate(Databases $databaseAdapter, $uuid, $dbName) 92 | { 93 | if ($this->confirm('Are you sure you want to truncate this database?')) { 94 | $this->say(sprintf('Truncate database (%s)', $dbName)); 95 | $response = $databaseAdapter->truncate($uuid, $dbName); 96 | $this->waitForNotification($response); 97 | } 98 | } 99 | 100 | /** 101 | * Copies a database from one environment to another. 102 | * 103 | * @param string $uuid 104 | * @param string $environmentFrom 105 | * @param string $environmentTo 106 | * @param string $dbName 107 | * 108 | * @command database:copy 109 | * @option no-backup Do not backup the databases on production. 110 | * @aliases db:copy 111 | */ 112 | public function dbCopy( 113 | $uuid, 114 | $environmentFrom, 115 | $environmentTo, 116 | $dbName, 117 | $options = ['no-backup'] 118 | ) { 119 | $environmentFrom = $this->cloudapiService->getEnvironment($uuid, $environmentFrom); 120 | $environmentTo = $this->cloudapiService->getEnvironment($uuid, $environmentTo); 121 | 122 | if ( 123 | $this->confirm( 124 | sprintf( 125 | 'Are you sure you want to copy database %s from %s to %s?', 126 | $dbName, 127 | $environmentFrom->label, 128 | $environmentTo->label 129 | ) 130 | ) 131 | ) { 132 | if (!$options['no-backup']) { 133 | $this->moveDbs($uuid, $environmentFrom, $environmentTo, $dbName); 134 | } else { 135 | $this->moveDbs($uuid, $environmentFrom, $environmentTo, $dbName, false); 136 | } 137 | } 138 | } 139 | 140 | /** 141 | * Copies all DBs from one environment to another environment. 142 | * 143 | * @param string $uuid 144 | * @param string $environmentFrom 145 | * @param string $environmentTo 146 | * 147 | * @command database:copy:all 148 | * @option no-backup Do not backup the databases on production. 149 | * @aliases db:copy:all 150 | */ 151 | public function dbCopyAll( 152 | $uuid, 153 | $environmentFrom, 154 | $environmentTo, 155 | $options = ['no-backup'] 156 | ) { 157 | $environmentFrom = $this->cloudapiService->getEnvironment($uuid, $environmentFrom); 158 | $environmentTo = $this->cloudapiService->getEnvironment($uuid, $environmentTo); 159 | 160 | if ( 161 | $this->confirm( 162 | sprintf( 163 | 'Are you sure you want to copy all databases from %s to %s?', 164 | $environmentFrom->label, 165 | $environmentTo->label 166 | ) 167 | ) 168 | ) { 169 | if (!$options['no-backup']) { 170 | $this->moveDbs($uuid, $environmentFrom, $environmentTo); 171 | } else { 172 | $this->moveDbs($uuid, $environmentFrom, $environmentTo, null, false); 173 | } 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/Commands/DeployCommand.php: -------------------------------------------------------------------------------- 1 | cloudapiService->getEnvironment($uuid, 'prod'); 32 | } else { 33 | $environmentFrom = $this->cloudapiService->getEnvironment($uuid, $environmentFrom); 34 | } 35 | 36 | $environmentTo = $this->cloudapiService->getEnvironment($uuid, $environmentTo); 37 | 38 | $this->moveDbs($uuid, $environmentFrom, $environmentTo); 39 | $this->copyFiles($uuid, $environmentFrom, $environmentTo); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Commands/DomainCommand.php: -------------------------------------------------------------------------------- 1 | cloudapiService->getEnvironment($uuid, $environment); 29 | $domains = $domainAdapter->getAll($environment->uuid); 30 | 31 | $table = new Table($output); 32 | $table->setHeaders(['Hostname', 'Default', 'Active', 'Uptime']); 33 | $table->setColumnStyle(1, 'center-align'); 34 | $table->setColumnStyle(2, 'center-align'); 35 | $table->setColumnStyle(3, 'center-align'); 36 | 37 | foreach ($domains as $domain) { 38 | /** 39 | * @var DomainResponse $domain 40 | */ 41 | $table 42 | ->addRows( 43 | [ 44 | [ 45 | $domain->hostname, 46 | $domain->flags->default ? '✓' : '', 47 | $domain->flags->active ? '✓' : '', 48 | $domain->flags->uptime ? '✓' : '', 49 | ], 50 | ] 51 | ); 52 | } 53 | 54 | $table->render(); 55 | } 56 | 57 | /** 58 | * Gets information about a domain. 59 | * 60 | * @param string $uuid 61 | * @param string $environment 62 | * @param string $domain 63 | * 64 | * @command domain:info 65 | */ 66 | public function domainInfo(OutputInterface $output, Domains $domainAdapter, $uuid, $environment, $domain) 67 | { 68 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 69 | $domain = $domainAdapter->status($environment->uuid, $domain); 70 | 71 | $table = new Table($output); 72 | $table->setHeaders(['Hostname', 'Active', 'DNS Resolves', 'IP Addresses', 'CNAMES']); 73 | $table->setColumnStyle(1, 'center-align'); 74 | $table->setColumnStyle(2, 'center-align'); 75 | $table 76 | ->addRows( 77 | [ 78 | [ 79 | $domain->hostname, 80 | $domain->flags->active ? '✓' : '', 81 | $domain->flags->dns_resolves ? '✓' : '', 82 | implode("\n", $domain->ip_addresses), 83 | implode("\n", $domain->cnames), 84 | ], 85 | ] 86 | ); 87 | 88 | $table->render(); 89 | } 90 | 91 | /** 92 | * Add a domain to an environment. 93 | * 94 | * @param string $uuid 95 | * @param string $environment 96 | * @param string $domain 97 | * 98 | * @command domain:create 99 | * @aliases domain:add 100 | */ 101 | public function domainCreate(Domains $domainAdapter, $uuid, $environment, $domain) 102 | { 103 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 104 | $this->say(sprintf('Adding %s to environment %s', $domain, $environment->label)); 105 | $response = $domainAdapter->create($environment->uuid, $domain); 106 | $this->waitForNotification($response); 107 | } 108 | 109 | /** 110 | * Remove a domain to an environment. 111 | * 112 | * @param string $uuid 113 | * @param string $environment 114 | * @param string $domain 115 | * 116 | * @command domain:delete 117 | * @aliases domain:remove 118 | */ 119 | public function domainDelete(Domains $domainAdapter, $uuid, $environment, $domain) 120 | { 121 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 122 | if ($this->confirm('Are you sure you want to remove this domain?')) { 123 | $this->say(sprintf('Removing %s from environment %s', $domain, $environment->label)); 124 | $response = $domainAdapter->delete($environment->uuid, $domain); 125 | $this->waitForNotification($response); 126 | } 127 | } 128 | 129 | /** 130 | * Move a domain from one environment to another. 131 | * 132 | * @param string $uuid 133 | * @param string $domain 134 | * @param string $environmentFrom 135 | * @param string $environmentTo 136 | * 137 | * @command domain:move 138 | */ 139 | public function domainMove(Domains $domainAdapter, $uuid, $domain, $environmentFrom, $environmentTo) 140 | { 141 | $environmentFrom = $this->cloudapiService->getEnvironment($uuid, $environmentFrom); 142 | $environmentTo = $this->cloudapiService->getEnvironment($uuid, $environmentTo); 143 | 144 | if ( 145 | $this->confirm( 146 | sprintf( 147 | 'Are you sure you want to move %s from environment %s to %s?', 148 | $domain, 149 | $environmentFrom->label, 150 | $environmentTo->label 151 | ) 152 | ) 153 | ) { 154 | $this->say(sprintf('Moving %s from %s to %s', $domain, $environmentFrom->label, $environmentTo->label)); 155 | 156 | $deleteResponse = $domainAdapter->delete($environmentFrom->uuid, $domain); 157 | $this->waitForNotification($deleteResponse); 158 | 159 | $addResponse = $domainAdapter->create($environmentTo->uuid, $domain); 160 | $this->waitForNotification($addResponse); 161 | } 162 | } 163 | 164 | /** 165 | * Clears varnish cache for a specific domain. 166 | * 167 | * @param string $uuid 168 | * 169 | * @command domain:purge 170 | */ 171 | public function domainPurge(Domains $domainAdapter, $uuid, $environment, $domain = null) 172 | { 173 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 174 | 175 | if ( 176 | $environment->name === 'prod' 177 | && !$this->confirm("Are you sure you want to purge varnish on the production environment?") 178 | ) { 179 | return; 180 | } 181 | 182 | if (null === $domain) { 183 | $domains = $domainAdapter->getAll($environment->uuid); 184 | $domainNames = array_map( 185 | function ($domain) { 186 | $this->say(sprintf('Purging domain: %s', $domain->hostname)); 187 | return $domain->hostname; 188 | }, 189 | $domains->getArrayCopy() 190 | ); 191 | } else { 192 | $this->say(sprintf('Purging domain: %s', $domain)); 193 | $domainNames = [$domain]; 194 | } 195 | 196 | $response = $domainAdapter->purge($environment->uuid, $domainNames); 197 | $this->waitForNotification($response); 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /src/Commands/DrushAliasesCommand.php: -------------------------------------------------------------------------------- 1 | false]) 24 | { 25 | $aliases = $accountAdapter->getDrushAliases(); 26 | $drushArchive = tempnam(sys_get_temp_dir(), 'AcquiaDrushAliases') . '.tar.gz'; 27 | $this->say(sprintf('Acquia Cloud Drush Aliases archive downloaded to %s', $drushArchive)); 28 | $home = Path::getHomeDirectory(); 29 | if (file_put_contents($drushArchive, $aliases, LOCK_EX)) { 30 | if ( 31 | $options['install'] || $this->confirm( 32 | sprintf( 33 | 'Do you want to automatically unpack Acquia Cloud Drush aliases to %s', 34 | $home 35 | ) 36 | ) 37 | ) { 38 | $drushDirectory = join(\DIRECTORY_SEPARATOR, [$home, '.drush']); 39 | if (!is_dir($drushDirectory)) { 40 | mkdir($drushDirectory, 0700); 41 | } 42 | if (!is_writeable($drushDirectory)) { 43 | chmod($drushDirectory, 0700); 44 | } 45 | $archive = new \PharData($drushArchive . '/.drush'); 46 | $drushFiles = []; 47 | foreach (new \RecursiveIteratorIterator($archive, \RecursiveIteratorIterator::LEAVES_ONLY) as $file) { 48 | $drushFiles[] = '.drush/' . $file->getFileName(); 49 | } 50 | 51 | $archive->extractTo($home, $drushFiles, true); 52 | $this->say(sprintf('Acquia Cloud Drush aliases installed into %s', $drushDirectory)); 53 | unlink($drushArchive); 54 | } else { 55 | $this->say('Run the following command to install Drush aliases on Linux/Mac:'); 56 | $this->writeln(sprintf('$ tar -C $HOME -xf %s', $drushArchive)); 57 | $this->yell( 58 | 'This command will unpack into ~/.acquia and ~/.drush potentially overwriting existing files!', 59 | 40, 60 | 'yellow' 61 | ); 62 | } 63 | } else { 64 | $this->say('Unable to download Drush Aliases'); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Commands/EnvironmentsCommand.php: -------------------------------------------------------------------------------- 1 | getAll($uuid); 32 | 33 | $table = new Table($output); 34 | $table->setHeaders( 35 | [ 36 | 'UUID', 37 | 'Name', 38 | 'Label', 39 | 'Domains', 40 | ] 41 | ); 42 | 43 | foreach ($environments as $environment) { 44 | /** 45 | * @var EnvironmentResponse $environment 46 | */ 47 | $table->addRows( 48 | [ 49 | [ 50 | $environment->uuid, 51 | $environment->name, 52 | $environment->label, 53 | implode("\n", $environment->domains), 54 | ], 55 | ] 56 | ); 57 | } 58 | 59 | $table->render(); 60 | } 61 | 62 | /** 63 | * Shows detailed information about servers in an environment. 64 | * 65 | * @param string $uuid 66 | * @param string|null $env 67 | * 68 | * @command environment:info 69 | * @aliases env:info,e:i 70 | */ 71 | public function environmentInfo( 72 | Client $client, 73 | Environments $environmentsAdapter, 74 | Servers $serversAdapter, 75 | $uuid, 76 | $env = null 77 | ) { 78 | 79 | if (null !== $env) { 80 | $client->addQuery('filter', "name=${env}"); 81 | } 82 | 83 | $environments = $environmentsAdapter->getAll($uuid); 84 | 85 | $client->clearQuery(); 86 | 87 | foreach ($environments as $e) { 88 | $this->renderEnvironmentInfo($e, $serversAdapter); 89 | } 90 | 91 | $this->say("Web servers not marked 'Active' are out of rotation."); 92 | $this->say("Load balancer servers not marked 'Active' are hot spares"); 93 | $this->say("Database servers not marked 'Primary' are the passive master"); 94 | } 95 | 96 | /** 97 | * @param EnvironmentResponse $environment 98 | */ 99 | protected function renderEnvironmentInfo(EnvironmentResponse $environment, Servers $serversAdapter) 100 | { 101 | 102 | $this->yell(sprintf('%s environment', $environment->label)); 103 | $this->say(sprintf('Environment ID: %s', $environment->uuid)); 104 | if ($environment->flags->livedev) { 105 | $this->say('💻 Livedev mode enabled.'); 106 | } 107 | if ($environment->flags->production_mode) { 108 | $this->say('🔒 Production mode enabled.'); 109 | } 110 | 111 | $output = $this->output(); 112 | 113 | if (!$environment->flags->cde) { 114 | $serverTable = new Table($output); 115 | // needs AZ? 116 | $serverTable->setHeaders( 117 | [ 118 | 'Role(s)', 119 | 'Name', 120 | 'FQDN', 121 | 'AMI', 122 | 'Region', 123 | 'IP', 124 | 'Memcache', 125 | 'Active', 126 | 'Primary', 127 | 'EIP' 128 | ] 129 | ); 130 | 131 | $servers = $serversAdapter->getAll($environment->uuid); 132 | 133 | foreach ($servers as $server) { 134 | $memcache = $server->flags->memcache ? '✓' : ' '; 135 | $active = $server->flags->active_web || $server->flags->active_bal ? '✓' : ' '; 136 | $primaryDb = $server->flags->primary_db ? '✓' : ' '; 137 | $eip = $server->flags->elastic_ip ? '✓' : ' '; 138 | 139 | $serverTable 140 | ->addRows( 141 | [ 142 | [ 143 | implode(', ', $server->roles), 144 | $server->name, 145 | $server->hostname, 146 | $server->amiType, 147 | $server->region, 148 | $server->ip, 149 | $memcache, 150 | $active, 151 | $primaryDb, 152 | $eip 153 | ], 154 | ] 155 | ); 156 | } 157 | $serverTable->render(); 158 | } 159 | 160 | $environmentTable = new Table($output); 161 | $environmentTable->setHeaders( 162 | [ 163 | 'Branch', 164 | 'CDE', 165 | 'PHP Version', 166 | 'Memory Limit', 167 | 'OpCache', 168 | 'APCu', 169 | 'Sendmail Path' 170 | ] 171 | ); 172 | 173 | if (!isset($environment->configuration->php)) { 174 | $environment->configuration = new \stdClass(); 175 | $environment->configuration->php = new \stdClass(); 176 | $environment->configuration->php->version = ' '; 177 | $environment->configuration->php->memory_limit = ' '; 178 | $environment->configuration->php->opcache = ' '; 179 | $environment->configuration->php->apcu = ' '; 180 | $environment->configuration->php->sendmail_path = ' '; 181 | } 182 | $environmentTable 183 | ->addRows( 184 | [ 185 | [ 186 | $environment->vcs->path, 187 | $environment->flags->cde ? $environment->name : ' ', 188 | $environment->configuration->php->version, 189 | $environment->configuration->php->memory_limit, 190 | $environment->configuration->php->opcache, 191 | $environment->configuration->php->apcu, 192 | $environment->configuration->php->sendmail_path 193 | ], 194 | ] 195 | ); 196 | $environmentTable->render(); 197 | } 198 | 199 | /** 200 | * Shows the branch an environment is currently on. 201 | * 202 | * @param string $uuid 203 | * @param string $environment 204 | * 205 | * @command environment:branch 206 | * @aliases env:branch,e:b 207 | */ 208 | public function environmentBranch(Environments $environmentsAdapter, $uuid, $environment) 209 | { 210 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 211 | $this->say($environment->vcs->path); 212 | } 213 | 214 | /** 215 | * Renames an environment. 216 | * 217 | * @param string $uuid 218 | * @param string $environment 219 | * @param string $name 220 | * 221 | * @command environment:rename 222 | * @aliases env:rename,e:rename 223 | */ 224 | public function environmentRename(Environments $environmentsAdapter, $uuid, $environment, $name) 225 | { 226 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 227 | $this->say(sprintf('Renaming %s to %s', $environment->label, $name)); 228 | $environments = $environmentsAdapter->rename($environment->uuid, $name); 229 | } 230 | 231 | /** 232 | * Deletes an environment. 233 | * 234 | * @param string $uuid 235 | * @param string $environment 236 | * 237 | * @command environment:delete 238 | * @aliases env:delete,e:d,environment:remove,env:remove 239 | */ 240 | public function environmentDelete(Environments $environmentsAdapter, $uuid, $environment) 241 | { 242 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 243 | if ($this->confirm(sprintf('Are you sure you want to delete the %s environment?', $environment->label))) { 244 | $this->say(sprintf('Deleting %s environment', $environment->label)); 245 | $response = $environmentsAdapter->delete($environment->uuid); 246 | $this->waitForNotification($response); 247 | } 248 | } 249 | 250 | /** 251 | * Configures an environment. 252 | * 253 | * Allowed values for configuration update are: 254 | * version: The PHP version. 255 | * max_execution_time: The maximum execution time for PHP scripts. 256 | * memory_limit: The PHP memory limit. 257 | * apcu: The APCu memory limit. 258 | * max_input_vars: The maximum number of input variables. 259 | * max_post_size: The maximum POST size. 260 | * sendmail_path: The path and any options required for sendmail. 261 | * 262 | * @param string $uuid 263 | * @param string $environment 264 | * @param string $key 265 | * @param string $value 266 | * 267 | * @command environment:configure 268 | * @aliases env:config,e:c,environment:config 269 | */ 270 | public function environmentConfigure(Environments $environmentsAdapter, $uuid, $environment, $key, $value) 271 | { 272 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 273 | if ($this->confirm(sprintf('Are you sure you want to update the %s environment with [%s => %s]?', $environment->label, $key, $value))) { 274 | $this->say(sprintf('Configuring %s with [%s => %s]', $environment->label, $key, $value)); 275 | $environmentsAdapter->update($environment->uuid, [$key => $value]); 276 | } 277 | } 278 | } 279 | -------------------------------------------------------------------------------- /src/Commands/FilesCommand.php: -------------------------------------------------------------------------------- 1 | cloudapiService->getEnvironment($uuid, $environmentFrom); 28 | $environmentTo = $this->cloudapiService->getEnvironment($uuid, $environmentTo); 29 | 30 | if ( 31 | $this->confirm( 32 | sprintf( 33 | 'Are you sure you want to copy files from %s to %s?', 34 | $environmentFrom->label, 35 | $environmentTo->label 36 | ) 37 | ) 38 | ) { 39 | $this->copyFiles($uuid, $environmentFrom, $environmentTo); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Commands/IdesCommand.php: -------------------------------------------------------------------------------- 1 | getAll($uuid); 29 | $table = new Table($this->output()); 30 | $table->setHeaders(['UUID', 'Label']); 31 | foreach ($ides as $ide) { 32 | $table 33 | ->addRows( 34 | [ 35 | [ 36 | $ide->uuid, 37 | $ide->label, 38 | ] 39 | ] 40 | ); 41 | } 42 | $table->render(); 43 | } 44 | 45 | /** 46 | * Creates an IDE. 47 | * 48 | * @param string $uuid 49 | * @param string $label 50 | * 51 | * @command ide:create 52 | * @aliases ide:add 53 | */ 54 | public function create(Ides $idesAdapter, $uuid, $label) 55 | { 56 | $response = $idesAdapter->create($uuid, $label); 57 | $this->say(sprintf('Creating IDE (%s)', $label)); 58 | $this->waitForNotification($response); 59 | } 60 | 61 | /** 62 | * De-provisions an IDE. 63 | * 64 | * @param string $ideUuid 65 | * 66 | * @command ide:delete 67 | * @aliases ide:remove 68 | */ 69 | public function delete(Ides $idesAdapter, $ideUuid) 70 | { 71 | if ($this->confirm('Are you sure you want to delete this IDE?')) { 72 | $this->say(sprintf('Deleting IDE (%s)', $ideUuid)); 73 | $response = $idesAdapter->delete($ideUuid); 74 | $this->waitForNotification($response); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/Commands/InsightsCommand.php: -------------------------------------------------------------------------------- 1 | getAll($uuid); 34 | } else { 35 | $environment = $cloudapi->getEnvironment($uuid, $environment); 36 | $insights = $insightsAdapter->getEnvironment($environment->uuid); 37 | } 38 | foreach ($insights as $insight) { 39 | /** 40 | * @var InsightResponse $insight 41 | */ 42 | 43 | $this->renderInsightInfo($insight); 44 | } 45 | } 46 | 47 | /** 48 | * Shows insights alerts for specified applications. 49 | * 50 | * @param string $siteId 51 | * @option failed Whether to only show failed insight checks. 52 | * 53 | * @command insights:alerts:list 54 | */ 55 | public function insightsAlertsList(Insights $insightsAdapter, $siteId, $options = ['failed' => null]) 56 | { 57 | $alerts = $insightsAdapter->getAllAlerts($siteId); 58 | 59 | $output = $this->output(); 60 | $table = new Table($output); 61 | $table->setHeaders(['UUID', 'Description', 'Failed', 'Resolved', 'Ignored']); 62 | $table->setColumnStyle(2, 'center-align'); 63 | $table->setColumnStyle(3, 'center-align'); 64 | $table->setColumnStyle(4, 'center-align'); 65 | 66 | foreach ($alerts as $alert) { 67 | /** 68 | * @var InsightModuleResponse $alert 69 | */ 70 | 71 | if ($options['failed'] && !$alert->failed_value) { 72 | continue; 73 | } 74 | 75 | $table 76 | ->addRows( 77 | [ 78 | [ 79 | $alert->uuid, 80 | $alert->name, 81 | $alert->failed_value ? '✓' : '', 82 | $alert->flags->resolved ? '✓' : '', 83 | $alert->flags->ignored ? '✓' : '', 84 | ], 85 | ] 86 | ); 87 | } 88 | 89 | $table->render(); 90 | } 91 | 92 | /** 93 | * Shows insights alerts for specified applications. 94 | * 95 | * @param string $siteId 96 | * @param string $alertUuid 97 | * 98 | * @command insights:alerts:get 99 | */ 100 | public function insightsAlertsGet(Insights $insightsAdapter, $siteId, $alertUuid) 101 | { 102 | $alert = $insightsAdapter->getAlert($siteId, $alertUuid); 103 | 104 | $this->say(sprintf('UUID: %s', $alert->uuid)); 105 | $this->say(sprintf('Name: %s', $alert->name)); 106 | $this->say(sprintf('Message: %s', filter_var($alert->message, FILTER_SANITIZE_STRING))); 107 | } 108 | 109 | /** 110 | * Shows insights alerts for specified applications. 111 | * 112 | * @param string $siteId 113 | * @option enabled Whether to only show enabled modules. 114 | * @option upgradeable Whether to only show modules that need an upgrade. 115 | * 116 | * @command insights:modules 117 | */ 118 | public function insightsModules( 119 | Insights $insightsAdapter, 120 | $siteId, 121 | $options = ['enabled', 'upgradeable'] 122 | ) { 123 | $modules = $insightsAdapter->getModules($siteId); 124 | 125 | $output = $this->output(); 126 | $table = new Table($output); 127 | $table->setHeaders(['Name', 'Version', 'Enabled', 'Upgradeable']); 128 | $table->setColumnStyle(2, 'center-align'); 129 | $table->setColumnStyle(3, 'center-align'); 130 | 131 | foreach ($modules as $module) { 132 | /** 133 | * @var InsightModuleResponse $module 134 | */ 135 | 136 | if ($options['enabled'] && !$module->flags->enabled) { 137 | continue; 138 | } 139 | if ($options['upgradeable'] && array_search('upgradeable', $module->tags, true) === false) { 140 | continue; 141 | } 142 | 143 | $table 144 | ->addRows( 145 | [ 146 | [ 147 | $module->name, 148 | $module->version, 149 | $module->flags->enabled ? '✓' : '', 150 | array_search('upgradeable', $module->tags, true) !== false ? '✓' : '', 151 | ], 152 | ] 153 | ); 154 | } 155 | 156 | $table->render(); 157 | } 158 | 159 | /** 160 | * @param InsightResponse $insight 161 | */ 162 | private function renderInsightInfo(InsightResponse $insight) 163 | { 164 | $title = $insight->label . ' (' . $insight->hostname . ')'; 165 | $score = $insight->scores->insight; 166 | 167 | if ($score >= 85) { 168 | $colour = 'green'; 169 | } elseif ($score >= 65) { 170 | $colour = 'yellow'; 171 | } else { 172 | $colour = 'red'; 173 | } 174 | $char = $this->decorationCharacter(' ', '➜'); 175 | $format = "${char} %s"; 176 | $this->formattedOutput("${title} Score: " . $score, 20, $format); 177 | 178 | $this->say(sprintf('Site ID: %s', $insight->uuid)); 179 | $this->say(sprintf('Status: %s', $insight->status)); 180 | 181 | $output = $this->output(); 182 | $table = new Table($output); 183 | $table->setHeaders(['Type', 'Pass', 'Fail', 'Ignored', 'Total', '%']); 184 | foreach ($insight->counts as $type => $count) { 185 | /** 186 | * @var InsightCountResponse $count 187 | */ 188 | $table 189 | ->addRows( 190 | [ 191 | [ 192 | ucwords(str_replace('_', ' ', $type)), 193 | $count->pass, 194 | $count->fail, 195 | $count->ignored, 196 | $count->total, 197 | $count->percent, 198 | ], 199 | ] 200 | ); 201 | } 202 | 203 | $table->render(); 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /src/Commands/LivedevCommand.php: -------------------------------------------------------------------------------- 1 | cloudapiService->getEnvironment($uuid, $environment); 27 | $this->say(sprintf('Enabling livedev for %s environment', $environment->label)); 28 | $environmentsAdapter->enableLiveDev($environment->uuid); 29 | } 30 | 31 | /** 32 | * Disable livedev for an environment. 33 | * 34 | * @param string $uuid 35 | * @param string $environment 36 | * 37 | * @command livedev:disable 38 | */ 39 | public function acquiaLivedevDisable(Environments $environmentsAdapter, $uuid, $environment) 40 | { 41 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 42 | if ($this->confirm('Are you sure you want to disable livedev? Uncommitted work will be lost.')) { 43 | $this->say(sprintf('Disabling livedev for %s environment', $environment->label)); 44 | $environmentsAdapter->disableLiveDev($environment->uuid); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Commands/LogForwardCommand.php: -------------------------------------------------------------------------------- 1 | cloudapiService->getEnvironment($uuid, $environment); 34 | $logForwards = $logForwardAdapter->getAll($environment->uuid); 35 | 36 | $table = new Table($output); 37 | $table->setHeaders(['UUID', 'Label', 'Address', 'Consumer', 'Active']); 38 | $table->setColumnStyle(1, 'center-align'); 39 | $table->setColumnStyle(2, 'center-align'); 40 | $table->setColumnStyle(3, 'center-align'); 41 | $table->setColumnStyle(4, 'center-align'); 42 | 43 | foreach ($logForwards as $logForward) { 44 | /** 45 | * @var LogForwardingDestinationResponse $logForward 46 | */ 47 | $table 48 | ->addRows( 49 | [ 50 | [ 51 | $logForward->uuid, 52 | $logForward->label, 53 | $logForward->address, 54 | $logForward->consumer, 55 | $logForward->status === 'active' ? '✓' : '', 56 | ], 57 | ] 58 | ); 59 | } 60 | 61 | $table->render(); 62 | } 63 | 64 | /** 65 | * Gets information about a Log Forward. 66 | * 67 | * @param string $uuid 68 | * @param string $environment 69 | * @param int $destinationId 70 | * 71 | * @command logforward:info 72 | * @aliases lf:info 73 | */ 74 | public function logforwardInfo( 75 | OutputInterface $output, 76 | LogForwardingDestinations $logForwardAdapter, 77 | $uuid, 78 | $environment, 79 | $destinationId 80 | ) { 81 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 82 | $logForward = $logForwardAdapter->get($environment->uuid, $destinationId); 83 | 84 | $this->yell(sprintf('Log server address: %s', $logForward->address)); 85 | $this->say(sprintf('Certificate: %s', $logForward->credentials->certificate->certificate)); 86 | $this->say(sprintf('Expires at: %s', $logForward->credentials->certificate->expires_at)); 87 | $this->say(sprintf('Token: %s', $logForward->credentials->token)); 88 | $this->say(sprintf('Key: %s', $logForward->credentials->key)); 89 | $this->say(sprintf('Sources: %s%s', "\n", implode("\n", $logForward->sources))); 90 | $this->say(sprintf('Health: %s', $logForward->health->summary)); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/Commands/LogsCommand.php: -------------------------------------------------------------------------------- 1 | false, 43 | 'logtypes|t' => [], 44 | 'servers' => [] 45 | ] 46 | ) { 47 | 48 | $environment = $cloudapi->getEnvironment($uuid, $environment); 49 | $stream = $logsAdapter->stream($environment->uuid); 50 | $logstream->setParams($stream->logstream->params); 51 | if ($opts['colourise']) { 52 | $logstream->setColourise(true); 53 | } 54 | $logstream->setLogTypeFilter($opts['logtypes']); 55 | $logstream->setLogServerFilter($opts['servers']); 56 | $logstream->stream(); 57 | } 58 | 59 | /** 60 | * Shows available log files. 61 | * 62 | * @param string $uuid 63 | * @param string $environment 64 | * 65 | * @command log:list 66 | */ 67 | public function logList(CloudApi $cloudapi, Logs $logsAdapter, $uuid, $environment) 68 | { 69 | $environment = $cloudapi->getEnvironment($uuid, $environment); 70 | $logs = $logsAdapter->getAll($environment->uuid); 71 | 72 | $output = $this->output(); 73 | $table = new Table($output); 74 | $table->setHeaders(['Type', 'Label', 'Available']); 75 | $table->setColumnStyle(2, 'center-align'); 76 | foreach ($logs as $log) { 77 | $table 78 | ->addRows( 79 | [ 80 | [ 81 | $log->type, 82 | $log->label, 83 | $log->flags->available ? '✓' : ' ', 84 | ], 85 | ] 86 | ); 87 | } 88 | $table->render(); 89 | } 90 | 91 | /** 92 | * Creates a log snapshot. 93 | * 94 | * @param string $uuid 95 | * @param string $environment 96 | * @param string $logType 97 | * 98 | * @command log:snapshot 99 | */ 100 | public function logSnapshot(CloudApi $cloudapi, Logs $logsAdapter, $uuid, $environment, $logType) 101 | { 102 | $environment = $cloudapi->getEnvironment($uuid, $environment); 103 | $this->say(sprintf('Creating snapshot for %s in %s environment', $logType, $environment->label)); 104 | $logsAdapter->snapshot($environment->uuid, $logType); 105 | } 106 | 107 | /** 108 | * Downloads a log file. 109 | * 110 | * @param string $uuid 111 | * @param string $environment 112 | * @param string $logType 113 | * 114 | * @command log:download 115 | * @option $path Select a path to download the log to. If omitted, the system temp directory will be used. 116 | * @option $filename Choose a filename for the dowloaded log. If omitted, the name will be automatically generated. 117 | */ 118 | public function logDownload( 119 | CloudApi $cloudapi, 120 | Logs $logsAdapter, 121 | $uuid, 122 | $environment, 123 | $logType, 124 | $opts = ['path' => null, 'filename' => null] 125 | ) { 126 | $environment = $cloudapi->getEnvironment($uuid, $environment); 127 | $log = $logsAdapter->download($environment->uuid, $logType); 128 | 129 | if (null === $opts['filename']) { 130 | $backupName = sprintf('%s-%s', $environment->name, $logType); 131 | } else { 132 | $backupName = $opts['filename']; 133 | } 134 | 135 | if (null === $opts['path']) { 136 | $tmpLocation = tempnam(sys_get_temp_dir(), $backupName); 137 | $location = sprintf('%s.tar.gz', $tmpLocation); 138 | if (is_string($tmpLocation)) { 139 | rename($tmpLocation, $location); 140 | } else { 141 | throw new \Exception('Unable to make temporary file.'); 142 | } 143 | } else { 144 | $location = sprintf("%s%s%s.tar.gz", $opts['path'], \DIRECTORY_SEPARATOR, $backupName); 145 | } 146 | 147 | if (file_put_contents($location, $log, LOCK_EX)) { 148 | $this->say(sprintf('Log downloaded to %s', $location)); 149 | } else { 150 | $this->say('Unable to download log.'); 151 | } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /src/Commands/NotificationsCommand.php: -------------------------------------------------------------------------------- 1 | getAll($uuid); 41 | $client->clearQuery(); 42 | 43 | $output = $this->output(); 44 | $table = new Table($output); 45 | $table->setHeaders(['UUID', 'Created', 'Name', 'Status']); 46 | 47 | $extraConfig = $config->get('extraconfig'); 48 | $tz = $extraConfig['timezone']; 49 | $format = $extraConfig['format']; 50 | $timezone = new \DateTimeZone($tz); 51 | 52 | /** 53 | * If we are using the details option, override the headers as we will 54 | * be using a different number of columns. 55 | * 56 | * We will also be making THREE additional API calls which is why details 57 | * nestled in as an option rather than the default, with a warning that 58 | * it will be slower. 59 | * 60 | * We have to get both admins and members as separate API calls as there 61 | * is no single call to source all users in an organisation. 62 | * 63 | * The array_reduce() allows us to go from an ArrayObject of MemberResponses 64 | * to a simple associative array keyed on user UUID with a value of their email. 65 | * 66 | * @TODO find a way to store the application object further up the chain 67 | * as we can call on that where needed. 68 | */ 69 | if ($options['details']) { 70 | $table->setHeaders(['UUID', 'User', 'Created', 'Name', 'Status']); 71 | 72 | $application = $applicationsAdapter->get($uuid); 73 | $orgUuid = $application->organization->uuid; 74 | 75 | $admins = $organizationsAdapter->getAdmins($orgUuid); 76 | $members = $organizationsAdapter->getMembers($orgUuid); 77 | 78 | $users = $admins->getArrayCopy() + $members->getArrayCopy(); 79 | $uuids = array_reduce($users, function ($result, $member) { 80 | $result[$member->uuid] = $member->mail; 81 | return $result; 82 | }, []); 83 | } 84 | 85 | foreach ($notifications as $notification) { 86 | $createdDate = new \DateTime($notification->created_at); 87 | $createdDate->setTimezone($timezone); 88 | 89 | $rows = [ 90 | $notification->uuid, 91 | $createdDate->format($format), 92 | $notification->label, 93 | $notification->status, 94 | ]; 95 | 96 | /** 97 | * Again only fires if we've used the details option. 98 | * There is a chance that an operation will occur without a user attached. 99 | * This could happen if an automated task/Acquia support person does something. 100 | * The code here finds the user by UUID and presents their email. 101 | */ 102 | if ($options['details']) { 103 | $author = $notification->context->author->uuid; 104 | $mail = isset($uuids[$author]) ? $uuids[$author] : 'N/A'; 105 | array_splice($rows, 1, 0, $mail); 106 | } 107 | 108 | $table 109 | ->addRows( 110 | [ 111 | $rows 112 | ] 113 | ); 114 | } 115 | 116 | $table->render(); 117 | } 118 | 119 | /** 120 | * Gets detailed information about a specific notification 121 | * 122 | * @param string $uuid 123 | * @param string $notificationUuid 124 | * 125 | * @command notification:info 126 | * @aliases n:i 127 | * @throws \Exception 128 | */ 129 | public function notificationInfo( 130 | Config $config, 131 | Applications $applicationsAdapter, 132 | Organizations $organizationsAdapter, 133 | Notifications $notificationsAdapter, 134 | $uuid, 135 | $notificationUuid 136 | ) { 137 | 138 | $extraConfig = $config->get('extraconfig'); 139 | $tz = $extraConfig['timezone']; 140 | $format = $extraConfig['format']; 141 | $timezone = new \DateTimeZone($tz); 142 | 143 | $notification = $notificationsAdapter->get($notificationUuid); 144 | 145 | $createdDate = new \DateTime($notification->created_at); 146 | $createdDate->setTimezone($timezone); 147 | $completedDate = new \DateTime($notification->completed_at); 148 | $completedDate->setTimezone($timezone); 149 | 150 | // @TODO Find a way to store the application object earlier to remove this call. 151 | $application = $applicationsAdapter->get($uuid); 152 | $orgUuid = $application->organization->uuid; 153 | $admins = $organizationsAdapter->getAdmins($orgUuid); 154 | $members = $organizationsAdapter->getMembers($orgUuid); 155 | $users = $admins->getArrayCopy() + $members->getArrayCopy(); 156 | $uuids = array_reduce($users, function ($result, $member) { 157 | $result[$member->uuid] = $member->mail; 158 | return $result; 159 | }, []); 160 | $author = $notification->context->author->uuid; 161 | $mail = isset($uuids[$author]) ? $uuids[$author] : 'N/A'; 162 | 163 | $this->say(sprintf('ID: %s', $notification->uuid)); 164 | $this->say(sprintf('User: %s', $mail)); 165 | $this->say(sprintf('Event: %s', $notification->event)); 166 | $this->say(sprintf('Description: %s', htmlspecialchars_decode($notification->description))); 167 | $this->say(sprintf('Status: %s', $notification->status)); 168 | $this->say(sprintf('Created: %s', $createdDate->format($format))); 169 | $this->say(sprintf('Completed: %s', $completedDate->format($format))); 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /src/Commands/OrganizationsCommand.php: -------------------------------------------------------------------------------- 1 | getAll(); 31 | 32 | $table = new Table($this->output()); 33 | $table->setHeaders(['UUID', 'Organization', 'Owner', 'Subs', 'Admins', 'Users', 'Teams', 'Roles']); 34 | foreach ($organizations as $organization) { 35 | /** 36 | * @var OrganizationResponse $permission 37 | */ 38 | $table 39 | ->addRows( 40 | [ 41 | [ 42 | $organization->uuid, 43 | $organization->name, 44 | $organization->owner->username, 45 | $organization->subscriptions_total, 46 | $organization->admins_total, 47 | $organization->users_total, 48 | $organization->teams_total, 49 | $organization->roles_total, 50 | ], 51 | ] 52 | ); 53 | } 54 | 55 | $table->render(); 56 | } 57 | 58 | /** 59 | * Shows a list of all applications within an organization. 60 | * 61 | * @param string $organization 62 | * 63 | * @command organization:applications 64 | * @aliases org:apps,o:a 65 | */ 66 | public function organizationApplications(Organizations $organizationsAdapter, $organization) 67 | { 68 | $organization = $this->cloudapiService->getOrganization($organization); 69 | $applications = $organizationsAdapter->getApplications($organization->uuid); 70 | 71 | $this->say(sprintf('Applications in organisation: %s', $organization->uuid)); 72 | $table = new Table($this->output()); 73 | $table->setHeaders(['UUID', 'Name', 'Type', 'Hosting ID']); 74 | foreach ($applications as $application) { 75 | /** 76 | * @var ApplicationResponse $application 77 | */ 78 | $table 79 | ->addRows( 80 | [ 81 | [ 82 | $application->uuid, 83 | $application->name, 84 | $application->hosting->type, 85 | $application->hosting->id, 86 | ], 87 | ] 88 | ); 89 | } 90 | 91 | $table->render(); 92 | } 93 | 94 | /** 95 | * Shows teams within an organization. 96 | * 97 | * @param string $organization 98 | * 99 | * @command organization:teams 100 | * @aliases org:teams,o:t 101 | */ 102 | public function organizationTeams(Organizations $organizationsAdapter, $organization) 103 | { 104 | $organization = $this->cloudapiService->getOrganization($organization); 105 | $teams = $organizationsAdapter->getTeams($organization->uuid); 106 | 107 | $this->say(sprintf('Teams in organisation: %s', $organization->uuid)); 108 | $table = new Table($this->output()); 109 | $table->setHeaders(['UUID', 'Name']); 110 | foreach ($teams as $team) { 111 | /** 112 | * @var TeamResponse $team 113 | */ 114 | $table 115 | ->addRows( 116 | [ 117 | [ 118 | $team->uuid, 119 | $team->name, 120 | ], 121 | ] 122 | ); 123 | } 124 | 125 | $table->render(); 126 | } 127 | 128 | /** 129 | * Shows all members. 130 | * 131 | * @param string $organization 132 | * 133 | * @command organization:members 134 | * @aliases org:members,o:m 135 | */ 136 | public function members(Organizations $organizationsAdapter, $organization) 137 | { 138 | $organization = $this->cloudapiService->getOrganization($organization); 139 | $organizationUuid = $organization->uuid; 140 | $admins = $organizationsAdapter->getAdmins($organization->uuid); 141 | $members = $organizationsAdapter->getMembers($organization->uuid); 142 | 143 | $this->say(sprintf('Members in organisation: %s', $organization->uuid)); 144 | $table = new Table($this->output()); 145 | $table 146 | ->setHeaders(['UUID', 'Username', 'Mail', 'Teams(s)']) 147 | ->setColumnStyle(0, 'center-align') 148 | ->setRows( 149 | [ 150 | [new TableCell('Organisation Administrators', ['colspan' => 4])], 151 | new TableSeparator(), 152 | ] 153 | ); 154 | 155 | foreach ($admins as $admin) { 156 | /** 157 | * @var MemberResponse $admin 158 | */ 159 | $table 160 | ->addRows( 161 | [ 162 | [ 163 | $admin->uuid, 164 | $admin->username, 165 | $admin->mail, 166 | 'admin' 167 | ], 168 | ] 169 | ); 170 | } 171 | 172 | $table 173 | ->addRows( 174 | [ 175 | new TableSeparator(), 176 | [new TableCell('Organisation Members', ['colspan' => 4])], 177 | new TableSeparator(), 178 | ] 179 | ); 180 | 181 | foreach ($members as $member) { 182 | /** 183 | * @var MemberResponse $member 184 | */ 185 | $teamList = array_map( 186 | function ($team) { 187 | return $team->name; 188 | }, 189 | $member->teams->getArrayCopy() 190 | ); 191 | $teamString = implode(',', $teamList); 192 | $table 193 | ->addRows( 194 | [ 195 | [ 196 | $member->uuid, 197 | $member->username, 198 | $member->mail, 199 | $teamString, 200 | ], 201 | ] 202 | ); 203 | } 204 | 205 | $table->render(); 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /src/Commands/ProductionModeCommand.php: -------------------------------------------------------------------------------- 1 | cloudapiService->getEnvironment($uuid, $environment); 34 | 35 | $this->say(sprintf('Enabling production mode for %s environment', $environment->label)); 36 | $environmentsAdapter->enableProductionMode($environment->uuid); 37 | } 38 | 39 | /** 40 | * Disable production mode for an environment. 41 | * 42 | * @param string $uuid 43 | * @param EnvironmentResponse $environment 44 | * @throws \Exception 45 | * 46 | * @command productionmode:disable 47 | * @aliases pm:disable 48 | */ 49 | public function productionModeDisable(Environments $environmentsAdapter, $uuid, $environment) 50 | { 51 | 52 | if ('prod' !== $environment) { 53 | throw new \Exception('Production mode may only be enabled/disabled on the prod environment.'); 54 | } 55 | 56 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 57 | 58 | if ($this->confirm('Are you sure you want to disable production mode?')) { 59 | $this->say(sprintf('Disabling production mode for %s environment', $environment->label)); 60 | $environmentsAdapter->disableProductionMode($environment->uuid); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Commands/SetupCommand.php: -------------------------------------------------------------------------------- 1 | $config->get('config.global')]; 27 | 28 | // Do not include project configuration if this is running in a Phar. 29 | if (!\Phar::running()) { 30 | $configFiles['project'] = $config->get('config.project'); 31 | } 32 | 33 | foreach ($configFiles as $type => $location) { 34 | $this->yell(sprintf('%s configuration (%s)', ucfirst($type), $location)); 35 | 36 | if (file_exists($location)) { 37 | if ($this->confirm(sprintf('Would you like to regenerate the %s configuration file', $type))) { 38 | $this->createConfigYaml($location); 39 | } 40 | } else { 41 | if ($this->confirm(sprintf('%s configuration file not found. Would you like to add one?', ucfirst($type)))) { 42 | $this->createConfigYaml($location); 43 | } 44 | } 45 | } 46 | } 47 | 48 | /** 49 | * Allows users to view the configuration that they have on their system. 50 | * 51 | * This provides a view of default, global, project, and environment variable based configuration. 52 | * 53 | * @command setup:config:view 54 | */ 55 | public function configView(Config $config) 56 | { 57 | $configFiles = [ 58 | 'default' => $config->get('config.default'), 59 | 'global' => $config->get('config.global'), 60 | 'environment' => $config->get('config.environment') 61 | ]; 62 | 63 | // Do not include project configuration if this is running in a Phar. 64 | if (!\Phar::running()) { 65 | $configFiles['project'] = $config->get('config.project'); 66 | } 67 | 68 | foreach ($configFiles as $type => $data) { 69 | $contents = ''; 70 | if (is_array($data)) { 71 | if (empty($data)) { 72 | continue; 73 | } 74 | $contents = Yaml::dump($data); 75 | } elseif (file_exists($data) && is_readable($data)) { 76 | $contents = file_get_contents($data); 77 | } else { 78 | continue; 79 | } 80 | $this->yell(sprintf('%s configuration', ucfirst($type))); 81 | $this->writeln($contents); 82 | } 83 | 84 | $this->yell('Running configuration'); 85 | $running = [ 86 | 'acquia' => $config->get('acquia'), 87 | 'extraconfig' => $config->get('extraconfig') 88 | ]; 89 | 90 | $this->writeln(Yaml::dump($running)); 91 | } 92 | 93 | /** 94 | * Function to create configuration files for this library. 95 | */ 96 | private function createConfigYaml($location) 97 | { 98 | $key = $this->ask('What is your Acquia key?'); 99 | $secret = $this->askHidden('What is your Acquia secret?'); 100 | 101 | $config = [ 102 | 'acquia' => [ 103 | 'key' => $key, 104 | 'secret' => $secret, 105 | ], 106 | 'extraconfig' => [ 107 | 'timezone' => 'Australia/Sydney', 108 | 'format' => 'Y-m-d H:i:s', 109 | 'taskwait' => 5, 110 | 'timeout' => 300, 111 | ], 112 | ]; 113 | 114 | $yaml = Yaml::dump($config, 3, 2); 115 | 116 | if (!is_dir(dirname($location))) { 117 | mkdir(dirname($location), 0700); 118 | } 119 | 120 | if (!is_writable(dirname($location)) && !@chmod(dirname($location), 0700)) { 121 | $this->yell(sprintf('%s is not writeable', dirname($location)), 40, 'red'); 122 | } elseif (file_put_contents($location, $yaml) && @chmod($location, 0644)) { 123 | $this->say(sprintf('Configuration file written to %s', $location)); 124 | } else { 125 | $this->say('Unable to write configuration file.'); 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/Commands/SshCommand.php: -------------------------------------------------------------------------------- 1 | addQuery('filter', "name=${env}"); 30 | } 31 | 32 | $environments = $environmentsAdapter->getAll($uuid); 33 | 34 | $client->clearQuery(); 35 | 36 | foreach ($environments as $e) { 37 | /** 38 | * @var $e EnvironmentResponse 39 | */ 40 | $this->say($e->name . ': ssh ' . $e->sshUrl); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Commands/SslCertificateCommand.php: -------------------------------------------------------------------------------- 1 | cloudapiService->getEnvironment($uuid, $environment); 33 | $certificates = $certificatesAdapter->getAll($environment->uuid); 34 | 35 | $table = new Table($output); 36 | $table->setHeaders(['ID', 'Label', 'Domains', 'Expires', 'Active']); 37 | $table->setColumnStyle(1, 'center-align'); 38 | $table->setColumnStyle(2, 'center-align'); 39 | $table->setColumnStyle(3, 'center-align'); 40 | $table->setColumnStyle(4, 'center-align'); 41 | 42 | foreach ($certificates as $certificate) { 43 | /** 44 | * @var SslCertificateResponse $certificate 45 | */ 46 | $table 47 | ->addRows( 48 | [ 49 | [ 50 | $certificate->id, 51 | $certificate->label, 52 | implode("\n", $certificate->domains), 53 | $certificate->expires_at, 54 | $certificate->flags->active ? '✓' : '', 55 | ], 56 | ] 57 | ); 58 | } 59 | 60 | $table->render(); 61 | } 62 | 63 | /** 64 | * Gets information about an SSL certificate. 65 | * 66 | * @param string $uuid 67 | * @param string $environment 68 | * @param int $certificateId 69 | * 70 | * @command ssl:info 71 | */ 72 | public function sslCertificateInfo( 73 | SslCertificates $certificatesAdapter, 74 | $uuid, 75 | $environment, 76 | $certificateId 77 | ) { 78 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 79 | $certificate = $certificatesAdapter->get($environment->uuid, $certificateId); 80 | 81 | $this->yell('Certificate'); 82 | $this->writeln($certificate->certificate); 83 | $this->yell('CA'); 84 | $this->writeln($certificate->ca); 85 | $this->yell('Private Key'); 86 | $this->writeln($certificate->private_key); 87 | } 88 | 89 | /** 90 | * Enables an SSL certificate. 91 | * 92 | * @param string $uuid 93 | * @param string $environment 94 | * @param int $certificateId 95 | * 96 | * @command ssl:enable 97 | */ 98 | public function sslCertificateEnable( 99 | SslCertificates $certificatesAdapter, 100 | $uuid, 101 | $environment, 102 | $certificateId 103 | ) { 104 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 105 | 106 | if ($this->confirm('Are you sure you want to activate this SSL certificate? Activating this certificate will deactivate all other non-legacy certificates.')) { 107 | $this->say(sprintf('Activating certificate on %s environment.', $environment->label)); 108 | $response = $certificatesAdapter->enable($environment->uuid, $certificateId); 109 | $this->waitForNotification($response); 110 | } 111 | } 112 | 113 | /** 114 | * Disables an SSL certificate. 115 | * 116 | * @param string $uuid 117 | * @param string $environment 118 | * @param int $certificateId 119 | * 120 | * @command ssl:disable 121 | */ 122 | public function sslCertificateDisable( 123 | SslCertificates $certificatesAdapter, 124 | $uuid, 125 | $environment, 126 | $certificateId 127 | ) { 128 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 129 | 130 | if ($this->confirm('Are you sure you want to disable this SSL certificate?')) { 131 | $this->say(sprintf('Disabling certificate on %s environment.', $environment->label)); 132 | $response = $certificatesAdapter->disable($environment->uuid, $certificateId); 133 | $this->waitForNotification($response); 134 | } 135 | } 136 | 137 | /** 138 | * Install an SSL certificate 139 | * 140 | * @param string $uuid 141 | * @param string $environment 142 | * @param string $label 143 | * @param string $certificate The path to the certificate file. 144 | * @param string $key The path to the private key file. 145 | * @param null|string $ca The path to the certificate authority file. 146 | * @option activate Enable certification after creation. 147 | * @command ssl:create 148 | */ 149 | public function sslCertificateCreate( 150 | SslCertificates $certificatesAdapter, 151 | $uuid, 152 | $environment, 153 | $label, 154 | $certificate, 155 | $key, 156 | $ca = null, 157 | $options = ['activate'] 158 | ) { 159 | $environment = $this->cloudapiService->getEnvironment($uuid, $environment); 160 | 161 | $confirmMessage = 'Are you sure you want to install this new SSL certificate? (It will not be activated unless the --activate option is passed).'; 162 | if ($options['activate']) { 163 | $confirmMessage = 'Are you sure you want to install and activate this new SSL certificate? Activating this certificate will deactivate all other non-legacy certificates.'; 164 | } 165 | if ($this->confirm($confirmMessage)) { 166 | if (!file_exists($certificate) || !is_readable($certificate)) { 167 | throw new \Exception(sprintf('Cannot open certificate file at %s.', $certificate)); 168 | } 169 | $certificate = strval(file_get_contents($certificate)); 170 | 171 | if (!file_exists($key) || !is_readable($key)) { 172 | throw new \Exception(sprintf('Cannot open key file at %s.', $key)); 173 | } 174 | $key = strval(file_get_contents($key)); 175 | 176 | if ($ca !== null) { 177 | if (!file_exists($ca) || !is_readable($ca)) { 178 | throw new \Exception(sprintf('Cannot open ca file at %s.', $ca)); 179 | } 180 | $ca = strval(file_get_contents($ca)); 181 | } 182 | 183 | $this->say(sprintf('Installing new certificate %s on %s environment.', $label, $environment->label)); 184 | 185 | $response = $certificatesAdapter->create( 186 | $environment->uuid, 187 | $label, 188 | $certificate, 189 | $key, 190 | $ca 191 | ); 192 | 193 | $this->waitForNotification($response); 194 | 195 | if ($options['activate']) { 196 | $certificates = $certificatesAdapter->getAll($environment->uuid); 197 | foreach ($certificates as $installedCertificate) { 198 | /** 199 | * @var SslCertificateResponse $certificate 200 | */ 201 | if ($installedCertificate->label === $label && !$installedCertificate->flags->active) { 202 | $this->say(sprintf('Activating certificate %s on %s environment.', $installedCertificate->label, $environment->label)); 203 | $response = $certificatesAdapter->enable($environment->uuid, $installedCertificate->id); 204 | $this->waitForNotification($response); 205 | } 206 | } 207 | } 208 | } 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /src/Commands/TeamsCommand.php: -------------------------------------------------------------------------------- 1 | cloudapiService->getOrganization($organization); 32 | $this->say('Creating new team.'); 33 | $teamsAdapter->create($organization->uuid, $name); 34 | } 35 | 36 | /** 37 | * Invites a user to a team. 38 | * 39 | * @param string $teamUuid 40 | * @param string $email The email address for the user that needs to be invited. 41 | * @param string $roleUuids A comma separated list of role UUIDs that a user should be invited to. 42 | * 43 | * @command team:invite 44 | */ 45 | public function teamInvite(Teams $teamsAdapter, $teamUuid, $email, $roleUuids) 46 | { 47 | $rolesArray = explode(',', $roleUuids); 48 | $this->say(sprintf('Inviting %s to team.', $email)); 49 | $teamsAdapter->invite($teamUuid, $email, $rolesArray); 50 | } 51 | 52 | /** 53 | * Assigns an application to a team. 54 | * 55 | * @param string $uuid 56 | * @param string $teamUuid 57 | * 58 | * @command team:addapplication 59 | * @aliases team:addapp 60 | */ 61 | public function teamAddApplication(Teams $teamsAdapter, $uuid, $teamUuid) 62 | { 63 | $this->say("Adding application to team."); 64 | $teamsAdapter->addApplication($teamUuid, $uuid); 65 | } 66 | 67 | /** 68 | * Displays all permissions available on the Acquia Cloud. 69 | * 70 | * @command permissions:list 71 | * @aliases perm:list 72 | */ 73 | public function showPermissions(Permissions $permissionsAdapter) 74 | { 75 | $permissions = $permissionsAdapter->get(); 76 | 77 | $table = new Table($this->output()); 78 | $table->setHeaders(['Name', 'Label']); 79 | foreach ($permissions as $permission) { 80 | /** 81 | * @var PermissionResponse $permission 82 | */ 83 | $table 84 | ->addRows( 85 | [ 86 | [ 87 | $permission->name, 88 | $permission->label, 89 | ], 90 | ] 91 | ); 92 | } 93 | 94 | $table->render(); 95 | } 96 | 97 | /** 98 | * Adds a new role to an organization. 99 | * 100 | * @param string $organization 101 | * @param string $name A human readable role name e.g. 'Release Managers' 102 | * @param string $permissions A comma separated list of permissions a role should have 103 | * e.g. 'administer domain non-prod,administer ssh 104 | * keys,deploy to non-prod' 105 | * @param null|string $description A human readable description of the role 106 | * e.g. 'For non-technical users to create 107 | * releases' 108 | * 109 | * @command role:add 110 | */ 111 | public function addRole(Roles $rolesAdapter, $organization, $name, $permissions, $description = null) 112 | { 113 | $organization = $this->cloudapiService->getOrganization($organization); 114 | $permissionsArray = explode(',', $permissions); 115 | $this->say(sprintf('Creating new role (%s) and adding it to organisation.', $name)); 116 | $rolesAdapter->create($organization->uuid, $name, $permissionsArray, $description); 117 | } 118 | 119 | /** 120 | * Deletes a role. 121 | * 122 | * @param string $roleUuid 123 | * 124 | * @command role:delete 125 | */ 126 | public function deleteRole(Roles $rolesAdapter, $roleUuid) 127 | { 128 | if ($this->confirm('Are you sure you want to remove this role?')) { 129 | $this->say('Deleting role'); 130 | $rolesAdapter->delete($roleUuid); 131 | } 132 | } 133 | 134 | /** 135 | * Updates the permissions for a role. 136 | * 137 | * @param string $roleUuid 138 | * @param string $permissions A comma separated list of permissions a role should have 139 | * e.g. 'administer domain non-prod,administer ssh keys,deploy to non-prod' 140 | * 141 | * @command role:update:permissions 142 | */ 143 | public function roleUpdatePermissions(Roles $rolesAdapter, $roleUuid, $permissions) 144 | { 145 | $permissionsArray = explode(',', $permissions); 146 | $this->say('Updating role permissions'); 147 | $rolesAdapter->update($roleUuid, $permissionsArray); 148 | } 149 | 150 | /** 151 | * Shows all roles within an organization. 152 | * 153 | * @param string $organization 154 | * 155 | * @command role:list 156 | */ 157 | public function showRoles(Roles $rolesAdapter, Permissions $permissionsAdapter, $organization) 158 | { 159 | $organization = $this->cloudapiService->getOrganization($organization); 160 | 161 | $organizationUuid = $organization->uuid; 162 | $roles = $rolesAdapter->getAll($organizationUuid); 163 | 164 | $permissions = $permissionsAdapter->get(); 165 | 166 | $roleList = array_map( 167 | function ($role) { 168 | $this->say($role->name . ': ' . $role->uuid); 169 | return $role->name; 170 | }, 171 | $roles->getArrayCopy() 172 | ); 173 | 174 | array_unshift($roleList, 'Permission'); 175 | 176 | $table = new Table($this->output()); 177 | $table->setHeaders($roleList); 178 | 179 | foreach ($permissions as $permission) { 180 | /** 181 | * @var PermissionResponse $permission 182 | */ 183 | $roleHasPermission = false; 184 | $permissionsMatrix = [$permission->name]; 185 | foreach ($roles as $role) { 186 | /** 187 | * @var RoleResponse $role 188 | */ 189 | foreach ($role->permissions as $rolePermission) { 190 | if ($rolePermission->name == $permission->name) { 191 | $permissionsMatrix[] = '✓'; 192 | $roleHasPermission = true; 193 | continue; 194 | } 195 | } 196 | if ($roleHasPermission === false) { 197 | $permissionsMatrix[] = ''; 198 | } 199 | } 200 | 201 | $table 202 | ->addRows( 203 | [ 204 | $permissionsMatrix, 205 | 206 | ] 207 | ); 208 | } 209 | 210 | $table->render(); 211 | } 212 | } 213 | -------------------------------------------------------------------------------- /src/Commands/VariablesCommand.php: -------------------------------------------------------------------------------- 1 | getEnvironment($uuid, $environment); 32 | $variables = $variablesAdapter->getAll($environment->uuid); 33 | 34 | $output = $this->output(); 35 | $table = new Table($output); 36 | $table->setHeaders(['Name', 'Value']); 37 | 38 | foreach ($variables as $variable) { 39 | /** 40 | * @var VariableResponse $variable 41 | */ 42 | $table 43 | ->addRows( 44 | [ 45 | [ 46 | $variable->name, 47 | $variable->value 48 | ], 49 | ] 50 | ); 51 | } 52 | 53 | $table->render(); 54 | } 55 | 56 | /** 57 | * Gets information about a variable. 58 | * 59 | * @param string $uuid 60 | * @param string $environment 61 | * @param string $name 62 | * 63 | * @command variable:info 64 | * @aliases v:i 65 | */ 66 | public function variableInfo(CloudApi $cloudapi, Variables $variablesAdapter, $uuid, $environment, $name) 67 | { 68 | $environment = $cloudapi->getEnvironment($uuid, $environment); 69 | 70 | $variable = $variablesAdapter->get($environment->uuid, $name); 71 | $this->say($variable->value); 72 | } 73 | 74 | /** 75 | * Add a variable to an environment. 76 | * 77 | * @param string $uuid 78 | * @param string $environment 79 | * @param string $name 80 | * @param string $value 81 | * 82 | * @command variable:create 83 | * @aliases variable:add,v:a 84 | */ 85 | public function variableCreate(CloudApi $cloudapi, Variables $variablesAdapter, $uuid, $environment, $name, $value) 86 | { 87 | $environment = $cloudapi->getEnvironment($uuid, $environment); 88 | 89 | $this->say(sprintf('Adding variable %s:%s to %s environment', $name, $value, $environment->label)); 90 | $response = $variablesAdapter->create($environment->uuid, $name, $value); 91 | $this->waitForNotification($response); 92 | } 93 | 94 | /** 95 | * Removes an environment variable from an environment. 96 | * 97 | * @param string $uuid 98 | * @param string $environment 99 | * @param string $name 100 | * 101 | * @command variable:delete 102 | * @aliases variable:remove,v:d,v:r 103 | */ 104 | public function variableDelete(CloudApi $cloudapi, Variables $variablesAdapter, $uuid, $environment, $name) 105 | { 106 | $environment = $cloudapi->getEnvironment($uuid, $environment); 107 | 108 | if ($this->confirm('Are you sure you want to remove this environment variable?')) { 109 | $this->say(sprintf('Removing variable %s from %s environment', $name, $environment->label)); 110 | $response = $variablesAdapter->delete($environment->uuid, $name); 111 | $this->waitForNotification($response); 112 | } 113 | } 114 | 115 | /** 116 | * Updates an environment variable on an environment. 117 | * 118 | * @param string $uuid 119 | * @param string $environment 120 | * @param string $name 121 | * @param string $value 122 | * 123 | * @command variable:update 124 | * @aliases v:u 125 | */ 126 | public function variableUpdate(CloudApi $cloudapi, Variables $variablesAdapter, $uuid, $environment, $name, $value) 127 | { 128 | $environment = $cloudapi->getEnvironment($uuid, $environment); 129 | 130 | if ($this->confirm('Are you sure you want to update this environment variable?')) { 131 | $this->say(sprintf('Updating variable %s:%s on %s environment', $name, $value, $environment->label)); 132 | $response = $variablesAdapter->update($environment->uuid, $name, $value); 133 | $this->waitForNotification($response); 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/Injector/AcquiaCliInjector.php: -------------------------------------------------------------------------------- 1 | config = \Robo\Robo::service('config'); 40 | $this->cloudapi = \Robo\Robo::service('cloudApi'); 41 | $this->client = \Robo\Robo::service('client'); 42 | $this->logstream = \Robo\Robo::service('logstream'); 43 | } 44 | 45 | public function get(CommandData $commandData, $interfaceName) 46 | { 47 | switch ($interfaceName) { 48 | case 'AcquiaCli\Cli\CloudApi': 49 | return $this->cloudapi; 50 | case 'AcquiaCli\Cli\Config': 51 | return $this->config; 52 | case 'AcquiaCloudApi\Connector\Client': 53 | return $this->client; 54 | case 'AcquiaLogstream\LogstreamManager': 55 | return $this->logstream; 56 | case 'AcquiaCloudApi\Endpoints\Applications': 57 | return new Applications($this->client); 58 | case 'AcquiaCloudApi\Endpoints\Environments': 59 | return new Environments($this->client); 60 | case 'AcquiaCloudApi\Endpoints\Databases': 61 | return new Databases($this->client); 62 | case 'AcquiaCloudApi\Endpoints\Servers': 63 | return new Servers($this->client); 64 | case 'AcquiaCloudApi\Endpoints\Domains': 65 | return new Domains($this->client); 66 | case 'AcquiaCloudApi\Endpoints\Code': 67 | return new Code($this->client); 68 | case 'AcquiaCloudApi\Endpoints\DatabaseBackups': 69 | return new DatabaseBackups($this->client); 70 | case 'AcquiaCloudApi\Endpoints\Crons': 71 | return new Crons($this->client); 72 | case 'AcquiaCloudApi\Endpoints\Account': 73 | return new Account($this->client); 74 | case 'AcquiaCloudApi\Endpoints\Roles': 75 | return new Roles($this->client); 76 | case 'AcquiaCloudApi\Endpoints\Permissions': 77 | return new Permissions($this->client); 78 | case 'AcquiaCloudApi\Endpoints\Teams': 79 | return new Teams($this->client); 80 | case 'AcquiaCloudApi\Endpoints\Variables': 81 | return new Variables($this->client); 82 | case 'AcquiaCloudApi\Endpoints\Logs': 83 | return new Logs($this->client); 84 | case 'AcquiaCloudApi\Endpoints\Notifications': 85 | return new Notifications($this->client); 86 | case 'AcquiaCloudApi\Endpoints\Insights': 87 | return new Insights($this->client); 88 | case 'AcquiaCloudApi\Endpoints\LogForwardingDestinations': 89 | return new LogForwardingDestinations($this->client); 90 | case 'AcquiaCloudApi\Endpoints\SslCertificates': 91 | return new SslCertificates($this->client); 92 | case 'AcquiaCloudApi\Endpoints\Organizations': 93 | return new Organizations($this->client); 94 | case 'AcquiaCloudApi\Endpoints\Ides': 95 | return new Ides($this->client); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /tests/Commands/AccountCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 14 | 15 | // $this->assertEquals( 16 | // preg_match( 17 | // '@> Acquia Cloud Drush Aliases archive downloaded to ((\S+)AcquiaDrushAliases(\w+).sql.gz)@', 18 | // $actualResponse, $matches), 19 | // 1 20 | // ); 21 | 22 | // $this->assertStringStartsWith('> Acquia Cloud Drush Aliases archive downloaded to ', $actualResponse); 23 | // $this->assertStringContainsString(sys_get_temp_dir(), $matches[2]); 24 | 25 | // $path = sprintf( 26 | // '%s/vendor/typhonius/acquia-php-sdk-v2/tests/Fixtures/Endpoints/%s', 27 | // dirname(dirname(__DIR__)), 28 | // 'Account/getDrushAliases.dat' 29 | // ); 30 | // $this->assertFileExists($path); 31 | // $contents = file_get_contents($path); 32 | // } 33 | 34 | /** 35 | * @dataProvider accountProvider 36 | */ 37 | public function testAccountInfo($command, $expected) 38 | { 39 | $actualResponse = $this->execute($command); 40 | $this->assertSame($expected, $actualResponse); 41 | } 42 | 43 | public function accountProvider() 44 | { 45 | 46 | $infoResponse = << Name: jane.doe 48 | > Last login: 2017-03-29 05:07:54 49 | > Created at: 2017-03-29 05:07:54 50 | > Status: ✓ 51 | > TFA: ✓ 52 | INFO; 53 | 54 | return [ 55 | [ 56 | ['account'], 57 | $infoResponse . PHP_EOL 58 | ] 59 | ]; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tests/Commands/ApplicationCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function applicationProvider() 20 | { 21 | $getAllApplications = << 🔧 Git URL: qa10@svn-3.networkdev.ahserversdev.com:qa10.git 43 | > 💻 indicates environment in livedev mode. 44 | > 🔒 indicates environment in production mode. 45 | TABLE; 46 | // phpcs:enable 47 | 48 | $getTags = <<
Creating application tag name:color' . PHP_EOL 72 | ], 73 | [ 74 | ['application:tag:delete', 'devcloud:devcloud2', 'name'], 75 | '> Deleting application tag name' . PHP_EOL 76 | ], 77 | [ 78 | ['application:rename', 'devcloud:devcloud2', 'foobar'], 79 | '> Renaming application to foobar' . PHP_EOL 80 | ] 81 | ]; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /tests/Commands/CacheClearCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | 17 | // Ensure the items exist in the cache before we attempt a clear. 18 | $cache = new FilesystemAdapter('acquiacli'); 19 | 20 | $this->assertTrue($cache->hasItem('application.devcloud.devcloud2')); 21 | $this->assertTrue($cache->hasItem('environment.a47ac10b-58cc-4372-a567-0e02b2c3d470.dev')); 22 | 23 | // Clear the cache. 24 | $command = ['cache:clear']; 25 | $this->execute($command); 26 | 27 | $this->assertFalse($cache->hasItem('application.devcloud.devcloud2')); 28 | $this->assertFalse($cache->hasItem('environment.a47ac10b-58cc-4372-a567-0e02b2c3d470.dev')); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/Commands/CodeCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function codeProvider() 20 | { 21 | 22 | $codeList = <<execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function cronProvider() 20 | { 21 | 22 | $cronList = << Cron commands starting with "#" are disabled. 30 | LIST; 31 | 32 | $cronInfo = << ID: 24 34 | > Label: 35 | > Environment: dev 36 | > Command: /usr/local/bin/drush cc all 37 | > Frequency: 25 7 * * * 38 | > Enabled: ✓ 39 | > System: 40 | > On any web: ✓ 41 | INFO; 42 | 43 | return [ 44 | [ 45 | ['cron:create', 'devcloud:devcloud2', 'dev', 'commandString', 'frequency', 'label'], 46 | '> Adding new cron task on dev environment' . PHP_EOL 47 | ], 48 | [ 49 | ['cron:delete', 'devcloud:devcloud2', 'dev', 'cronId'], 50 | '> Deleting cron task cronId from Dev' . PHP_EOL 51 | ], 52 | [ 53 | ['cron:disable', 'devcloud:devcloud2', 'dev', 'cronId'], 54 | '> Disabling cron task cronId on dev environment' . PHP_EOL 55 | ], 56 | [ 57 | ['cron:enable', 'devcloud:devcloud2', 'dev', 'cronId'], 58 | '> Enabling cron task cronId on dev environment' . PHP_EOL 59 | ], 60 | [ 61 | ['cron:info', 'devcloud:devcloud2', 'dev', 'cronId'], 62 | $cronInfo . PHP_EOL 63 | ], 64 | [ 65 | ['cron:list', 'devcloud:devcloud2', 'dev'], 66 | $cronList . PHP_EOL 67 | ] 68 | ]; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /tests/Commands/DbBackupCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 14 | 15 | $this->assertEquals( 16 | preg_match( 17 | '@> Downloading database backup to ((\S+)dev-database2-(\w+).sql.gz)@', 18 | $actualResponse, 19 | $matches 20 | ), 21 | 1 22 | ); 23 | 24 | $this->assertStringStartsWith('> Downloading database backup to ', $actualResponse); 25 | $this->assertStringContainsString(sys_get_temp_dir(), $matches[2]); 26 | } 27 | 28 | public function testDownloadDatabaseBackupsCommandsWithOptions() 29 | { 30 | $command = [ 31 | 'database:backup:download', 32 | 'devcloud:devcloud2', 33 | 'dev', 34 | 'database2', 35 | '--backup=1', 36 | '--filename=foo', 37 | '--path=/tmp' 38 | ]; 39 | $actualResponse = $this->execute($command); 40 | 41 | $this->assertEquals( 42 | preg_match( 43 | '@> Downloading database backup to ((/tmp/)foo.sql.gz)@', 44 | $actualResponse, 45 | $matches 46 | ), 47 | 1 48 | ); 49 | 50 | $this->assertStringStartsWith('> Downloading database backup to ', $actualResponse); 51 | $this->assertStringContainsString('/tmp/', $matches[2]); 52 | } 53 | 54 | /** 55 | * @dataProvider dbBackupProvider 56 | */ 57 | public function testDbBackupCommands($command, $expected) 58 | { 59 | $actualResponse = $this->execute($command); 60 | $this->assertSame($expected, $actualResponse); 61 | } 62 | 63 | public function dbBackupProvider() 64 | { 65 | 66 | $dbBackupList = <<
https://cloud.acquia.com/api', 93 | '24-a47ac10b-58cc-4372-a567-0e02b2c3d470', 94 | 'dbName', 95 | 1234 96 | ); 97 | 98 | return [ 99 | [ 100 | ['database:backup:restore', 'devcloud:devcloud2', 'dev', 'dbName', '1234'], 101 | '> Restoring backup 1234 to dbName on Dev' . PHP_EOL 102 | ], 103 | [ 104 | ['database:backup:all', 'devcloud:devcloud2', 'dev'], 105 | $createBackupAllText . PHP_EOL 106 | ], 107 | [ 108 | ['database:backup', 'devcloud:devcloud2', 'dev', 'database1'], 109 | $createBackupText . PHP_EOL 110 | ], 111 | [ 112 | ['database:backup:list', 'devcloud:devcloud2', 'dev'], 113 | $dbBackupList . PHP_EOL 114 | ], 115 | [ 116 | ['database:backup:list', 'devcloud:devcloud2', 'dev', 'dbName'], 117 | $dbBackupList . PHP_EOL 118 | ], 119 | [ 120 | ['database:backup:link', 'devcloud:devcloud2', 'dev', 'dbName', '1234'], 121 | $dbLink . PHP_EOL 122 | ], 123 | [ 124 | ['database:backup:delete', 'devcloud:devcloud2', 'dev', 'dbName', '1234'], 125 | '> Deleting backup 1234 to dbName on Dev' . PHP_EOL 126 | ], 127 | ]; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /tests/Commands/DbCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function dbProvider() 20 | { 21 | 22 | $dbTable = <<
Backing up DB (database1) on Dev 33 | > Moving DB (database1) from Stage to Dev 34 | > Backing up DB (database2) on Dev 35 | > Moving DB (database2) from Stage to Dev 36 | TEXT; 37 | 38 | $dbCopyNoBackup = << Moving DB (database1) from Stage to Dev 40 | > Moving DB (database2) from Stage to Dev 41 | TEXT; 42 | 43 | return [ 44 | [ 45 | ['database:create', 'devcloud:devcloud2', 'dbName'], 46 | '> Creating database (dbName)' . PHP_EOL 47 | ], 48 | [ 49 | ['database:delete', 'devcloud:devcloud2', 'dbName'], 50 | '> Deleting database (dbName)' . PHP_EOL 51 | ], 52 | [ 53 | ['database:list', 'devcloud:devcloud2'], 54 | $dbTable . PHP_EOL 55 | ], 56 | [ 57 | ['database:truncate', 'devcloud:devcloud2', 'dbName'], 58 | '> Truncate database (dbName)' . PHP_EOL 59 | ], 60 | [ 61 | ['database:copy', 'devcloud:devcloud2', 'test', 'dev', 'dbName'], 62 | $dbCopy . PHP_EOL 63 | ], 64 | [ 65 | ['database:copy:all', 'devcloud:devcloud2', 'test', 'dev'], 66 | $dbCopy . PHP_EOL 67 | ], 68 | [ 69 | ['database:copy', 'devcloud:devcloud2', 'test', 'dev', 'dbName', '--no-backup'], 70 | $dbCopyNoBackup . PHP_EOL 71 | ], 72 | [ 73 | ['database:copy:all', 'devcloud:devcloud2', 'test', 'dev', '--no-backup'], 74 | $dbCopyNoBackup . PHP_EOL 75 | ] 76 | ]; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /tests/Commands/DeployCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function deployProvider() 20 | { 21 | 22 | $deployResponseDev = << Backing up DB (database1) on Dev 24 | > Moving DB (database1) from Production to Dev 25 | > Backing up DB (database2) on Dev 26 | > Moving DB (database2) from Production to Dev 27 | > Copying files from Production to Dev 28 | INFO; 29 | 30 | $deployResponseTest = << Backing up DB (database1) on Stage 32 | > Moving DB (database1) from Production to Stage 33 | > Backing up DB (database2) on Stage 34 | > Moving DB (database2) from Production to Stage 35 | > Copying files from Production to Stage 36 | INFO; 37 | 38 | $deployResponseProd = <<execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function domainsProvider() 20 | { 21 | 22 | $domainInfo = <<
Purging domain: www.example.com 42 | > Purging domain: other.example.com 43 | > Purging domain: *.example.com 44 | PURGE; 45 | 46 | return [ 47 | [ 48 | ['domain:create', 'devcloud:devcloud2', 'dev', 'domain'], 49 | '> Adding domain to environment Dev' . PHP_EOL 50 | ], 51 | [ 52 | ['domain:delete', 'devcloud:devcloud2', 'test', 'domain'], 53 | '> Removing domain from environment Stage' . PHP_EOL 54 | ], 55 | [ 56 | ['domain:info', 'devcloud:devcloud2', 'prod', 'domain'], 57 | $domainInfo . PHP_EOL 58 | ], 59 | [ 60 | ['domain:list', 'devcloud:devcloud2', 'dev'], 61 | $domainsList . PHP_EOL 62 | ], 63 | [ 64 | ['domain:move', 'devcloud:devcloud2', 'domain', 'dev', 'test'], 65 | '> Moving domain from Dev to Stage' . PHP_EOL 66 | ], 67 | [ 68 | ['domain:purge', 'devcloud:devcloud2', 'dev'], 69 | $domainPurge . PHP_EOL 70 | ], 71 | [ 72 | ['domain:purge', 'devcloud:devcloud2', 'dev', 'www.domain1.com'], 73 | '> Purging domain: www.domain1.com' . PHP_EOL 74 | ] 75 | ]; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /tests/Commands/EnvironmentCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function environmentProvider() 20 | { 21 | $getAllEnvironments = <<
Environment ID: 24-a47ac10b-58cc-4372-a567-0e02b2c3d470 39 | +---------+-------+--------------------------+-----------+-----------+----------+----------+--------+---------+-----+ 40 | | Role(s) | Name | FQDN | AMI | Region | IP | Memcache | Active | Primary | EIP | 41 | +---------+-------+--------------------------+-----------+-----------+----------+----------+--------+---------+-----+ 42 | | web, db | ded-6 | ded-6.servers.acquia.com | c1.medium | us-west-1 | 10.0.0.1 | ✓ | ✓ | ✓ | | 43 | | bal | bal-4 | bal-4.servers.acquia.com | m1.small | us-west-1 | 10.0.0.2 | | | ✓ | | 44 | +---------+-------+--------------------------+-----------+-----------+----------+----------+--------+---------+-----+ 45 | +--------+-----+-------------+--------------+---------+------+---------------+ 46 | | Branch | CDE | PHP Version | Memory Limit | OpCache | APCu | Sendmail Path | 47 | +--------+-----+-------------+--------------+---------+------+---------------+ 48 | | master | | 7.2 | 128 | 96 | 32 | | 49 | +--------+-----+-------------+--------------+---------+------+---------------+ 50 | 51 | Production environment 52 | 53 | > Environment ID: 15-a47ac10b-58cc-4372-a567-0e02b2c3d470 54 | > 🔒 Production mode enabled. 55 | +---------+-------+--------------------------+-----------+-----------+----------+----------+--------+---------+-----+ 56 | | Role(s) | Name | FQDN | AMI | Region | IP | Memcache | Active | Primary | EIP | 57 | +---------+-------+--------------------------+-----------+-----------+----------+----------+--------+---------+-----+ 58 | | web, db | ded-6 | ded-6.servers.acquia.com | c1.medium | us-west-1 | 10.0.0.1 | ✓ | ✓ | ✓ | | 59 | | bal | bal-4 | bal-4.servers.acquia.com | m1.small | us-west-1 | 10.0.0.2 | | | ✓ | | 60 | +---------+-------+--------------------------+-----------+-----------+----------+----------+--------+---------+-----+ 61 | +-----------------+-----+-------------+--------------+---------+------+---------------+ 62 | | Branch | CDE | PHP Version | Memory Limit | OpCache | APCu | Sendmail Path | 63 | +-----------------+-----+-------------+--------------+---------+------+---------------+ 64 | | tags/01-01-2015 | | | | | | | 65 | +-----------------+-----+-------------+--------------+---------+------+---------------+ 66 | 67 | Stage environment 68 | 69 | > Environment ID: 32-a47ac10b-58cc-4372-a567-0e02b2c3d470 70 | +---------+-------+--------------------------+-----------+-----------+----------+----------+--------+---------+-----+ 71 | | Role(s) | Name | FQDN | AMI | Region | IP | Memcache | Active | Primary | EIP | 72 | +---------+-------+--------------------------+-----------+-----------+----------+----------+--------+---------+-----+ 73 | | web, db | ded-6 | ded-6.servers.acquia.com | c1.medium | us-west-1 | 10.0.0.1 | ✓ | ✓ | ✓ | | 74 | | bal | bal-4 | bal-4.servers.acquia.com | m1.small | us-west-1 | 10.0.0.2 | | | ✓ | | 75 | +---------+-------+--------------------------+-----------+-----------+----------+----------+--------+---------+-----+ 76 | +--------+-----+-------------+--------------+---------+------+---------------+ 77 | | Branch | CDE | PHP Version | Memory Limit | OpCache | APCu | Sendmail Path | 78 | +--------+-----+-------------+--------------+---------+------+---------------+ 79 | | | | | | | | | 80 | +--------+-----+-------------+--------------+---------+------+---------------+ 81 | > Web servers not marked 'Active' are out of rotation. 82 | > Load balancer servers not marked 'Active' are hot spares 83 | > Database servers not marked 'Primary' are the passive master 84 | TABLE; 85 | 86 | return [ 87 | [ 88 | ['environment:list', 'devcloud:devcloud2'], 89 | $getAllEnvironments . PHP_EOL 90 | ], 91 | [ 92 | ['environment:info', 'devcloud:devcloud2', 'dev'], 93 | $getEnvironmentInfo . PHP_EOL 94 | ], 95 | [ 96 | ['environment:branch', 'devcloud:devcloud2', 'dev'], 97 | '> master' . PHP_EOL 98 | ], 99 | [ 100 | ['environment:rename', 'devcloud:devcloud2', 'dev', 'name'], 101 | '> Renaming Dev to name' . PHP_EOL 102 | ], 103 | [ 104 | ['environment:delete', 'devcloud:devcloud2', 'dev'], 105 | '> Deleting Dev environment' . PHP_EOL 106 | ], 107 | [ 108 | ['environment:configure', 'devcloud:devcloud2', 'dev', 'version', '7.4'], 109 | '> Configuring Dev with [version => 7.4]' . PHP_EOL 110 | ] 111 | ]; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /tests/Commands/FilesCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function filesProvider() 20 | { 21 | 22 | return [ 23 | [ 24 | ['files:copy', 'devcloud:devcloud2', 'dev', 'test'], 25 | '> Copying files from Dev to Stage' . PHP_EOL 26 | ] 27 | ]; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/Commands/IdesCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function idesProvider() 20 | { 21 | 22 | $idesTable = <<
Creating IDE (Example IDE)' . PHP_EOL 34 | ], 35 | [ 36 | ['ide:delete', '215824ff-272a-4a8c-9027-df32ed1d68a9'], 37 | '> Deleting IDE (215824ff-272a-4a8c-9027-df32ed1d68a9)' . PHP_EOL 38 | ], 39 | [ 40 | ['ide:list', 'devcloud:devcloud2'], 41 | $idesTable . PHP_EOL 42 | ] 43 | ]; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/Commands/InsightsCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function insightsProvider() 20 | { 21 | 22 | // phpcs:disable Generic.Files.LineLength.TooLong 23 | $insightAlert = << UUID: a47ac10b-58cc-4372-a567-0e02b2c3d470 25 | > Name: PHP errors visible 26 | > Message: Your website is configured to display PHP error messages to users. These error messages can reveal sensitive information about your website and its server to site visitors. 27 | ALERT; 28 | 29 | // phpcs:enable 30 | 31 | $insightModules = <<
Site ID: 50227ff0-2a53-11e9-b210-d663bd873d93 56 | > Status: ok 57 | +----------------+------+------+---------+-------+----+ 58 | | Type | Pass | Fail | Ignored | Total | % | 59 | +----------------+------+------+---------+-------+----+ 60 | | Best Practices | 5 | 1 | 0 | 6 | 83 | 61 | | Performance | 9 | 10 | 0 | 19 | 47 | 62 | | Security | 10 | 10 | 0 | 20 | 50 | 63 | +----------------+------+------+---------+-------+----+ 64 | 65 | Test Site: prod (test.example.com) Score: 62 66 | 67 | > Site ID: 50227ff0-2a53-11e9-b210-d663bd873d93 68 | > Status: ok 69 | +----------------+------+------+---------+-------+----+ 70 | | Type | Pass | Fail | Ignored | Total | % | 71 | +----------------+------+------+---------+-------+----+ 72 | | Best Practices | 5 | 1 | 0 | 6 | 83 | 73 | | Performance | 10 | 9 | 0 | 19 | 53 | 74 | | Security | 11 | 9 | 0 | 20 | 55 | 75 | +----------------+------+------+---------+-------+----+ 76 | INFO; 77 | 78 | $insightApplicationInfo = << Site ID: 1bc0b462-2665-11e9-ab14-d663bd873d93 83 | > Status: ok 84 | +----------------+------+------+---------+-------+----+ 85 | | Type | Pass | Fail | Ignored | Total | % | 86 | +----------------+------+------+---------+-------+----+ 87 | | Best Practices | 5 | 1 | 0 | 6 | 83 | 88 | | Performance | 9 | 10 | 0 | 19 | 47 | 89 | | Security | 10 | 10 | 0 | 20 | 50 | 90 | +----------------+------+------+---------+-------+----+ 91 | 92 | Test Site: prod (test.example.com) Score: 62 93 | 94 | > Site ID: 63645c1a-2665-11e9-ab14-d663bd873d93 95 | > Status: ok 96 | +----------------+------+------+---------+-------+----+ 97 | | Type | Pass | Fail | Ignored | Total | % | 98 | +----------------+------+------+---------+-------+----+ 99 | | Best Practices | 5 | 1 | 0 | 6 | 83 | 100 | | Performance | 10 | 9 | 0 | 19 | 53 | 101 | | Security | 11 | 9 | 0 | 20 | 55 | 102 | +----------------+------+------+---------+-------+----+ 103 | INFO; 104 | 105 | 106 | return [ 107 | [ 108 | ['insights:alerts:get', 'siteId', 'alertUuid'], 109 | $insightAlert . PHP_EOL 110 | ], 111 | [ 112 | ['insights:alerts:list', 'siteId'], 113 | $insightAlerts . PHP_EOL 114 | ], 115 | [ 116 | ['insights:info', 'devcloud:devcloud2', 'dev'], 117 | $insightEnvironmentInfo . PHP_EOL 118 | ], 119 | [ 120 | ['insights:info', 'devcloud:devcloud2'], 121 | $insightApplicationInfo . PHP_EOL 122 | ], 123 | [ 124 | ['insights:modules', 'siteId'], 125 | $insightModules . PHP_EOL 126 | ] 127 | ]; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /tests/Commands/LiveDevCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function liveDevProvider() 20 | { 21 | 22 | return [ 23 | [ 24 | ['livedev:enable', 'devcloud:devcloud2', 'dev'], 25 | '> Enabling livedev for Dev environment' . PHP_EOL 26 | ], 27 | [ 28 | ['livedev:disable', 'devcloud:devcloud2', 'dev'], 29 | '> Disabling livedev for Dev environment' . PHP_EOL 30 | ] 31 | ]; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/Commands/LogForwardCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function logForwardProvider() 20 | { 21 | 22 | $listResponse = << Certificate: -----BEGIN CERTIFICATE-----...-----END CERTIFICATE----- 36 | > Expires at: 2018-07-16T16:15:33+00:00 37 | > Token: 204d892b449026f6e4ded264c8891c400df8fc8905f07beb5f70d706f6d4d5e5 38 | > Key: 1d0789d519c0b943cf38f401d30ffbdcd2e0c4cfb7c32ebc0c872bce62aadd4d 39 | > Sources: 40 | apache-access 41 | apache-error 42 | > Health: OK 43 | INFO; 44 | 45 | return [ 46 | [ 47 | ['lf:list', 'devcloud:devcloud2', 'dev'], 48 | $listResponse . PHP_EOL 49 | ], 50 | [ 51 | ['lf:info', 'devcloud:devcloud2', 'dev', '1234'], 52 | $infoResponse . PHP_EOL, 53 | ] 54 | ]; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/Commands/LogsCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 14 | 15 | $this->assertEquals( 16 | preg_match('@> Log downloaded to ((\S+)dev-apache-access(\w+).tar.gz)@', $actualResponse, $matches), 17 | 1 18 | ); 19 | 20 | $this->assertStringStartsWith('> Log downloaded to ', $actualResponse); 21 | $this->assertStringContainsString(sys_get_temp_dir(), $matches[2]); 22 | 23 | $path = sprintf( 24 | '%s/vendor/typhonius/acquia-php-sdk-v2/tests/Fixtures/Endpoints/%s', 25 | dirname(dirname(__DIR__)), 26 | 'Logs/downloadLog.dat' 27 | ); 28 | $this->assertFileExists($path); 29 | $contents = file_get_contents($path); 30 | if ($contents) { 31 | $this->assertStringEqualsFile($matches[1], $contents); 32 | } 33 | } 34 | 35 | public function testDownloadLogsCommandsWithOptions() 36 | { 37 | $command = [ 38 | 'log:download', 39 | 'devcloud:devcloud2', 40 | 'dev', 41 | 'apache-access', 42 | '--filename=bar', 43 | '--path=/tmp' 44 | ]; 45 | 46 | $actualResponse = $this->execute($command); 47 | 48 | $this->assertEquals( 49 | preg_match( 50 | '@> Log downloaded to ((/tmp/)bar.tar.gz)@', 51 | $actualResponse, 52 | $matches 53 | ), 54 | 1 55 | ); 56 | 57 | $this->assertStringStartsWith('> Log downloaded to ', $actualResponse); 58 | $this->assertStringContainsString('/tmp/', $matches[2]); 59 | } 60 | 61 | public function testLogstream() 62 | { 63 | 64 | $command = [ 65 | 'log:stream', 66 | 'devcloud:devcloud2', 67 | 'dev', 68 | '--colourise', 69 | '--logtypes=apache-access', 70 | '--servers=web-1234' 71 | ]; 72 | 73 | $this->execute($command); 74 | 75 | $authArray = [ 76 | 'site' => 'clouduidev:qa4', 77 | 'd' => 'd8b940bb5a1865e57b22734d541ed981c89f952e527b0a983d0e457437a43c23', 78 | 't' => 1516990002, 79 | 'env' => 'prod', 80 | 'cmd' => 'stream-environment' 81 | ]; 82 | $this->assertSame('1.1.1.1', $this->logstream->getDns()); 83 | $this->assertSame(['apache-access'], $this->logstream->getLogTypeFilter()); 84 | $this->assertSame(['web-1234'], $this->logstream->getLogServerFilter()); 85 | $this->assertSame(10, $this->logstream->getTimeout()); 86 | $this->assertSame(true, $this->logstream->getColourise()); 87 | 88 | $class = new \ReflectionClass(get_class($this->logstream)); 89 | $method = $class->getMethod('getAuthArray'); 90 | $method->setAccessible(true); 91 | $output = $method->invoke($this->logstream); 92 | 93 | $this->assertEquals($authArray, $output); 94 | } 95 | 96 | /** 97 | * @dataProvider logsProvider 98 | */ 99 | public function testLogsCommands($command, $expected) 100 | { 101 | $actualResponse = $this->execute($command); 102 | $this->assertSame($expected, $actualResponse); 103 | } 104 | 105 | public function logsProvider() 106 | { 107 | 108 | $logsList = <<
Creating snapshot for apache-access in Dev environment' . PHP_EOL 129 | ], 130 | ]; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /tests/Commands/NotificationCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function notificationProvider() 20 | { 21 | $getAllNotifictions = <<
ID: f4b37e3c-1g96-4ed4-ad20-3081fe0f9545 39 | > User: N/A 40 | > Event: DatabaseBackupCreated 41 | > Description: A "sample_db" database backup has been created for "Dev". 42 | > Status: completed 43 | > Created: 2019-09-24 01:59:39 44 | > Completed: 2019-09-24 02:01:16 45 | INFO; 46 | 47 | return [ 48 | [ 49 | ['notification:list', 'devcloud:devcloud2'], 50 | $getAllNotifictions . PHP_EOL 51 | ], 52 | [ 53 | ['notification:list', 'devcloud:devcloud2', '--details'], 54 | $getAllNotifictionsDetails . PHP_EOL 55 | ], 56 | [ 57 | ['notification:info', 'devcloud:devcloud2', 'f4b37e3c-1g96-4ed4-ad20-3081fe0f9545'], 58 | $getNotification . PHP_EOL 59 | ] 60 | ]; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /tests/Commands/OrganizationsCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function organizationsProvider() 20 | { 21 | $getOrganizations = <<
Teams in organisation: g47ac10b-58cc-4372-a567-0e02b2c3d470 33 | +--------------------------------------+-------------+ 34 | | UUID | Name | 35 | +--------------------------------------+-------------+ 36 | | abcd1234-82b5-11e3-9170-12313920a02c | Team Name 1 | 37 | | 1234abcd-82b5-11e3-9170-12313920a02c | Team Name 2 | 38 | +--------------------------------------+-------------+ 39 | TABLE; 40 | 41 | $organizationMembers = <<
Members in organisation: g47ac10b-58cc-4372-a567-0e02b2c3d470 43 | +--------------------------------------+-----------------+-----------------------------+-------------------------+ 44 | | UUID | Username | Mail | Teams(s) | 45 | +--------------------------------------+-----------------+-----------------------------+-------------------------+ 46 | | Organisation Administrators | 47 | +--------------------------------------+-----------------+-----------------------------+-------------------------+ 48 | | 5aa902c5-f1c1-6c94-edfa-86bc58d0dce3 | james.kirk | james.kirk@example.com | admin | 49 | | 30dacb5e-4122-11e1-9eb5-12313928d3c2 | chris.pike | chris.pike@example.com | admin | 50 | | 3bcddc3a-52ba-4cce-aaa3-9adf721c1b52 | jonathan.archer | jonathan.archer@example.com | admin | 51 | +--------------------------------------+-----------------+-----------------------------+-------------------------+ 52 | | Organisation Members | 53 | +--------------------------------------+-----------------+-----------------------------+-------------------------+ 54 | | 5aa902c5-f1c1-6c94-edfa-86bc58d0dce3 | james.kirk | james.kirk@example.com | Team Name 1 | 55 | | 30dacb5e-4122-11e1-9eb5-12313928d3c2 | chris.pike | chris.pike@example.com | Team Name 2 | 56 | | 3bcddc3a-52ba-4cce-aaa3-9adf721c1b52 | jonathan.archer | jonathan.archer@example.com | Team Name 1,Team Name 2 | 57 | +--------------------------------------+-----------------+-----------------------------+-------------------------+ 58 | TABLE; 59 | 60 | $organizationApplications = <<
Applications in organisation: g47ac10b-58cc-4372-a567-0e02b2c3d470 62 | +--------------------------------------+----------------------+------+--------------------+ 63 | | UUID | Name | Type | Hosting ID | 64 | +--------------------------------------+----------------------+------+--------------------+ 65 | | a47ac10b-58cc-4372-a567-0e02b2c3d470 | Sample application 1 | acp | devcloud:devcloud2 | 66 | | a47ac10b-58cc-4372-a567-0e02b2c3d471 | Sample application 2 | free | devcloud:devcloud2 | 67 | +--------------------------------------+----------------------+------+--------------------+ 68 | TABLE; 69 | 70 | return [ 71 | [ 72 | ['organization:applications', 'Sample organization'], 73 | $organizationApplications . PHP_EOL 74 | ], 75 | [ 76 | ['organization:list'], 77 | $getOrganizations . PHP_EOL 78 | ], 79 | [ 80 | ['organization:members', 'Sample organization'], 81 | $organizationMembers . PHP_EOL 82 | ], 83 | [ 84 | ['organization:teams', 'Sample organization'], 85 | $organizationTeams . PHP_EOL 86 | ] 87 | ]; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /tests/Commands/PermissionsCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function permissionsProvider() 20 | { 21 | 22 | $permissions = <<execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function productionModeProvider() 20 | { 21 | 22 | $infoResponse = << dev: ssh 24 | > prod: ssh 25 | > test: ssh 26 | INFO; 27 | return [ 28 | [ 29 | ['productionmode:enable', 'devcloud:devcloud2', 'dev'], 30 | ' [error] Production mode may only be enabled/disabled on the prod environment. ' . PHP_EOL 31 | ], 32 | [ 33 | ['productionmode:disable', 'devcloud:devcloud2', 'dev'], 34 | ' [error] Production mode may only be enabled/disabled on the prod environment. ' . PHP_EOL 35 | ], 36 | [ 37 | ['productionmode:enable', 'devcloud:devcloud2', 'prod'], 38 | '> Enabling production mode for Production environment' . PHP_EOL 39 | ], 40 | [ 41 | ['productionmode:disable', 'devcloud:devcloud2', 'prod'], 42 | '> Disabling production mode for Production environment' . PHP_EOL 43 | ] 44 | ]; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tests/Commands/RolesCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function roleProvider() 20 | { 21 | 22 | $roleList = <<
Team Lead: 312c0121-906b-4498-8402-7b479172768c 24 | > Senior Developer: 5f7da0a9-9ff0-4db8-802e-9d2b9969efc2 25 | > Developer: d33cd9ff-281d-4bcf-9f89-b10b249caa35 26 | +-----------------------------+-----------+------------------+-----------+ 27 | | Permission | Team Lead | Senior Developer | Developer | 28 | +-----------------------------+-----------+------------------+-----------+ 29 | | administer alerts | | | | 30 | | revoke insight installs | | | | 31 | | deploy to non-prod | | | | 32 | | deploy to prod | | | | 33 | | pull from prod | | | | 34 | | move file to non-prod | | | | 35 | | move file to prod | | | | 36 | | move file from prod | | | | 37 | | move file from non-prod | | | | 38 | | clear varnish on non-prod | | | | 39 | | clear varnish on prod | | | | 40 | | configure prod env | | | | 41 | | configure non-prod env | | | | 42 | | add an environment | | | | 43 | | delete an environment | | | | 44 | | administer domain non-prod | | | | 45 | | administer domain prod | | | | 46 | | administer ssl prod | | | | 47 | | administer ssl non-prod | | | | 48 | | reboot server | | | | 49 | | resize server | | | | 50 | | suspend server | | | | 51 | | configure server | | | | 52 | | download logs non-prod | | | | 53 | | download logs prod | | | | 54 | | add database | | | | 55 | | remove database | | | | 56 | | view database connection | | | | 57 | | download db backup non-prod | | | | 58 | | download db backup prod | | | | 59 | | create db backup non-prod | | | | 60 | | create db backup prod | | | | 61 | | restore db backup non-prod | | | | 62 | | restore db backup prod | | | | 63 | | administer team | ✓ | ✓ | | 64 | | access cloud api | | ✓ | ✓ | 65 | | administer cron non-prod | | | | 66 | | administer cron prod | | | | 67 | | search limit increase | | | | 68 | | search schema edit | | | | 69 | | create support ticket | | | | 70 | | edit any support ticket | | | | 71 | | administer ssh keys | | | | 72 | | view build plans | | | | 73 | | edit build plans | | | | 74 | | run build plans | | | | 75 | | add ssh key to git | | | | 76 | | add ssh key to non-prod | | | | 77 | | add ssh key to prod | | | | 78 | | view remote administration | | | | 79 | | edit remote administration | | | | 80 | +-----------------------------+-----------+------------------+-----------+ 81 | TABLE; 82 | 83 | return [ 84 | [ 85 | ['role:add', 'Sample organization', 'name', 'permissions'], 86 | '> Creating new role (name) and adding it to organisation.' . PHP_EOL 87 | ], 88 | [ 89 | ['role:delete', 'roleUuid'], 90 | '> Deleting role' . PHP_EOL 91 | ], 92 | [ 93 | ['role:list', 'Sample organization'], 94 | $roleList . PHP_EOL 95 | ], 96 | [ 97 | ['role:update:permissions', 'roleUuid', 'permissions'], 98 | '> Updating role permissions' . PHP_EOL 99 | ] 100 | ]; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /tests/Commands/SetupCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 49 | $this->assertSame($defaultConfiguration, $actualResponse); 50 | } 51 | 52 | public function testSetupConfigViewOverwritten() 53 | { 54 | $command = ['setup:config:view']; 55 | $overwrittenConfiguration = <<< OVERWRITTEN 56 | 57 | Default configuration 58 | 59 | acquia: 60 | key: 'd0697bfc-7f56-4942-9205-b5686bf5b3f5' 61 | secret: 'D5UfO/4FfNBWn4+0cUwpLOoFzfP7Qqib4AoY+wYGsKE=' 62 | extraconfig: 63 | timezone: 'Australia/Sydney' 64 | format: 'Y-m-d H:i:s' 65 | taskwait: 5 66 | timeout: 300 67 | 68 | 69 | Environment configuration 70 | 71 | extraconfig: 72 | timezone: Australia/Melbourne 73 | format: U 74 | 75 | 76 | Running configuration 77 | 78 | acquia: 79 | key: d0697bfc-7f56-4942-9205-b5686bf5b3f5 80 | secret: D5UfO/4FfNBWn4+0cUwpLOoFzfP7Qqib4AoY+wYGsKE= 81 | extraconfig: 82 | timezone: Australia/Melbourne 83 | format: U 84 | taskwait: 5 85 | timeout: 300 86 | 87 | 88 | OVERWRITTEN; 89 | 90 | putenv('ACQUIACLI_TIMEZONE=Australia/Melbourne'); 91 | putenv('ACQUIACLI_FORMAT=U'); 92 | 93 | $actualResponse = $this->execute($command); 94 | $this->assertSame($overwrittenConfiguration, $actualResponse); 95 | 96 | putenv('ACQUIACLI_TIMEZONE='); 97 | putenv('ACQUIACLI_FORMAT='); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /tests/Commands/SshCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function sshProvider() 20 | { 21 | 22 | $infoResponse = << dev: ssh 24 | > prod: ssh 25 | > test: ssh 26 | INFO; 27 | 28 | return [ 29 | [ 30 | ['ssh:info', 'devcloud:devcloud2'], 31 | $infoResponse . PHP_EOL 32 | ], 33 | [ 34 | ['ssh:info', 'devcloud:devcloud2', 'dev'], 35 | $infoResponse . PHP_EOL, 36 | ] 37 | ]; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/Commands/SslCertificateCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function sslCertificateProvider() 20 | { 21 | $sslCertificatesPath = dirname(__DIR__) . "/Fixtures/SslCertificates"; 22 | 23 | $listResponse = << Activating certificate on Dev environment.' . PHP_EOL, 63 | ], 64 | [ 65 | ['ssl:disable', 'devcloud:devcloud2', 'dev', '1234'], 66 | '> Disabling certificate on Dev environment.' . PHP_EOL, 67 | ], 68 | [ 69 | ['ssl:create', 70 | 'devcloud:devcloud2', 71 | 'dev', 72 | 'Test Certificate 2', 73 | $sslCertificatesPath . '/cert.pem', 74 | $sslCertificatesPath . '/key.pem', 75 | $sslCertificatesPath . '/ca.pem', 76 | '--activate'], 77 | '> Installing new certificate Test Certificate 2 on Dev environment.' . PHP_EOL . 78 | '> Activating certificate Test Certificate 2 on Dev environment.' . PHP_EOL 79 | ], 80 | [ 81 | ['ssl:create', 82 | 'devcloud:devcloud2', 83 | 'dev', 84 | 'Test Certificate 2', 85 | $sslCertificatesPath . '/cert.pem', 86 | $sslCertificatesPath . '/key.pem'], 87 | '> Installing new certificate Test Certificate 2 on Dev environment.' . PHP_EOL, 88 | ], 89 | [ 90 | ['ssl:create', 91 | 'devcloud:devcloud2', 92 | 'dev', 93 | 'Test Certificate 2', 94 | '/nopath/cert.pem', 95 | $sslCertificatesPath . '/key.pem'], 96 | ' [error] Cannot open certificate file at /nopath/cert.pem. ' . PHP_EOL, 97 | ], 98 | [ 99 | ['ssl:create', 100 | 'devcloud:devcloud2', 101 | 'dev', 102 | 'Test Certificate 2', 103 | $sslCertificatesPath . '/cert.pem', 104 | '/nopath/key.pem'], 105 | ' [error] Cannot open key file at /nopath/key.pem. ' . PHP_EOL, 106 | ], 107 | [ 108 | ['ssl:create', 109 | 'devcloud:devcloud2', 110 | 'dev', 111 | 'Test Certificate 2', 112 | $sslCertificatesPath . '/cert.pem', 113 | $sslCertificatesPath . '/key.pem', 114 | '/nopath/ca.pem'], 115 | ' [error] Cannot open ca file at /nopath/ca.pem. ' . PHP_EOL, 116 | ] 117 | ]; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /tests/Commands/TeamsCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function teamsProvider() 20 | { 21 | 22 | return [ 23 | [ 24 | ['team:addapplication', 'devcloud:devcloud2', 'teamUuid'], 25 | '> Adding application to team.' . PHP_EOL 26 | ], 27 | [ 28 | ['team:create', 'Sample organization', 'name'], 29 | '> Creating new team.' . PHP_EOL 30 | ], 31 | [ 32 | ['team:invite', 'teamUuid', 'email', 'roles'], 33 | '> Inviting email to team.' . PHP_EOL 34 | ] 35 | ]; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/Commands/VariablesCommandTest.php: -------------------------------------------------------------------------------- 1 | execute($command); 16 | $this->assertSame($expected, $actualResponse); 17 | } 18 | 19 | public function variablesProvider() 20 | { 21 | 22 | $variablesList = <<
Adding variable variable_one:Sample Value One to Dev environment' . PHP_EOL 36 | ], 37 | [ 38 | ['variable:delete', 'devcloud:devcloud2', 'dev', 'variable_one'], 39 | '> Removing variable variable_one from Dev environment' . PHP_EOL 40 | ], 41 | [ 42 | ['variable:info', 'devcloud:devcloud2', 'dev', 'variable_one'], 43 | '> Sample Value One' . PHP_EOL 44 | ], 45 | [ 46 | ['variable:list', 'devcloud:devcloud2', 'dev'], 47 | $variablesList . PHP_EOL 48 | ], 49 | [ 50 | ['variable:update', 'devcloud:devcloud2', 'dev', 'variable_one', 'Sample Value One'], 51 | '> Updating variable variable_one:Sample Value One on Dev environment' . PHP_EOL 52 | ] 53 | ]; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/Fixtures/SslCertificates/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | 123abc.... 3 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /tests/Fixtures/SslCertificates/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | abc123.... 3 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /tests/Fixtures/SslCertificates/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | secret.... 3 | -----END RSA PRIVATE KEY----- --------------------------------------------------------------------------------