public function testDecrypt()
 {
     $encrypted_key = 'hu8gZ19fINO3HrPUQkHgqdZ5qaLcKFg4kRgUISFOhQWiAWVYbyo53gE6JQ61gZ64tvclc0RtVghPZCGLvQSJvmQxFwdxzXF7mqvJdepFXhIdwJ6PMIE701kGmdjNoSoXFiOACb73c70DZQmzLA4sVulwcTtJcMWsRgpiC4PayrNWun9x0bWsvsDNNZ2YPZL8yf0paeyfLPsMONfqakSUrJfprYFtjbEkWcgx0hluvZpHj3Nl6AU3TFBJS6b8qFrp99qVsS7wBKAUNSUrDBzGjYNy';
     $decrypted_key = 'FOGdGgtmjWZufLyyCe91QG1njTKrylvn8wv0RaLmoCd7sEhDKAjJ6iHGXJPRrfdm2Mtw2nlpBjbukKBU';
     $credentials_param = Parameter::make(['id' => 'cloud_credentials', 'sensitive' => true, 'value' => ['access_key' => 'test-key', 'secret_key' => $encrypted_key]]);
     $params = ParametersCollection::make(['StackName' => 'test-stack', 'cloud_credentials' => $credentials_param]);
     $unencrypted_values = ['test-stack', 'cloud_credentials', true, 'test-key'];
     foreach ($unencrypted_values as $value) {
         Crypt::shouldReceive('decrypt')->once()->with($value)->andThrow(new \Illuminate\Contracts\Encryption\DecryptException('Invalid data.'));
     }
     Crypt::shouldReceive('decrypt')->once()->with($encrypted_key)->andReturn($decrypted_key);
     $decrypted_params = $params->decrypted()->toArray();
     $this->assertEquals(array_get($decrypted_params, 'cloud_credentials.value.secret_key'), $decrypted_key);
 }
示例#2
0
 /**
  * @param Stack $stack
  * @param $action
  * @return Stack
  * @throws \Aws\CloudFormation\Exception\CloudFormationException
  * @throws \Exception
  */
 private function manageStack(Stack $stack, $action)
 {
     $cfn_params = new ParametersCollection(['StackName' => $stack->get('name'), 'DisableRollback' => true, 'Capabilities' => ['CAPABILITY_IAM']]);
     switch ($action) {
         case 'create':
         case 'update':
             $stack_params = $this->getParams($stack, $with_outputs = true);
             $stack_params->forget('cloud_credentials');
             $template = $this->generateTemplate($stack, $stack_params);
             $bucket = $stack_params->get(Stack::PARAM_TEMPLATE_BUCKET)->value;
             $s3_template = $this->publishTemplate($stack, $bucket, $template);
             $cfn_params->put('TemplateURL', $s3_template['url']);
             $params = $cfn_params->merge($stack_params);
             $params->forget('components');
             $defined_params = TemplateEngine::getParams($stack->template);
             $defined_params_keys = ParametersCollection::make($defined_params)->parametersKeys();
             $sensitive = $params->onlyIds($defined_params_keys)->sensitive()->flat()->studly()->decrypted()->toCollection();
             if ($sensitive_aws = $sensitive->toAws()) {
                 $cfn_params->put('Parameters', $sensitive_aws);
             }
             //                TODO protect credentials from logging / output
             try {
                 $action == 'create' ? $this->cfn($stack)->createStack($cfn_params->toArray()) : $this->cfn($stack)->updateStack($cfn_params->toArray());
             } catch (CloudFormationException $e) {
                 if ($e->getMessage() != 'No updates are to be performed.') {
                     throw $e;
                 }
             } finally {
                 $this->destroyTemplate($stack, $bucket, $s3_template['key']);
             }
             break;
         case 'describe':
             Log::debug(__METHOD__);
             if ($stack->provisioned) {
                 $components = ComponentCollection::make($stack->components->all());
                 $cache_key = 'CloudFormer-DescribeStack-' . $stack->name;
                 if (($cf_response = Cache::get($cache_key)) === null) {
                     Log::debug('No cache for ' . $cache_key);
                     $cf_response = $this->cfn($stack)->describeStacks($cfn_params->toArray());
                     Cache::add($cache_key, $cf_response, self::CACHE_LIFETIME);
                 }
                 $cf_response = head($cf_response->get('Stacks'));
                 $stack->status = $this->translateAwsStatus($cf_response['StackStatus']);
                 $stack->outputs = Collection::make([]);
                 $distributedOutputs = $components->distributeResources(data_get($cf_response, 'Outputs', []), 'OutputKey');
                 $distributedOutputs->map(function (Collection $componentOutputs, $componentName) use($components, $stack) {
                     if (in_array($componentName, ['_stack', '_ungrouped'])) {
                         $stack->outputs = $stack->outputs->merge($componentOutputs);
                     } else {
                         $components[$componentName]->outputs = $componentOutputs;
                     }
                 });
                 $cache_key = 'CloudFormer-ListStackResources-' . $stack->name;
                 if (($cf_stack_resources = Cache::get($cache_key)) === null) {
                     Log::debug('No cache for ' . $cache_key);
                     $cf_stack_resources = $this->cfn($stack)->listStackResources($cfn_params->toArray())['StackResourceSummaries'];
                     Cache::add($cache_key, $cf_stack_resources, self::CACHE_LIFETIME);
                 }
                 $components->distributeResources($cf_stack_resources)->map(function (Collection $resources, $componentName) use($components, $stack) {
                     $status = $resources->reduce(function ($carry, $item) {
                         $itemStatus = $this->translateAwsStatus($item['ResourceStatus']);
                         if ($carry === null) {
                             return $itemStatus;
                         }
                         return $this->weighStatus($itemStatus) > $this->weighStatus($carry) ? $itemStatus : $carry;
                     });
                     if (!in_array($componentName, ['_stack', '_ungrouped']) && is_object($status)) {
                         $components[$componentName]->status = $status;
                     }
                 });
             }
             break;
         case 'delete':
             $this->cfn($stack)->deleteStack($cfn_params->toArray());
             break;
     }
     return $stack;
 }