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);
break;
case '--remote': // run the command on a remote install
$cmd->remote_id = admin_cmd::parse_remote(array_shift($arguments));
break;
default:
//fail(99,lang('Unknown option %1',$extra);
echo lang('Unknown option %1',$extra)."\n\n";
@ -121,6 +125,7 @@ function run_command($cmd)
break;
}
}
//_debug_array($cmd);
return $cmd->run($time);
}
@ -162,7 +167,7 @@ function user_pass_from_argv(&$account)
function usage($action=null,$ret=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 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 $uid;
private $type = __CLASS__;
public $remote_id;
/**
* Stores the data of the derived classes
*
@ -78,6 +80,13 @@ abstract class admin_cmd
*/
static private $sql;
/**
* Instance of so_sql for egw_admin_remote
*
* @var so_sql
*/
static private $remote;
/**
* Executes the command
*
@ -136,7 +145,14 @@ abstract class admin_cmd
else
{
try {
if (!$this->remote_id)
{
$ret = $this->exec();
}
else
{
$ret = $this->remote_exec();
}
$this->status = admin_cmd::successful;
}
catch (Exception $e) {
@ -152,6 +168,61 @@ abstract class admin_cmd
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
*
@ -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
*/
private static function _instanciate_sql()
{
include_once(EGW_INCLUDE_ROOT.'/etemplate/inc/class.so_sql.inc.php');
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_');
}
}
/**
* 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
*
@ -437,6 +523,7 @@ abstract class admin_cmd
*
* @param string $date
* @return int timestamp
* @throws Exception(lang('Invalid formated date "%1"!',$datein),998);
*/
static function parse_date($date)
{
@ -454,6 +541,27 @@ abstract class admin_cmd
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
*

View File

@ -27,13 +27,17 @@ if (!isset($GLOBALS['egw_domain'][$instance]))
$instance = $GLOBALS['egw_info']['server']['default_domain'];
}
$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']) ||
$_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");
//die("secret != '$md5'");
echo lang('Permission denied!');
//die("0 secret != '$md5'");
echo lang('0 Permission denied!');
$GLOBALS['egw']->common->egw_exit();
}
@ -53,7 +57,7 @@ if (!$_REQUEST['uid'] || // no uid
!$_REQUEST['creator_email']) // no creator email
{
header("HTTP/1.1 400 Bad format!");
echo lang('Bad format!');
echo lang('0 Bad format!');
$GLOBALS['egw']->common->egw_exit();
}
@ -61,6 +65,7 @@ if (!$_REQUEST['uid'] || // no uid
$data = isset($_POST['uid']) ? $_POST : $_GET;
unset($data['secret']);
unset($data['id']); // we are remote
unset($data['remote_id']);
$data['creator'] = 0; // remote
if (isset($data['modifier'])) $data['modifier'] = 0;
if (isset($data['requested'])) $data['requested'] = 0;
@ -69,7 +74,7 @@ if (isset($data['requested'])) $data['requested'] = 0;
try {
$cmd = admin_cmd::instanciate($data);
//_debug_array($cmd); exit;
$success_msg = $cmd->run($data['sheduled']);
$success_msg = $cmd->run();
}
catch (Exception $e) {
header('HTTP/1.1 400 '.$e->getMessage());

View File

@ -10,9 +10,9 @@
*/
$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']['tables'] = array('egw_admin_queue');
$setup_info['admin']['tables'] = array('egw_admin_queue','egw_admin_remote');
$setup_info['admin']['enable'] = 1;
$setup_info['admin']['author'][] = array(
@ -53,3 +53,4 @@ $setup_info['admin']['depends'][] = array(
'appname' => 'etemplate',
'versions' => Array('1.4','1.5')
);

View File

@ -12,7 +12,7 @@
* @version $Id$
*/
$phpgw_baseline = array(
$phpgw_baseline = array(
'egw_admin_queue' => array(
'fd' => array(
'cmd_id' => array('type' => 'auto'),
@ -31,11 +31,25 @@ $phpgw_baseline = array(
'cmd_requested' => array('type' => 'int','precision' => '4'),
'cmd_requested_email' => array('type' => 'varchar','precision' => '128'),
'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')
),
'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')
)
);
);

View File

@ -12,6 +12,11 @@
* @version $Id$
*/
function admin_upgrade1_2()
{
return $GLOBALS['setup_info']['admin']['currentver'] = '1.4';
}
function admin_upgrade1_4()
{
$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';
}
$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';
}
?>