diff --git a/src/App/Service/CiExecutorService.php b/src/App/Service/CiExecutorService.php index 95a2365..86b251b 100644 --- a/src/App/Service/CiExecutorService.php +++ b/src/App/Service/CiExecutorService.php @@ -18,6 +18,7 @@ class CiExecutorService const CONFIG_1_PATH = '/me/my-views/view/Configuration/job/Config_1_edvidan'; const CONFIG_2_PATH = '/me/my-views/view/Configuration/job/manual_config_2_edvidan'; const ADD_JCAT_PATH = '/view/Tools/job/JCAT_deploy_handler_tool'; + const NIGHTLY_CONFIG_PATH = '/view/Tools/job/Nightly_config_cleaner_tool'; const JCAT_DEPLOY_SOURCE_URL = 'http://jcat.tsp.eth.ericsson.se/www/autotest/deploy'; @@ -70,9 +71,10 @@ class CiExecutorService public function debug() { - /** @var CiConfig $config */ - $config = $this->entityManager->find(CiConfig::class, 20170317); - return $this->runTest($config->getConfigItems()->first()); +// /** @var CiConfig $config */ +// $config = $this->entityManager->find(CiConfig::class, 20170317); +// return $this->runTest($config->getConfigItems()->first()); + return $this->getActiveNightlyConfiguration(); } /** @@ -224,7 +226,7 @@ class CiExecutorService } } - $this->buildConfigTwo($configItem, $package, $nodes, $nodeBases, $nodeTraffics); +// $this->buildConfigTwo($configItem, $package, $nodes, $nodeBases, $nodeTraffics); return [ "config1ok"=> $config1Status, @@ -356,6 +358,24 @@ class CiExecutorService return $response->getBody(); } + /** + * @return string + * @throws \Exception + * @todo investigate why GET method on the config page returns HTTP405 + */ + private function getNightlyConfigHtml(): string + { + $this->httpClient->setUri($this->jenkinsBaseUrl . self::NIGHTLY_CONFIG_PATH . "/build"); + $this->httpClient->resetParameters(false, false); + $request = $this->httpClient->getRequest(); + $request->setMethod('GET'); + $response = $this->httpClient->send(); + if ($response->getStatusCode() == 401) { + throw new \Exception("Not authenticated"); + } + return $response->getBody(); + } + private function getStaplerTokens($config2Body, $blockName = "STREAM") { $pattern = '#referencedParameters\.push\("%s"\);.*?makeStaplerProxy\(\'(.*?)\',\'(.*?)\'.*?// Create#msi'; @@ -370,28 +390,7 @@ class CiExecutorService private function getStreams($config2Body) { - $cssToXpathConverter = new CssSelectorConverter(); - $xpathQuery = $cssToXpathConverter->toXPath('input[value=STREAM]'); - - $domDocument = new \DOMDocument(); - $domDocument->loadHTML($config2Body); - - $xpath = new \DOMXPath($domDocument); - $element = $xpath->query($xpathQuery); - - if ($element->length == 0) { - throw new \Exception("Can't find STREAM"); - } - - if ($element[0]->nextSibling->nodeName != "select") { - throw new \Exception("Can't find STREAM dropdown"); - } - - $streams = []; - foreach ($element[0]->nextSibling->childNodes as $option) { - $streams[] = $option->textContent; - } - + $streams = $this->getHtmlDropdownValues($config2Body, "STREAM"); sort($streams, SORT_NATURAL); return array_values(array_filter(array_unique($streams), function ($item) { return $item != "" && $item != "none"; @@ -400,30 +399,8 @@ class CiExecutorService private function getPackage($stream, $url, $token): string { - $this->httpClient->setUri($this->jenkinsBaseUrl . $url . '/doUpdate'); - $this->httpClient->resetParameters(false, false); - $headers = $this->httpClient->getRequest()->getHeaders(); - $headers->addHeaderLine("Crumb", $token); - $headers->addHeaderLine("Content-type", "application/x-stapler-method-invocation;charset=UTF-8"); - $request = $this->httpClient->getRequest(); - $request->setMethod('POST'); - $request->setContent(sprintf('["STREAM=%s"]', $stream)); - $updateResponse = $this->httpClient->send(); - if (!$updateResponse->isSuccess()) { - throw new \Exception("Stapler doUpdate error"); - } - sleep(1); - $this->httpClient->setUri($this->jenkinsBaseUrl . $url . '/getChoicesForUI'); - $request->setContent("[]"); - $choicesResponse = $this->httpClient->send(); - if (!$choicesResponse->isSuccess()) { - throw new \Exception("Stapler getChoicesForUI error"); - } - $packages = Json::decode($choicesResponse->getBody()); - if ($packages[0][0] == "Script error") { - throw new \Exception("STREAM stapler script error"); - } - return array_shift($packages[0]); + $packageStaplerData = $this->getStaplerData("STREAM", $stream, $url, $token); + return array_shift($packageStaplerData); } /** @@ -434,33 +411,34 @@ class CiExecutorService */ private function getJcatVersions($url, $token) { - // v1 -// $cssToXpathConverter = new CssSelectorConverter(); -// $xpathQuery = $cssToXpathConverter->toXPath('input[value=JCAT_DIR__MAIN]'); -// -// $domDocument = new \DOMDocument(); -// $domDocument->loadHTML($config2Body); -// -// $xpath = new \DOMXPath($domDocument); -// $element = $xpath->query($xpathQuery); -// -// if($element->length == 0) { -// throw new \Exception("Can't find JCAT_DIR__MAIN"); -// } -// -// if($element[0]->nextSibling->nodeName != "select") { -// throw new \Exception("Can't find JCAT dropdown"); -// } -// -// $jcatVersions = []; -// foreach ($element[0]->nextSibling->childNodes as $option) { -// $jcatVersions[] = $option->textContent; -// } -// -// rsort($jcatVersions, SORT_NATURAL); -// return array_values(array_filter(array_unique($jcatVersions), function($item){return $item != "";})); + $jcatStaplerData = $this->getStaplerData("JCAT_TYPE", "INSTALLED", $url, $token); + rsort($jcatStaplerData); + return $jcatStaplerData; + } - // v2 + /** + * @param $stream + * @param $url + * @param $token + * @return mixed + */ + private function getNightlyNodesForStream($stream, $url, $token) + { + return $this->getStaplerData("STREAM", $stream, $url, $token); + } + + /** + * Returns a single dimensional array of select options + * + * @param $parameter + * @param $value + * @param $url + * @param $token + * @return mixed + * @throws \Exception + */ + private function getStaplerData($parameter, $value, $url, $token) + { $this->httpClient->setUri($this->jenkinsBaseUrl . $url . '/doUpdate'); $this->httpClient->resetParameters(false, false); $headers = $this->httpClient->getRequest()->getHeaders(); @@ -468,7 +446,7 @@ class CiExecutorService $headers->addHeaderLine("Content-type", "application/x-stapler-method-invocation;charset=UTF-8"); $request = $this->httpClient->getRequest(); $request->setMethod('POST'); - $request->setContent('["JCAT_TYPE=INSTALLED"]'); + $request->setContent(sprintf('["%s=%s"]', $parameter, $value)); $updateResponse = $this->httpClient->send(); if (!$updateResponse->isSuccess()) { throw new \Exception("Stapler doUpdate error"); @@ -480,38 +458,16 @@ class CiExecutorService if (!$choicesResponse->isSuccess()) { throw new \Exception("Stapler getChoicesForUI error"); } - $jcats = Json::decode($choicesResponse->getBody()); - rsort($jcats[0]); - if ($jcats[0][0] == "Script error") { - throw new \Exception("JCAT stapler script error"); + $staplerData = Json::decode($choicesResponse->getBody()); + if ($staplerData[0][0] == "Script error") { + throw new \Exception(sprintf("%s stapler script error", $parameter)); } - return $jcats[0]; + return $staplerData[0]; } private function getNodeBaseNames($config2Body, $nodeName) { - $cssToXpathConverter = new CssSelectorConverter(); - $xpathQuery = $cssToXpathConverter->toXPath(sprintf('input[value=%s_BASE_BACKUP]', $nodeName)); - - $domDocument = new \DOMDocument(); - $domDocument->loadHTML($config2Body); - - $xpath = new \DOMXPath($domDocument); - $element = $xpath->query($xpathQuery); - - if ($element->length == 0) { - throw new \Exception(sprintf("Can't find %s_BASE_BACKUP", $nodeName)); - } - - if ($element[0]->nextSibling->nodeName != "select") { - throw new \Exception(sprintf("Can't find %s_BASE_BACKUP dropdown", $nodeName)); - } - - $baseNames = []; - foreach ($element[0]->nextSibling->childNodes as $option) { - $baseNames[] = $option->textContent; - } - + $baseNames = $this->getHtmlDropdownValues($config2Body, sprintf("%s_BASE_BACKUP", $nodeName)); rsort($baseNames, SORT_NATURAL); return array_filter($baseNames, function ($item) { return $item != ""; @@ -520,28 +476,7 @@ class CiExecutorService private function getNodeTrafficConfigs($config2Body, $nodeName) { - $cssToXpathConverter = new CssSelectorConverter(); - $xpathQuery = $cssToXpathConverter->toXPath(sprintf('input[value=%s_TRAFFIC]', $nodeName)); - - $domDocument = new \DOMDocument(); - $domDocument->loadHTML($config2Body); - - $xpath = new \DOMXPath($domDocument); - $element = $xpath->query($xpathQuery); - - if ($element->length == 0) { - throw new \Exception(sprintf("Can't find %s_TRAFFIC", $nodeName)); - } - - if ($element[0]->nextSibling->nodeName != "select") { - throw new \Exception(sprintf("Can't find %s_TRAFFIC dropdown", $nodeName)); - } - - $trafficConfigs = []; - foreach ($element[0]->nextSibling->childNodes as $option) { - $trafficConfigs[] = $option->textContent; - } - + $trafficConfigs = $this->getHtmlDropdownValues($config2Body, sprintf("%s_TRAFFIC", $nodeName)); rsort($trafficConfigs, SORT_NATURAL); return array_filter($trafficConfigs, function ($item) { return $item != ""; @@ -737,29 +672,7 @@ class CiExecutorService $this->httpClient->resetParameters(false, false); $response = $this->httpClient->send(); $jcatHandlerPageBody = $response->getBody(); - - $cssToXpathConverter = new CssSelectorConverter(); - $xpathQuery = $cssToXpathConverter->toXPath('input[value=NODES]'); - - $domDocument = new \DOMDocument(); - $domDocument->loadHTML($jcatHandlerPageBody); - - $xpath = new \DOMXPath($domDocument); - $element = $xpath->query($xpathQuery); - - if ($element->length == 0) { - throw new \Exception("Can't find NODES"); - } - - if ($element[0]->nextSibling->nodeName != "select") { - throw new \Exception("Can't find NODES dropdown"); - } - - $trafficConfigs = []; - foreach ($element[0]->nextSibling->childNodes as $option) { - $trafficConfigs[] = $option->textContent; - } - + $trafficConfigs = $this->getHtmlDropdownValues($jcatHandlerPageBody, "NODES"); sort($trafficConfigs, SORT_NATURAL); return $trafficConfigs; } @@ -779,6 +692,47 @@ class CiExecutorService throw new \Exception("Jenkins redirect url is not working, return code was: " . $response->getStatusCode()); } + public function getActiveNightlyConfiguration() + { + $nightlyConfigHtml = $this->getNightlyConfigHtml(); + $streams = $this->getHtmlDropdownValues($nightlyConfigHtml, "STREAM"); + + sort($streams, SORT_NATURAL); + $stapler = $this->getStaplerTokens($nightlyConfigHtml, "STREAM"); + + $result = []; + foreach($streams as $stream) { + $result[$stream] = $this->getNightlyNodesForStream($stream, $stapler['url'], $stapler['token']); + } + return $result; + } + + private function getHtmlDropdownValues(string $html, string $fieldName): array + { + $cssToXpathConverter = new CssSelectorConverter(); + $xpathQuery = $cssToXpathConverter->toXPath(sprintf('input[value=%s]', $fieldName)); + + $domDocument = new \DOMDocument(); + $domDocument->loadHTML($html); + + $xpath = new \DOMXPath($domDocument); + $element = $xpath->query($xpathQuery); + + if ($element->length == 0) { + throw new \Exception(sprintf("Can't find %s", $fieldName)); + } + + if ($element[0]->nextSibling->nodeName != "select") { + throw new \Exception(sprintf("Can't find %s dropdown", $fieldName)); + } + + $values = []; + foreach ($element[0]->nextSibling->childNodes as $option) { + $values[] = $option->textContent; + } + return $values; + } + public function isNodeOnline(string $node): bool { $this->httpClient->setUri($this->jenkinsBaseUrl . self::NODE_STATUS_PATH . "/${node}/api/json");