/**
  * @param Account $account
  */
 public function removeAccount(Account $account)
 {
     $workspaces = new Workspaces($this->getClient());
     try {
         $workspaces->deleteWorkspace($account->getWorkspaceId(), ["async" => true]);
     } catch (\Keboola\StorageApi\Exception $e) {
         $this->logException(Logger::DEBUG, $e->getMessage(), $e);
     }
 }
Beispiel #2
0
 /**
  * @param Account $account
  */
 protected function dropDatabase(Account $account)
 {
     // User current users credentials to see available databases
     $conn = $this->connect($account->getDatabase());
     $databases = $conn->fetchArray("SHOW DATABASES WHERE `Database` = '{$account->getDatabase()}';");
     if (is_array($databases) && in_array($account->getDatabase(), $databases)) {
         $privileges = $conn->fetchAll("\n                SELECT\n                  *\n                FROM information_schema.schema_privileges\n                WHERE\n                  TABLE_SCHEMA = '{$account->getDatabase()}'\n                  AND SUBSTR(SUBSTRING_INDEX(GRANTEE, '\\'@', 1), 2) != '{$account->getUser()}';\n            ");
         // Drop only if no other users have access to the db
         if (count($privileges) == 0) {
             $conn->exec("DROP DATABASE {$account->getDatabase()};");
         }
     }
     $conn->close();
 }
 /**
  * @param Account $account
  * @param Connection $conn
  * @param $tokenInfo
  * @param $buckets
  * @throws DBALException
  */
 protected function grantPermissionsTry(Account $account, Connection $conn, $tokenInfo, $buckets)
 {
     $userName = $account->getUser();
     $allowedBuckets = array();
     if ($account->getType() == 'transformations' || $account->getType() == 'sandbox' || $account->getType() == 'luckyguess') {
         foreach ($buckets as $bucket) {
             if ((substr($bucket["id"], 0, 3) == 'in.' || substr($bucket["id"], 0, 4) == 'out.') && $bucket["backend"] == 'redshift' && in_array($bucket["id"], array_keys($tokenInfo["bucketPermissions"]))) {
                 $allowedBuckets[] = strtolower($bucket["id"]);
             }
         }
     }
     // Set custom permissions
     if (count($allowedBuckets) > 0) {
         // Tables
         $query = "\n                SELECT TRIM(schemaname) AS schema, TRIM(tablename) AS table\n                FROM pg_tables\n                WHERE TRIM(schemaname) IN ('" . join("', '", $allowedBuckets) . "');\n            ";
         $tablesInRs = $conn->fetchAll($query);
         $schemaNames = array();
         if (count($tablesInRs)) {
             $tableIds = array();
             foreach ($tablesInRs as $tableInRs) {
                 if (substr($tableInRs["table"], 0, 6) != '__temp') {
                     $tableIds[] = '"' . strtolower($tableInRs["schema"]) . '"."' . strtolower($tableInRs["table"]) . '"';
                     $schemaNames[] = '"' . strtolower($tableInRs["schema"]) . '"';
                 }
             }
             $query = "\n                    GRANT SELECT\n                    ON " . join(', ', $tableIds) . "\n                    TO {$userName};\n                ";
             $conn->exec($query);
         }
         // Views
         $query = "\n                SELECT TRIM(schemaname) AS schema, TRIM(viewname) AS view\n                FROM pg_views\n                WHERE TRIM(schemaname) IN ('" . join("', '", $allowedBuckets) . "');\n            ";
         $viewsInRs = $conn->fetchAll($query);
         if (count($viewsInRs)) {
             $viewIds = array();
             foreach ($viewsInRs as $viewInRs) {
                 $viewIds[] = '"' . strtolower($viewInRs["schema"]) . '"."' . strtolower($viewInRs["view"]) . '"';
                 $schemaNames[] = '"' . strtolower($viewInRs["schema"]) . '"';
             }
             $query = "\n                    GRANT SELECT\n                    ON " . join(', ', $viewIds) . "\n                    TO {$userName};\n                ";
             $conn->exec($query);
         }
         // Schemas
         if (count($schemaNames)) {
             $schemaNames = array_unique($schemaNames);
             $query = "\n                    GRANT USAGE\n                    ON SCHEMA " . join(', ', $schemaNames) . "\n                    TO {$userName};\n                ";
             $conn->exec($query);
         }
     }
     // system tables
     if ($account->getType() == "transformations") {
         $query = "\n   \t\t\t\tGRANT SELECT\n   \t\t\t\tON SVV_TABLE_INFO\n   \t\t\t\tTO {$account->getUser()};\n   \t\t\t";
         $conn->exec($query);
     }
     // Grant access to its own schema
     if ($account->getType() == 'read') {
         $conn->exec("GRANT USAGE ON SCHEMA \"{$account->getSchema()}\" TO \"{$account->getUser()}\";");
         $conn->exec("GRANT SELECT ON ALL TABLES IN SCHEMA \"{$account->getSchema()}\" TO \"{$account->getUser()}\";");
     } else {
         $conn->exec("GRANT ALL ON SCHEMA \"{$account->getSchema()}\" TO \"{$account->getUser()}\";");
     }
 }
Beispiel #4
0
 /**
  * @param Account $account
  * @return bool
  * @throws InvalidCredentialsException
  */
 public function validateAccount(Account $account)
 {
     if (!$this->isAlive() || !$account->isAlive()) {
         $this->dropAccount($account);
         throw new InvalidCredentialsException();
     }
     return true;
 }
 /**
  * @param Account $account
  */
 protected function dropDatabase(Account $account)
 {
     // User current users credentials to see available databases
     $conn = $this->connect($account->getDatabase());
     $databases = $conn->fetchArray("SHOW DATABASES WHERE `Database` = '{$account->getDatabase()}';");
     if (is_array($databases) && in_array($account->getDatabase(), $databases)) {
         $conn->exec("DROP DATABASE {$account->getDatabase()};");
     }
     $conn->close();
 }
Beispiel #6
0
 /**
  * @param Account $account Docker account
  * @return \Keboola\ProvisioningBundle\Entity\Server[]
  * @throws Exception
  */
 public function getServersByAccount(Account $account)
 {
     /** @var Account\Docker $account */
     $cluster = $account->getCluster();
     $servers = $this->getRepository()->findBy(array("cluster" => $cluster, "active" => true));
     if (count($servers) === 0) {
         throw new NoActiveServerException("No active '{$this->getBackend()}' server found.");
     }
     return $servers;
 }
Beispiel #7
0
 /**
  * @param Account $account
  */
 public function removeAccount(Account $account)
 {
     $servers = $this->getServersByHostname($account->getHostname());
     if (!$servers || !isset($servers[0]) || !$servers[0]) {
         return;
     }
     $server = $servers[0];
     if ($account->getGroupId()) {
         $accounts = $this->getAccountRepository()->findBy(array("hostname" => $account->getHostname(), "groupId" => $account->getGroupId(), "active" => true));
         $otherAccounts = array();
         foreach ($accounts as $item) {
             if ($item->getId() != $account->getId()) {
                 $otherAccounts[] = $item;
             }
         }
         if (!count($otherAccounts)) {
             $server->dropAccount($account);
         } else {
             try {
                 $server->killProcesses($account);
                 $server->revokePermission($account, $account->getDatabase());
             } catch (InvalidCredentialsException $e) {
                 // Skip this exception
             }
         }
     } else {
         $server->dropAccount($account);
     }
 }
Beispiel #8
0
 /**
  * Create and start a new docker sandbox.
  *
  * @param Account $account
  * @throws Exception
  */
 public function addAccount(Account $account)
 {
     /** @var Account\Docker $account */
     $ecsClient = $this->getEcsClient();
     $ec2Client = $this->getEc2Client();
     $imageName = $this->getDockerImageByType($account->getType());
     $selectedPort = random_int(self::MIN_PORT, self::MAX_PORT);
     // Start the container
     try {
         $taskDefinition = $this->getTaskDefinition($this->getTaskName($account), $imageName, $selectedPort, $this->getContainerPortByType($account->getType()));
         $res = $ecsClient->registerTaskDefinition($taskDefinition)->toArray();
         $this->checkResponseSuccess($res);
         $taskId = $res['taskDefinition']['family'] . ':' . $res['taskDefinition']['revision'];
         $res = $ecsClient->runTask($this->getRunTaskDefinition($taskId, $imageName, $account->getToken(), $this->exportConfig, $this->script, $account, $this->runId))->toArray();
         $this->checkResponseSuccess($res);
         $taskArn = $res['tasks'][0]['taskArn'];
     } catch (EcsException $e) {
         $this->logException(Logger::ERROR, $e->getMessage(), $e);
         throw $e;
     } catch (Exception $e) {
         $this->logException(Logger::ERROR, $e->getMessage(), $e);
         throw $e;
     }
     // Wait for the task to start
     $attempt = 0;
     do {
         $attempt++;
         sleep(min(pow(2, $attempt), self::MAX_WAIT_DELAY));
         $res = $ecsClient->describeTasks(['cluster' => $this->getCluster(), 'tasks' => [$taskArn]])->toArray();
         $this->checkResponseSuccess($res);
     } while ($res['tasks'][0]['lastStatus'] == 'PENDING');
     if ($res['tasks'][0]['lastStatus'] != 'RUNNING') {
         throw new Exception("ECS task did not start successfully. " . !empty($res['tasks'][0]['stoppedReason']) ? $res['tasks'][0]['stoppedReason'] : '');
     }
     // Determine container EC2 instance ID
     $taskContainerArn = $res['tasks'][0]['containerInstanceArn'];
     $result = $ecsClient->describeContainerInstances(['containerInstances' => [$taskContainerArn], 'cluster' => $this->getCluster()])->toArray();
     // Get DNS name of EC2 instance
     $ec2InstanceId = $result['containerInstances'][0]['ec2InstanceId'];
     $result = $ec2Client->describeInstances(['InstanceIds' => [$ec2InstanceId]])->toArray();
     $dns = $result['Reservations'][0]['Instances'][0]['PublicDnsName'];
     $account->setArn($taskArn);
     $account->setPort($selectedPort);
     $account->setHostname($dns);
 }