chg: [sync] Simplify galaxy cluster pushing

pull/8205/head
Jakub Onderka 2022-03-13 13:06:11 +01:00
parent 0326d35387
commit d8fd3e937a
3 changed files with 49 additions and 144 deletions

View File

@ -1,5 +1,6 @@
<?php
App::uses('SyncTool', 'Tools');
App::uses('JsonTool', 'Tools');
class ServerSyncTool
{
@ -10,7 +11,9 @@ class ServerSyncTool
FEATURE_PROPOSALS = 'proposals',
FEATURE_PROTECTED_EVENT = 'protected_event',
FEATURE_POST_TEST = 'post_test',
FEATURE_EDIT_OF_GALAXY_CLUSTER = 'edit_of_galaxy_cluster';
FEATURE_EDIT_OF_GALAXY_CLUSTER = 'edit_of_galaxy_cluster',
PERM_SYNC = 'perm_sync',
PERM_GALAXY_EDITOR = 'perm_galaxy_editor';
/** @var array */
private $server;
@ -197,6 +200,18 @@ class ServerSyncTool
return $this->get('/galaxy_clusters/view/' . $galaxyClusterId);
}
/**
* @param array $cluster
* @return HttpSocketResponseExtended
* @throws HttpSocketHttpException
* @throws HttpSocketJsonException
*/
public function pushGalaxyCluster(array $cluster)
{
$logMessage = "Pushing Galaxy Cluster #{$cluster['GalaxyCluster']['id']} to Server #{$this->serverId()}";
return $this->post('/galaxies/pushCluster', [$cluster], $logMessage);
}
/**
* @param array $params
* @return HttpSocketResponseExtended
@ -367,6 +382,10 @@ class ServerSyncTool
return $version[0] == 2 && $version[1] == 4 && $version[2] > 155;
case self::FEATURE_EDIT_OF_GALAXY_CLUSTER:
return isset($info['perm_galaxy_editor']);
case self::PERM_SYNC:
return isset($info['perm_sync']) && $info['perm_sync'];
case self::PERM_GALAXY_EDITOR:
return isset($info['perm_galaxy_editor']) && $info['perm_galaxy_editor'];
default:
throw new InvalidArgumentException("Invalid flag `$flag` provided");
}
@ -408,7 +427,7 @@ class ServerSyncTool
private function post($url, $data, $logMessage = null)
{
$protectedMode = !empty($data['Event']['protected']);
$data = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$data = JsonTool::encode($data);
if ($logMessage && !empty(Configure::read('Security.sync_audit'))) {
$pushLogEntry = sprintf(

View File

@ -628,13 +628,11 @@ class GalaxyCluster extends AppModel
$elevatedUser = array(
'Role' => array(
'perm_site_admin' => 1,
'perm_sync' => 1
'perm_sync' => 1,
'perm_audit' => 0,
),
'org_id' => $clusterOrgcId['GalaxyCluster']['orgc_id']
);
$elevatedUser['Role']['perm_site_admin'] = 1;
$elevatedUser['Role']['perm_sync'] = 1;
$elevatedUser['Role']['perm_audit'] = 0;
$cluster = $this->fetchGalaxyClusters($elevatedUser, array('minimal' => true, 'conditions' => array('id' => $clusterId)), $full=false);
if (empty($cluster)) {
return true;
@ -655,14 +653,10 @@ class GalaxyCluster extends AppModel
return true;
}
$uploaded = false;
$failedServers = array();
App::uses('SyncTool', 'Tools');
foreach ($servers as &$server) {
foreach ($servers as $server) {
if ((!isset($server['Server']['internal']) || !$server['Server']['internal']) && $cluster['GalaxyCluster']['distribution'] < 2) {
continue;
}
$syncTool = new SyncTool();
$HttpSocket = $syncTool->setupHttpSocket($server);
$fakeSyncUser = array(
'id' => 0,
'email' => 'fakeSyncUser@user.test',
@ -678,14 +672,13 @@ class GalaxyCluster extends AppModel
);
$cluster = $this->fetchGalaxyClusters($fakeSyncUser, array('conditions' => array('GalaxyCluster.id' => $clusterId)), $full=true);
if (empty($cluster)) {
return true;
continue;
}
$cluster = $cluster[0];
$result = $this->uploadClusterToServer($cluster, $server, $HttpSocket, $fakeSyncUser);
if ($result == 'Success') {
$serverSync = new ServerSyncTool($server, $this->setupSyncRequest($server));
$result = $this->uploadClusterToServer($cluster, $server, $serverSync, $fakeSyncUser);
if ($result === 'Success') {
$uploaded = true;
} else {
$failedServers[] = $server;
}
}
return $uploaded;
@ -1672,79 +1665,29 @@ class GalaxyCluster extends AppModel
/**
* @return string|bool The result of the upload. True if success, a string otherwise
* @throws Exception
*/
public function uploadClusterToServer($cluster, $server, $HttpSocket, $user)
{
$this->Server = ClassRegistry::init('Server');
$this->Log = ClassRegistry::init('Log');
$push = $this->Server->checkVersionCompatibility($server, false);
if (empty($push['canPush']) && empty($push['canPushGalaxyCluster'])) {
return __('The remote user does not have the permission to manipulate galaxies - the upload of the galaxy clusters has been blocked.');
}
$updated = null;
$newLocation = $newTextBody = '';
$result = $this->__executeRestfulGalaxyClusterToServer($cluster, $server, null, $newLocation, $newTextBody, $HttpSocket, $user);
if ($result !== true) {
return $result;
}
if (strlen($newLocation)) { // HTTP/1.1 302 Found and Location: http://<newLocation>
$result = $this->__executeRestfulGalaxyClusterToServer($cluster, $server, $newLocation, $newLocation, $newTextBody, $HttpSocket, $user);
if ($result !== true) {
return $result;
}
}
$uploadFailed = false;
try {
$json = json_decode($newTextBody, true);
} catch (Exception $e) {
$uploadFailed = true;
}
if (!is_array($json) || $uploadFailed) {
$this->Log->createLogEntry($user, 'push', 'GalaxyCluster', $cluster['GalaxyCluster']['id'], 'push', $newTextBody);
}
return 'Success';
}
private function __executeRestfulGalaxyClusterToServer($cluster, $server, $resourceId, &$newLocation, &$newTextBody, $HttpSocket, $user)
{
$result = $this->restfulGalaxyClusterToServer($cluster, $server, $resourceId, $newLocation, $newTextBody, $HttpSocket);
if (is_numeric($result)) {
$error = $this->__resolveErrorCode($result, $cluster, $server, $user);
if ($error) {
return $error . ' Error code: ' . $result;
}
}
return true;
}
/**
* @return string|bool|int The result of the upload.
*/
public function restfulGalaxyClusterToServer($cluster, $server, $urlPath, &$newLocation, &$newTextBody, $HttpSocket = null)
public function uploadClusterToServer(array $cluster, array $server, ServerSyncTool $serverSync, array $user)
{
$cluster = $this->__prepareForPushToServer($cluster, $server);
if (is_numeric($cluster)) {
return $cluster;
}
$url = $server['Server']['url'];
$HttpSocket = $this->setupHttpSocket($server, $HttpSocket);
$request = $this->setupSyncRequest($server);
$scope = 'galaxies/pushCluster';
$uri = $url . '/' . $scope;
$clusters = array($cluster);
$data = json_encode($clusters);
if (!empty(Configure::read('Security.sync_audit'))) {
$pushLogEntry = sprintf(
"==============================================================\n\n[%s] Pushing Galaxy Cluster #%d to Server #%d:\n\n%s\n\n",
date("Y-m-d H:i:s"),
$cluster['GalaxyCluster']['id'],
$server['Server']['id'],
$data
);
file_put_contents(APP . 'files/scripts/tmp/debug_server_' . $server['Server']['id'] . '.log', $pushLogEntry, FILE_APPEND);
try {
if (!$serverSync->isSupported(ServerSyncTool::PERM_SYNC) || $serverSync->isSupported(ServerSyncTool::PERM_GALAXY_EDITOR)) {
return __('The remote user does not have the permission to manipulate galaxies - the upload of the galaxy clusters has been blocked.');
}
$serverSync->pushGalaxyCluster($cluster)->json();
} catch (Exception $e) {
$title = __('Uploading GalaxyCluster (%s) to Server (%s)', $cluster['GalaxyCluster']['id'], $server['Server']['id']);
$this->loadLog()->createLogEntry($user, 'push', 'GalaxyCluster', $cluster['GalaxyCluster']['id'], $title, $e->getMessage());
$this->logException("Could not push galaxy cluster to remote server {$serverSync->serverId()}", $e);
return $e->getMessage();
}
$response = $HttpSocket->post($uri, $data, $request);
return $this->__handleRestfulGalaxyClusterToServerResponse($response, $newLocation, $newTextBody);
return 'Success';
}
/**
@ -1752,7 +1695,7 @@ class GalaxyCluster extends AppModel
*
* @param array $cluster
* @param array $server
* @return array The cluster ready to be pushed
* @return array|int The cluster ready to be pushed
*/
private function __prepareForPushToServer(array $cluster, array $server)
{
@ -1773,11 +1716,9 @@ class GalaxyCluster extends AppModel
}
$this->Event = ClassRegistry::init('Event');
if ($this->Event->checkDistributionForPush($cluster, $server, 'GalaxyCluster')) {
$cluster = $this->__updateClusterForSync($cluster, $server);
} else {
return 403;
return $this->__updateClusterForSync($cluster, $server);
}
return $cluster;
return 403;
}
/**
@ -1886,59 +1827,6 @@ class GalaxyCluster extends AppModel
return $relation;
}
/**
* @return string|bool|int The result of the upload.
*/
private function __handleRestfulGalaxyClusterToServerResponse($response, &$newLocation, &$newTextBody)
{
switch ($response->code) {
case '200': // 200 (OK) + entity-action-result
if ($response->isOk()) {
$newTextBody = $response->body();
return true;
} else {
try {
$jsonArray = json_decode($response->body, true);
} catch (Exception $e) {
return true;
}
return $jsonArray['name'];
}
// no break
case '302': // Found
$newLocation = $response->headers['Location'];
$newTextBody = $response->body();
return true;
case '404': // Not Found
$newLocation = $response->headers['Location'];
$newTextBody = $response->body();
return 404;
case '405':
return 405;
case '403': // Not authorised
return 403;
}
}
private function __resolveErrorCode($code, &$cluster, &$server, $user)
{
$this->Log = ClassRegistry::init('Log');
$error = false;
switch ($code) {
case 403:
return __('The distribution level of the cluster blocks it from being pushed.');
case 405:
$error = __('The sync user on the remote instance does not have the required privileges to handle this cluster.');
break;
}
if ($error) {
$newTextBody = 'Uploading GalaxyCluster (' . $cluster['GalaxyCluster']['id'] . ') to Server (' . $server['Server']['id'] . ')';
$newTextBody = __('Uploading GalaxyCluster (%s) to Server (%s)', $cluster['GalaxyCluster']['id'], $server['Server']['id']);
$this->Log->createLogEntry($user, 'push', 'GalaxyCluster', $cluster['GalaxyCluster']['id'], 'push', $newTextBody);
}
return $error;
}
/**
* pullGalaxyClusters
*

View File

@ -1129,7 +1129,6 @@ class Server extends AppModel
}
$this->GalaxyCluster = ClassRegistry::init('GalaxyCluster');
$this->Event = ClassRegistry::init('Event');
$HttpSocket = $this->setupHttpSocket($server);
$clusters = array();
if ($technique == 'full') {
$clusters = $this->GalaxyCluster->getElligibleClustersToPush($user, $conditions=array(), $full=true);
@ -1150,7 +1149,7 @@ class Server extends AppModel
return [];
}
foreach ($clustersToPush as $cluster) {
$result = $this->GalaxyCluster->uploadClusterToServer($cluster, $server, $HttpSocket, $user);
$result = $this->GalaxyCluster->uploadClusterToServer($cluster, $server, $serverSync, $user);
if ($result === 'Success') {
$successes[] = __('GalaxyCluster %s', $cluster['GalaxyCluster']['uuid']);
}
@ -3740,8 +3739,7 @@ class Server extends AppModel
public function extensionDiagnostics()
{
try {
$file = new File(APP . DS . 'composer.json');
$composer = $this->jsonDecode($file->read());
$composer = FileAccessTool::readJsonFromFile(APP . DS . 'composer.json');
$extensions = [];
foreach ($composer['require'] as $require => $foo) {
if (substr($require, 0, 4) === 'ext-') {