next step admin-cli can send now commands to remote installs (defined direct in egw_admin_remote, no GUI yet)

This commit is contained in:
Ralf Becker 2007-11-23 20:04:26 +00:00
parent 4d933cf0f4
commit 912bbae120
6 changed files with 210 additions and 39 deletions

View File

@ -114,6 +114,10 @@ function run_command($cmd)
$cmd->comment = array_shift($arguments); $cmd->comment = array_shift($arguments);
break; break;
case '--remote': // run the command on a remote install
$cmd->remote_id = admin_cmd::parse_remote(array_shift($arguments));
break;
default: default:
//fail(99,lang('Unknown option %1',$extra); //fail(99,lang('Unknown option %1',$extra);
echo lang('Unknown option %1',$extra)."\n\n"; echo lang('Unknown option %1',$extra)."\n\n";
@ -121,6 +125,7 @@ function run_command($cmd)
break; break;
} }
} }
//_debug_array($cmd);
return $cmd->run($time); return $cmd->run($time);
} }
@ -162,7 +167,7 @@ function user_pass_from_argv(&$account)
function usage($action=null,$ret=0) function usage($action=null,$ret=0)
{ {
$cmd = basename($_SERVER['argv'][0]); $cmd = basename($_SERVER['argv'][0]);
echo "Usage: $cmd --command admin-account[@domain],admin-password,options,... [--schedule {YYYY-mm-dd|+1 week|+5 days}] [--requested 'Name <email>'] [--comment 'comment ...']\n\n"; echo "Usage: $cmd --command admin-account[@domain],admin-password,options,... [--schedule {YYYY-mm-dd|+1 week|+5 days}] [--requested 'Name <email>'] [--comment 'comment ...'] [--remote {id|name}]\n\n";
echo "--edit-user admin-account[@domain],admin-password,account[=new-account-name],first-name,last-name,password,email,expires{never(default)|YYYY-MM-DD|already},can-change-pw{yes(default)|no},anon-user{yes|no(default)},primary-group{Default(default)|...}[,groups,...]\n"; echo "--edit-user admin-account[@domain],admin-password,account[=new-account-name],first-name,last-name,password,email,expires{never(default)|YYYY-MM-DD|already},can-change-pw{yes(default)|no},anon-user{yes|no(default)},primary-group{Default(default)|...}[,groups,...]\n";
echo " Edit or add a user to eGroupWare. If you specify groups, they *replace* the exiting memberships!\n"; echo " Edit or add a user to eGroupWare. If you specify groups, they *replace* the exiting memberships!\n";

View File

@ -50,6 +50,8 @@ abstract class admin_cmd
private $id; private $id;
private $uid; private $uid;
private $type = __CLASS__; private $type = __CLASS__;
public $remote_id;
/** /**
* Stores the data of the derived classes * Stores the data of the derived classes
* *
@ -78,6 +80,13 @@ abstract class admin_cmd
*/ */
static private $sql; static private $sql;
/**
* Instance of so_sql for egw_admin_remote
*
* @var so_sql
*/
static private $remote;
/** /**
* Executes the command * Executes the command
* *
@ -136,7 +145,14 @@ abstract class admin_cmd
else else
{ {
try { try {
$ret = $this->exec(); if (!$this->remote_id)
{
$ret = $this->exec();
}
else
{
$ret = $this->remote_exec();
}
$this->status = admin_cmd::successful; $this->status = admin_cmd::successful;
} }
catch (Exception $e) { catch (Exception $e) {
@ -152,6 +168,61 @@ abstract class admin_cmd
return $ret; return $ret;
} }
/**
* Runs a command on a remote install
*
* This is a very basic remote procedure call to an other egw instance.
* The payload / command data is send as POST request to the remote installs admin/remote.php script.
* The remote domain (eGW instance) and the secret authenticating the request are send as GET parameters.
*
* To authenticate with the installation we use a secret, which is a md5 hash build from the uid
* of the command (to not allow to send new commands with an earsdroped secret) and the md5 hash
* of the md5 hash of the config password and the install_id (egw_admin_remote.remote_hash)
*
* @return string sussess message
* @throws Exception(lang('Invalid remote id or name "%1"!',$id_or_name),997) or other Exceptions reported from remote
*/
private function remote_exec()
{
admin_cmd::_instanciate_remote();
if (!($remote = admin_cmd::$remote->read($this->remote_id)))
{
throw new Exception(lang('Invalid remote id or name "%1"!',$id_or_name),997);
}
if (!$this->uid)
{
$this->save(); // to get the uid
}
$secret = md5($this->uid.$remote['remote_hash']);
$postdata = $GLOBALS['egw']->translation->convert($this->as_array(),$GLOBALS['egw']->translation->charset(),'utf-8');
// dont send the id's which have no meaning on the remote install
foreach(array('id','creator','modifier','requested','remote_id') as $name)
{
unset($postdata[$name]);
}
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($postdata),
)
);
$url = $remote['remote_url'].'/admin/remote.php?domain='.urlencode($remote['remote_domain']).'&secret='.urlencode($secret);
//echo "sending command to $url\n"; _debug_array($opts);
$message = file_get_contents($url, false, stream_context_create($opts));
//echo "got: $message\n";
$message = $GLOBALS['egw']->translation->convert($message,'utf-8');
if (preg_match('/^([0-9]+) (.*)$/',$message,$matches))
{
throw new Exception($matches[2],(int)$matches[1]);
}
return $message;
}
/** /**
* Delete / canncels a scheduled command * Delete / canncels a scheduled command
* *
@ -301,20 +372,35 @@ abstract class admin_cmd
} }
/** /**
* Instanciate our static so_sql object * Instanciate our static so_sql object for egw_admin_queue
* *
* @static * @static
*/ */
private static function _instanciate_sql() private static function _instanciate_sql()
{ {
include_once(EGW_INCLUDE_ROOT.'/etemplate/inc/class.so_sql.inc.php');
if (is_null(admin_cmd::$sql)) if (is_null(admin_cmd::$sql))
{ {
include_once(EGW_INCLUDE_ROOT.'/etemplate/inc/class.so_sql.inc.php');
admin_cmd::$sql = new so_sql('admin','egw_admin_queue',null,'cmd_'); admin_cmd::$sql = new so_sql('admin','egw_admin_queue',null,'cmd_');
} }
} }
/**
* Instanciate our static so_sql object for egw_admin_remote
*
* @static
*/
private static function _instanciate_remote()
{
if (is_null(admin_cmd::$remote))
{
include_once(EGW_INCLUDE_ROOT.'/etemplate/inc/class.so_sql.inc.php');
admin_cmd::$remote = new so_sql('admin','egw_admin_remote');
}
}
/** /**
* magic method to read a property, all non admin-cmd properties are stored in the data array * magic method to read a property, all non admin-cmd properties are stored in the data array
* *
@ -437,6 +523,7 @@ abstract class admin_cmd
* *
* @param string $date * @param string $date
* @return int timestamp * @return int timestamp
* @throws Exception(lang('Invalid formated date "%1"!',$datein),998);
*/ */
static function parse_date($date) static function parse_date($date)
{ {
@ -453,6 +540,27 @@ abstract class admin_cmd
} }
return (int)$date; return (int)$date;
} }
/**
* Parse a remote id or name and return the remote_id
*
* @param string $id_or_name
* @return int remote_id
* @throws Exception(lang('Invalid remote id or name "%1"!',$id_or_name),997);
*/
static function parse_remote($id_or_name)
{
admin_cmd::_instanciate_remote();
if (!($remotes = admin_cmd::$remote->search(array(
'remote_id' => $id_or_name,
'remote_name' => $id_or_name,
),true,'','','',false,'OR')) || count($remotes) != 1)
{
throw new Exception(lang('Invalid remote id or name "%1"!',$id_or_name),997);
}
return $remotes[0]['remote_id'];
}
/** /**
* Instanciated accounts class * Instanciated accounts class

View File

@ -27,13 +27,17 @@ if (!isset($GLOBALS['egw_domain'][$instance]))
$instance = $GLOBALS['egw_info']['server']['default_domain']; $instance = $GLOBALS['egw_info']['server']['default_domain'];
} }
$domain_data = $GLOBALS['egw_domain'][$instance]; $domain_data = $GLOBALS['egw_domain'][$instance];
//echo $instance; _debug_array($domain_data);
// to authenticate with the installation we use a secret, which is a md5 hash build from the uid
// of the command (to not allow to send new commands with an earsdroped secret) and the md5 hash
// of the md5 hash of the config password and the install_id (egw_admin_remote.remote_hash)
if (!$domain_data || is_numeric($_REQUEST['uid']) || if (!$domain_data || is_numeric($_REQUEST['uid']) ||
$_REQUEST['secret'] != ($md5=md5($_REQUEST['uid'].$GLOBALS['egw_info']['server']['install_id'].$domain_data['config_password']))) $_REQUEST['secret'] != ($md5=md5($_REQUEST['uid'].md5($domain_data['config_passwd'].$GLOBALS['egw_info']['server']['install_id']))))
{ {
header("HTTP/1.1 401 Unauthorized"); header("HTTP/1.1 401 Unauthorized");
//die("secret != '$md5'"); //die("0 secret != '$md5'");
echo lang('Permission denied!'); echo lang('0 Permission denied!');
$GLOBALS['egw']->common->egw_exit(); $GLOBALS['egw']->common->egw_exit();
} }
@ -53,14 +57,15 @@ if (!$_REQUEST['uid'] || // no uid
!$_REQUEST['creator_email']) // no creator email !$_REQUEST['creator_email']) // no creator email
{ {
header("HTTP/1.1 400 Bad format!"); header("HTTP/1.1 400 Bad format!");
echo lang('Bad format!'); echo lang('0 Bad format!');
$GLOBALS['egw']->common->egw_exit(); $GLOBALS['egw']->common->egw_exit();
} }
// create command from request data // create command from request data
$data = isset($_POST['uid']) ? $_POST : $_GET; $data = isset($_POST['uid']) ? $_POST : $_GET;
unset($data['secret']); unset($data['secret']);
unset($data['id']); // we are remote unset($data['id']); // we are remote
unset($data['remote_id']);
$data['creator'] = 0; // remote $data['creator'] = 0; // remote
if (isset($data['modifier'])) $data['modifier'] = 0; if (isset($data['modifier'])) $data['modifier'] = 0;
if (isset($data['requested'])) $data['requested'] = 0; if (isset($data['requested'])) $data['requested'] = 0;
@ -69,7 +74,7 @@ if (isset($data['requested'])) $data['requested'] = 0;
try { try {
$cmd = admin_cmd::instanciate($data); $cmd = admin_cmd::instanciate($data);
//_debug_array($cmd); exit; //_debug_array($cmd); exit;
$success_msg = $cmd->run($data['sheduled']); $success_msg = $cmd->run();
} }
catch (Exception $e) { catch (Exception $e) {
header('HTTP/1.1 400 '.$e->getMessage()); header('HTTP/1.1 400 '.$e->getMessage());

View File

@ -10,9 +10,9 @@
*/ */
$setup_info['admin']['name'] = 'admin'; $setup_info['admin']['name'] = 'admin';
$setup_info['admin']['version'] = '1.5.001'; $setup_info['admin']['version'] = '1.5.003';
$setup_info['admin']['app_order'] = 1; $setup_info['admin']['app_order'] = 1;
$setup_info['admin']['tables'] = array('egw_admin_queue'); $setup_info['admin']['tables'] = array('egw_admin_queue','egw_admin_remote');
$setup_info['admin']['enable'] = 1; $setup_info['admin']['enable'] = 1;
$setup_info['admin']['author'][] = array( $setup_info['admin']['author'][] = array(
@ -53,3 +53,4 @@ $setup_info['admin']['depends'][] = array(
'appname' => 'etemplate', 'appname' => 'etemplate',
'versions' => Array('1.4','1.5') 'versions' => Array('1.4','1.5')
); );

View File

@ -12,30 +12,44 @@
* @version $Id$ * @version $Id$
*/ */
$phpgw_baseline = array( $phpgw_baseline = array(
'egw_admin_queue' => array( 'egw_admin_queue' => array(
'fd' => array( 'fd' => array(
'cmd_id' => array('type' => 'auto'), 'cmd_id' => array('type' => 'auto'),
'cmd_uid' => array('type' => 'varchar','precision' => '255','nullable' => False), 'cmd_uid' => array('type' => 'varchar','precision' => '255','nullable' => False),
'cmd_creator' => array('type' => 'int','precision' => '4','nullable' => False), 'cmd_creator' => array('type' => 'int','precision' => '4','nullable' => False),
'cmd_creator_email' => array('type' => 'varchar','precision' => '128','nullable' => False), 'cmd_creator_email' => array('type' => 'varchar','precision' => '128','nullable' => False),
'cmd_created' => array('type' => 'int','precision' => '8','nullable' => False), 'cmd_created' => array('type' => 'int','precision' => '8','nullable' => False),
'cmd_type' => array('type' => 'varchar','precision' => '32','nullable' => False,'default' => 'admin_cmd'), 'cmd_type' => array('type' => 'varchar','precision' => '32','nullable' => False,'default' => 'admin_cmd'),
'cmd_status' => array('type' => 'int','precision' => '1'), 'cmd_status' => array('type' => 'int','precision' => '1'),
'cmd_scheduled' => array('type' => 'int','precision' => '8'), 'cmd_scheduled' => array('type' => 'int','precision' => '8'),
'cmd_modified' => array('type' => 'int','precision' => '8'), 'cmd_modified' => array('type' => 'int','precision' => '8'),
'cmd_modifier' => array('type' => 'int','precision' => '4'), 'cmd_modifier' => array('type' => 'int','precision' => '4'),
'cmd_modifier_email' => array('type' => 'varchar','precision' => '128'), 'cmd_modifier_email' => array('type' => 'varchar','precision' => '128'),
'cmd_error' => array('type' => 'varchar','precision' => '255'), 'cmd_error' => array('type' => 'varchar','precision' => '255'),
'cmd_errno' => array('type' => 'int','precision' => '4'), 'cmd_errno' => array('type' => 'int','precision' => '4'),
'cmd_requested' => array('type' => 'int','precision' => '4'), 'cmd_requested' => array('type' => 'int','precision' => '4'),
'cmd_requested_email' => array('type' => 'varchar','precision' => '128'), 'cmd_requested_email' => array('type' => 'varchar','precision' => '128'),
'cmd_comment' => array('type' => 'varchar','precision' => '255'), 'cmd_comment' => array('type' => 'varchar','precision' => '255'),
'cmd_data' => array('type' => 'blob') 'cmd_data' => array('type' => 'blob'),
'remote_id' => array('type' => 'int','precision' => '4')
),
'pk' => array('cmd_id'),
'fk' => array(),
'ix' => array('cmd_status','cmd_scheduled'),
'uc' => array('cmd_uid')
), ),
'pk' => array('cmd_id'), 'egw_admin_remote' => array(
'fk' => array(), 'fd' => array(
'ix' => array('cmd_status','cmd_scheduled'), 'remote_id' => array('type' => 'auto'),
'uc' => array('cmd_uid') 'remote_name' => array('type' => 'varchar','precision' => '64','nullable' => False),
) 'remote_hash' => array('type' => 'varchar','precision' => '32','nullable' => False),
); 'remote_url' => array('type' => 'varchar','precision' => '128','nullable' => False),
'remote_domain' => array('type' => 'varchar','precision' => '64','nullable' => False)
),
'pk' => array('remote_id'),
'fk' => array(),
'ix' => array(),
'uc' => array('remote_name')
)
);

View File

@ -12,6 +12,11 @@
* @version $Id$ * @version $Id$
*/ */
function admin_upgrade1_2()
{
return $GLOBALS['setup_info']['admin']['currentver'] = '1.4';
}
function admin_upgrade1_4() function admin_upgrade1_4()
{ {
$GLOBALS['egw_setup']->oProc->CreateTable('egw_admin_queue',array( $GLOBALS['egw_setup']->oProc->CreateTable('egw_admin_queue',array(
@ -41,3 +46,36 @@ function admin_upgrade1_4()
)); ));
return $GLOBALS['setup_info']['admin']['currentver'] = '1.5.001'; return $GLOBALS['setup_info']['admin']['currentver'] = '1.5.001';
} }
$test[] = '1.5.001';
function admin_upgrade1_5_001()
{
$GLOBALS['egw_setup']->oProc->CreateTable('egw_admin_remote',array(
'fd' => array(
'remote_id' => array('type' => 'auto'),
'remote_name' => array('type' => 'varchar','precision' => '64','nullable' => False),
'remote_hash' => array('type' => 'varchar','precision' => '32','nullable' => False),
'remote_url' => array('type' => 'varchar','precision' => '128','nullable' => False),
'remote_domain' => array('type' => 'varchar','precision' => '64','nullable' => False)
),
'pk' => array('remote_id'),
'fk' => array(),
'ix' => array(),
'uc' => array('remote_name')
));
return $GLOBALS['setup_info']['admin']['currentver'] = '1.5.002';
}
$test[] = '1.5.002';
function admin_upgrade1_5_002()
{
$GLOBALS['egw_setup']->oProc->AddColumn('egw_admin_queue','remote_id',array(
'type' => 'int',
'precision' => '4'
));
return $GLOBALS['setup_info']['admin']['currentver'] = '1.5.003';
}
?>