Exemple #1
0
 /**
  * Makes api request
  *
  * @param   string     $qid     The id of the query.
  * @param   array      $options optional Query options for the request.
  * @param   string     $path    optional Uri path for the request (/user by default)
  * @param   string     $method  optional Http method (GET by default)
  * @return  object     Returns object that is an response data.
  * @throws  CloudynException
  */
 public function call($qid, array $options = array(), $path = '/user', $method = 'GET')
 {
     $options['qid'] = (string) $qid;
     $options['out'] = self::OUT_JSON;
     if (!isset($options['rqid'])) {
         $options['rqid'] = $this->getRequestId();
     }
     if (!isset($options['apiversion'])) {
         $options['apiversion'] = '0.4';
     }
     $this->request = $this->createNewRequest();
     $this->request->setRequestUrl($this->getUrl() . $path);
     $this->request->setRequestMethod($method);
     $this->request->setOptions(array('redirect' => 10, 'cookiesession' => true));
     $this->request->addQuery($options);
     $this->response = $this->tryCall($this->request);
     $json = $this->response->getBody()->toString();
     $json = preg_replace('#^[^\\{\\[]+|[^\\}\\]]+$#', '', trim($json));
     $obj = json_decode($json);
     if (isset($obj->status) && $obj->status != 'ok' && isset($obj->message)) {
         throw new CloudynException('Cloudyn error. ' . $obj->message);
     }
     return $obj;
 }
Exemple #2
0
 /**
  * Send message to instance
  * @param Scalr_Messaging_Msg $message
  * @return Scalr_Messaging_Msg
  */
 public function SendMessage(Scalr_Messaging_Msg $message, $isEventNotice = false, $delayed = false)
 {
     $startTime = microtime(true);
     if ($this->farmId && $message->getName() != 'BeforeHostTerminate') {
         if ($this->GetFarmObject()->Status == FARM_STATUS::TERMINATED) {
             $this->Db->Execute("UPDATE messages SET status = ? WHERE messageid = ?", array(MESSAGE_STATUS::FAILED, $message->messageId));
             return;
         }
     }
     // We don't need to send any messages other then it's own to the server that is not in Running state
     if ($message->serverId != $this->serverId && !in_array($this->status, array(SERVER_STATUS::RUNNING, SERVER_STATUS::TEMPORARY, SERVER_STATUS::IMPORTING))) {
         return;
     }
     // Ignore OLD messages (ami-scripts)
     if (!$this->IsSupported("0.5")) {
         return;
     }
     // Put access data and reserialize message
     $pl = PlatformFactory::NewPlatform($this->platform);
     $pl->PutAccessData($this, $message);
     $logger = \Scalr::getContainer()->logger('DBServer');
     $serializer = Scalr_Messaging_XmlSerializer::getInstance();
     $cryptoTool = \Scalr::getContainer()->srzcrypto($this->GetKey(true));
     if ($this->GetProperty(\SERVER_PROPERTIES::SZR_MESSAGE_FORMAT) == 'json') {
         $serializer = Scalr_Messaging_JsonSerializer::getInstance();
         $rawMessage = $serializer->serialize($message);
         $messageType = 'json';
     } else {
         $rawMessage = $serializer->serialize($message);
         $messageType = 'xml';
     }
     //$rawJsonMessage = @json_encode($message);
     $time = microtime(true) - $startTime;
     // Add message to database
     $this->Db->Execute("INSERT INTO messages SET\n                `messageid`             = ?,\n                `processing_time`       = ?,\n                `server_id`             = ?,\n                `event_server_id`       = ?,\n                `message`               = ?,\n                `type`                  = 'out',\n                `message_name`          = ?,\n                `handle_attempts`       = ?,\n                `message_version`       = ?,\n                `dtlasthandleattempt`   = NOW(),\n                `dtadded`               = NOW(),\n                `message_format`        = ?,\n                `event_id`              = ?\n            ON DUPLICATE KEY UPDATE handle_attempts = handle_attempts+1, dtlasthandleattempt = NOW()\n            ", array($message->messageId, $time, $this->serverId, $message->serverId, $rawMessage, $message->getName(), $delayed ? '0' : '1', 2, $messageType, isset($message->eventId) ? $message->eventId : ''));
     if ($delayed) {
         return $message;
     }
     $isVPC = false;
     if ($this->farmId) {
         if (DBFarm::LoadByID($this->farmId)->GetSetting(Entity\FarmSetting::EC2_VPC_ID)) {
             $isVPC = true;
         }
     }
     if (!$this->remoteIp && !$this->localIp && !$isVPC) {
         return;
     }
     $cryptoTool->setCryptoKey($this->GetKey(true));
     $encMessage = $cryptoTool->encrypt($rawMessage);
     $timestamp = date("c", time());
     $signature = $cryptoTool->sign($encMessage, null, $timestamp);
     try {
         $request = new Request();
         $request->setRequestMethod('POST');
         $ctrlPort = $this->getPort(self::PORT_CTRL);
         $requestHost = $this->getSzrHost() . ":{$ctrlPort}";
         if ($isVPC) {
             $routerFarmRoleId = $this->GetFarmRoleObject()->GetSetting(Scalr_Role_Behavior_Router::ROLE_VPC_SCALR_ROUTER_ID);
             if ($routerFarmRoleId) {
                 $routerRole = DBFarmRole::LoadByID($routerFarmRoleId);
             } else {
                 $routerRole = $this->GetFarmObject()->GetFarmRoleByBehavior(ROLE_BEHAVIORS::VPC_ROUTER);
             }
             if ($routerRole) {
                 // No public IP need to use proxy
                 if (!$this->remoteIp) {
                     $requestHost = $routerRole->GetSetting(Scalr_Role_Behavior_Router::ROLE_VPC_IP) . ":80";
                     $request->addHeaders(array("X-Receiver-Host" => $this->localIp, "X-Receiver-Port" => $ctrlPort));
                     // There is public IP, can use it
                 } else {
                     $requestHost = "{$this->remoteIp}:{$ctrlPort}";
                 }
             }
         }
         //Prepare request
         $request->setRequestUrl("http://{$requestHost}/control");
         $request->setOptions(array('timeout' => \Scalr::config('scalr.system.instances_connection_timeout'), 'connecttimeout' => \Scalr::config('scalr.system.instances_connection_timeout')));
         $request->addHeaders(array("Date" => $timestamp, "X-Signature" => $signature, 'X-Server-Id' => $this->serverId));
         if ($messageType == 'json') {
             $request->addHeaders(array('Content-type' => 'application/json'));
         }
         $request->append($encMessage);
         // Send request
         $response = \Scalr::getContainer()->srzhttp->sendRequest($request);
         // Process response
         if ($response->getResponseCode() == 201) {
             $logger->info(sprintf("[FarmID: %s] Sending message '%s' via REST to server '%s' (server_id: %s) completed", $this->farmId, $message->getName(), $this->remoteIp, $this->serverId));
             if (in_array($message->getName(), array('ExecScript'))) {
                 $this->Db->Execute("DELETE FROM messages WHERE messageid = ?", array($message->messageId));
             } else {
                 if ($messageType != 'json') {
                     $this->Db->Execute("UPDATE messages SET status = ?, message = '' WHERE messageid = ?", array(MESSAGE_STATUS::HANDLED, $message->messageId));
                 } else {
                     $this->Db->Execute("UPDATE messages SET status = ? WHERE messageid = ?", array(MESSAGE_STATUS::HANDLED, $message->messageId));
                 }
                 if (!empty($message->eventId)) {
                     $this->Db->Execute("UPDATE events SET msg_sent = msg_sent + 1 WHERE event_id = ?", array($message->eventId));
                 }
             }
         } else {
             $logger->warn(sprintf("[FarmID: %s] Cannot deliver message '%s' (message_id: %s) via REST" . " to server '%s' (server_id: %s). Error: %s %s", $this->farmId, $message->getName(), $message->messageId, $this->remoteIp, $this->serverId, $response->getResponseCode(), $response->getResponseStatus()));
         }
     } catch (http\Exception $e) {
         if (isset($e->innerException)) {
             $msg = $e->innerException->getMessage();
         } else {
             $msg = $e->getMessage();
         }
         if ($this->farmId) {
             $logger->warn(new FarmLogMessage($this->farmId, sprintf("Cannot deliver message '%s' (message_id: %s) via REST to server '%s' (server_id: %s). Error: %s", $message->getName(), $message->messageId, $this->remoteIp, $this->serverId, $msg), $this->serverId));
         } else {
             $logger->fatal(sprintf("Cannot deliver message '%s' (message_id: %s) via REST" . " to server '%s' (server_id: %s). Error: %s", $message->getName(), $message->messageId, $this->remoteIp, $this->serverId, $msg));
         }
         return false;
     }
     return $message;
 }
Exemple #3
0
 /**
  * Returns page with RabbitMQ role status
  *
  * @param  int $farmId     Identifier of the Farm
  * @param  int $farmRoleId optional Identifier of the FarmRole
  */
 public function statusAction($farmId, $farmRoleId = null)
 {
     $dbFarm = DBFarm::LoadByID($farmId);
     $this->user->getPermissions()->validate($dbFarm);
     $list = [];
     foreach ($dbFarm->GetFarmRoles() as $dbFarmRole) {
         if (!$dbFarmRole->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::RABBITMQ)) {
             continue;
         }
         $farmRole = ['id' => $dbFarmRole->ID, 'alias' => $dbFarmRole->Alias];
         if (empty($farmRoleId) && empty($list) || $dbFarmRole->ID == $farmRoleId) {
             $rabbitmq = [];
             $rabbitmq['status'] = '';
             $rabbitmq['showSetup'] = false;
             $rabbitmq['showStatusLabel'] = true;
             $cpUrl = $dbFarmRole->GetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_URL);
             if ($cpUrl) {
                 $serverId = $dbFarmRole->GetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_SERVER_ID);
                 try {
                     $dbServer = DBServer::LoadByID($serverId);
                     if ($dbServer->status == SERVER_STATUS::RUNNING) {
                         $rabbitmq['username'] = '******';
                         $rabbitmq['password'] = $dbFarmRole->GetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_PASSWORD);
                         $rabbitmq['url'] = $cpUrl;
                         $url = str_replace('/mgmt/', '/api/overview', $rabbitmq['url']);
                         $httpRequest = new Request();
                         $httpRequest->setRequestMethod('GET');
                         $httpRequest->setRequestUrl($url);
                         $httpRequest->setOptions(['redirect' => 5, 'timeout' => 30, 'connecttimeout' => 10]);
                         $httpRequest->setHeaders(array('Authorization' => 'Basic ' . base64_encode($rabbitmq['username'] . ':' . $rabbitmq['password'])));
                         $response = \Scalr::getContainer()->http->sendRequest($httpRequest);
                         $data = $response->getBody()->toString();
                         $result = json_decode($data, true);
                         if ($result) {
                             $rabbitmq['overview'] = $result;
                         }
                     } else {
                         throw new \Scalr\Exception\ServerNotFoundException();
                     }
                 } catch (\Scalr\Exception\ServerNotFoundException $e) {
                     $rabbitmq['status'] = "Control panel was installed, however server wasn't found";
                     $rabbitmq['showSetup'] = true;
                     $dbFarmRole->ClearSettings('rabbitmq.cp');
                 } catch (Exception $e) {
                     if (isset($e->innerException)) {
                         $msg = $e->innerException->getMessage();
                     } else {
                         $msg = $e->getMessage();
                     }
                     $rabbitmq['status'] = "Error retrieving information about control panel: \"{$msg}\"";
                 }
             } else {
                 if ($dbFarmRole->GetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_REQUESTED) == '1') {
                     if ($dbFarmRole->GetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_ERROR_MSG)) {
                         $rabbitmq['showSetup'] = true;
                         $rabbitmq['status'] = 'Server returned error: "' . $dbFarmRole->GetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_ERROR_MSG) . '"';
                     } else {
                         if ($dbFarmRole->GetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_REQUEST_TIME) > time() - self::REQUEST_TIMEOUT) {
                             $rabbitmq['status'] = "Request was sent at " . Scalr_Util_DateTime::convertTz((int) $dbFarmRole->GetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_REQUEST_TIME)) . ". Please wait...";
                         } else {
                             $rabbitmq['showSetup'] = true;
                             $rabbitmq['status'] = "Request timeout exceeded. Request was sent at " . Scalr_Util_DateTime::convertTz((int) $dbFarmRole->GetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_REQUEST_TIME));
                         }
                     }
                 } else {
                     if ($dbFarmRole->GetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_PASSWORD)) {
                         $rabbitmq['showSetup'] = true;
                     } else {
                         $rabbitmq['status'] = 'Rabbitmq cluster not initialized yet. Please wait ...';
                         $rabbitmq['showStatusLabel'] = false;
                     }
                 }
             }
             $rabbitmq['password'] = $dbFarmRole->GetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_PASSWORD);
             $farmRole['data'] = $rabbitmq;
         }
         $list[] = $farmRole;
     }
     $this->response->page('ui/services/rabbitmq/status.js', ['list' => $list]);
 }
Exemple #4
0
 private function request($path, $method, $data = "")
 {
     $data = trim($data);
     $httpRequest = new Request();
     $httpRequest->setSslOptions(['verifypeer' => false, 'verifyhost' => false]);
     $fullUrl = "{$this->chefServerUrl}{$path}";
     $chunks = parse_url($fullUrl);
     if (in_array($method, ["POST", "PUT"]) && $data) {
         $httpRequest->append($data);
     }
     $httpRequest->setRequestUrl($fullUrl);
     $httpRequest->setRequestMethod($method);
     $tz = @date_default_timezone_get();
     date_default_timezone_set("UTC");
     $timestamp = date("Y-m-d\\TH:i:s\\Z");
     date_default_timezone_set($tz);
     $chunks['path'] = str_replace('//', '/', $chunks['path']);
     $hashedPath = base64_encode(sha1($chunks['path'], true));
     $hashedBody = base64_encode(sha1($data, true));
     $userId = $this->username;
     $str = "Method:{$method}\n" . "Hashed Path:{$hashedPath}\n" . "X-Ops-Content-Hash:{$hashedBody}\n" . "X-Ops-Timestamp:{$timestamp}\n" . "X-Ops-UserId:{$userId}";
     $headers = array('x-ops-sign' => "algorithm=sha1;version=1.0", 'x-chef-version' => "0.10.8", 'x-ops-userid' => $userId, 'x-ops-timestamp' => $timestamp, 'x-ops-content-hash' => $hashedBody, 'content-type' => 'application/json', 'accept' => 'application/json');
     $r = array_merge($headers, $this->sign($str));
     $httpRequest->addHeaders($r);
     $response = \Scalr::getContainer()->http->sendRequest($httpRequest);
     if ($response->getResponseCode() == 401) {
         throw new Exception("Failed to authenticate as {$userId}. Ensure that your node_name and client key are correct.");
     }
     if ($response->getResponseCode() == 404) {
         throw new Exception("Client not found or parameters are not valid");
     } else {
         if ($response->getResponseCode() <= 205) {
             $data = $response->getBody()->toString();
             $retval = empty($data) ? true : json_decode($data);
         } else {
             if ($response->getResponseCode() >= 300 && $response->getResponseCode() < 400) {
                 throw new Exception("Request to chef server failed. Chef server returned code {$response->getResponseCode()}. Redirect URL: {$response->getHeader("Location")}");
             } else {
                 if ($response->getResponseCode() > 400) {
                     $data = $response->getBody()->toString();
                     $msg = empty($data) ? "" : json_decode($data);
                     if (is_array($msg->error)) {
                         $msg = $msg->error[0];
                     } elseif ($msg->error) {
                         $msg = $msg->error;
                     } else {
                         $msg = "Unknown error. Error code: {$response->getResponseCode()}";
                     }
                     throw new Exception("Request to chef server failed with error: {$msg} ({$method} {$path})");
                 } else {
                     throw new Exception("Unexpected situation. Response code {$response->getResponseCode()}");
                 }
             }
         }
     }
     return $retval;
 }
Exemple #5
0
 /**
  * {@inheritdoc}
  * @see Scalr\Service\CloudStack\Client.ClientInterface::call()
  */
 public function call($command, array $args = null, $verb = 'GET')
 {
     $attempts = 3;
     if ($args === null) {
         $args = array();
     }
     foreach ($args as $key => $value) {
         if (is_null($value)) {
             unset($args[$key]);
         }
         // Workaround for zones.
         if ($key == 'zoneid' && !is_null($value)) {
             if (empty($this->zonesCache)) {
                 foreach ($this->cloudstack->zone->describe() as $zone) {
                     $this->zonesCache[$zone->name] = $zone->id;
                 }
             }
             if (!empty($this->zonesCache[$value])) {
                 $args[$key] = $this->zonesCache[$value];
             } else {
                 throw new RestClientException("Availability zone '{$value}' no longer supported");
             }
         }
     }
     $args['apikey'] = $this->apiKey;
     $args['command'] = $command;
     $args['response'] = 'json';
     ksort($args);
     $query = http_build_query($args, null, '&', PHP_QUERY_RFC3986);
     if ('GET' == $verb) {
         $query .= "&signature=" . $this->getSignature(strtolower($query));
     } else {
         $args['signature'] = $this->getSignature(strtolower($query));
     }
     $httpRequest = new Request();
     $httpRequest->setRequestMethod($verb);
     $url = 'GET' == $verb ? $this->endpoint . "?" . $query : $this->endpoint;
     $httpRequest->setRequestUrl($url);
     if ('POST' == $verb) {
         $httpRequest->append($args);
     }
     $message = $this->tryCall($httpRequest, $attempts);
     $response = new QueryClientResponse($message, $command);
     $response->setRawRequestMessage($httpRequest->toString());
     if ($this->debug) {
         echo "\nURL: " . $httpRequest->getRequestUrl() . "\n", "{$httpRequest}\n", "{$response->getResponse()}\n";
     }
     return $response;
 }