protected function executeWithStack(Stack $stack, InputInterface $input, OutputInterface $output) { $this->dependencyTracker->reset(); foreach ($this->blueprintFactory->getAllBlueprints() as $blueprint) { $blueprint->getPreprocessedTemplate(); } $dependants = $this->dependencyTracker->findDependantsForStack($stack->getName()); $rows = []; foreach ($dependants as $dependant) { $rows[] = [$dependant['targetType'] . ':' . $dependant['targetResource'], $dependant['type'] . ':' . $dependant['blueprint'] . ':' . $dependant['key']]; } $output->writeln("Following blueprints depend on stack '{$stack->getName()}':"); $table = new Table($output); $table->setHeaders(['Origin (Stack: ' . $stack->getName() . ')', 'Blueprint'])->setRows($rows)->render(); }
public function compare() { if (empty($this->stack)) { throw new \InvalidArgumentException('Stack not set'); } if (empty($this->blueprint)) { throw new \InvalidArgumentException('Blueprint not set'); } $tmp = []; try { // parameters if ($this->output->isVerbose()) { $this->output->writeln($this->stack->getName() . ': Comparing parameters'); } $parametersStack = $this->stack->getParameters(); $parametersBlueprint = $this->blueprint->getParameters(true); $parametersBlueprint = Div::flatten($parametersBlueprint, 'ParameterKey', 'ParameterValue'); if ($this->parametersAreEqual($parametersStack, $parametersBlueprint)) { $tmp['parameters'] = "<fg=green>equal</>"; } else { $tmp['parameters'] = "<fg=red>different</>"; $tmp['error'] = true; } // template if ($this->output->isVerbose()) { $this->output->writeln($this->stack->getName() . ': Comparing template'); } $templateStack = trim($this->stack->getTemplate()); $templateBlueprint = trim($this->blueprint->getPreprocessedTemplate()); $templateStack = $this->normalizeJson($templateStack); $templateBlueprint = $this->normalizeJson($templateBlueprint); if ($templateStack === $templateBlueprint) { $tmp['template'] = "<fg=green>equal</>"; } else { $tmp['template'] = "<fg=red>different</>"; $tmp['error'] = true; } } catch (CloudFormationException $e) { $tmp['parameters'] = 'Stack not found'; $tmp['template'] = 'Stack not found'; $tmp['error'] = true; } catch (\Exception $e) { $tmp['parameters'] = '<fg=red>EXCEPTION: ' . $e->getMessage() . '</>'; $tmp['template'] = 'EXCEPTION'; $tmp['error'] = true; } return $tmp; }
public function testName() { $this->assertEquals('test-stack1', $this->stack->getName()); }
protected function executeWithStack(Stack $stack, InputInterface $input, OutputInterface $output) { $events = $stack->getEvents(); $groups = []; $itemsByGroup = []; foreach ($events as $event) { $groupId = $event['LogicalResourceId']; if (!isset($groups[$groupId])) { $groups[$groupId] = ['id' => $groupId, 'content' => '<strong>' . $groupId . '</strong><br /><em>' . $event["ResourceType"] . '</em>', 'first_event' => $event["Timestamp"]]; } $status = $event["ResourceStatus"]; if (isset($itemsByGroup[$groupId])) { $lastItem = end($itemsByGroup[$groupId]); $lastKey = key($itemsByGroup[$groupId]); if ($lastItem['status'] == $status) { continue; } $duration = strtotime($event["Timestamp"]) - strtotime($itemsByGroup[$groupId][$lastKey]['start']); if ($duration > 15) { $content = floor($duration / 60) . ':' . sprintf("%02d", (int) $duration % 60); $itemsByGroup[$groupId][$lastKey]['content'] = $content; } $itemsByGroup[$groupId][$lastKey]['end'] = $event["Timestamp"]; } $tmp = ['className' => strtolower($status) . ' ' . strtolower(preg_replace('/[^a-zA-Z0-9]/', '-', $event["ResourceType"])), 'group' => $groupId, 'start' => $event["Timestamp"], 'content' => ' ', 'status' => $status]; if (!preg_match('/_IN_PROGRESS$/', $status)) { $tmp['type'] = 'point'; } if (preg_match('/_IN_PROGRESS$/', $status)) { $tmp['className'] .= ' in_progress'; } if (preg_match('/_COMPLETE$/', $status)) { $tmp['className'] .= ' complete'; } if (preg_match('/_FAILED$/', $status)) { $tmp['className'] .= ' failed'; } $itemsByGroup[$groupId][] = $tmp; } $items = []; foreach ($itemsByGroup as $group) { $items = array_merge($items, $group); } $timeline = '<!DOCTYPE HTML> <html> <head> <title>AWS CloudFormation Stack Event Visualization</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.4/moment.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.12.0/vis.min.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.12.0/vis.min.css" rel="stylesheet" type="text/css" /> <style> body, html { font-family: arial, sans-serif; font-size: 11pt; } #visualization { box-sizing: border-box; width: 100%; height: 300px; } .vis-item { border-width: 0; } .vis-item.in_progress { background-color: orange; } .vis-item.failed { border-color: red; border-width: 8px; border-radius: 8px; } .vis-item.complete { border-color: green; border-width: 8px; border-radius: 8px; } em { font-size: smaller; } .vis-labelset .vis-label { background-color: #eee; } .vis-item.aws--cloudformation--waitcondition.in_progress { background: repeating-linear-gradient(to right, #f6ba52, #f6ba52 10px, #ffd180 10px, #ffd180 20px); } </style> </head> <body> <h1>' . $stack->getName() . '</h1> <div id="visualization"></div> <script> var groups = new vis.DataSet(); var items = new vis.DataSet(); groups.add(' . json_encode(array_values($groups)) . '); items.add(' . json_encode(array_values($items)) . '); var timeline = new vis.Timeline(document.getElementById("visualization")); timeline.setOptions({ stack: false, groupOrder: "first_event" }); timeline.setGroups(groups); timeline.setItems(items); </script> </body> </html>'; $output->writeln($timeline); }