forked from extern/egroupware
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:
parent
4d933cf0f4
commit
912bbae120
@ -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";
|
||||||
|
@ -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
|
||||||
|
@ -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());
|
||||||
|
@ -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')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
@ -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';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
Loading…
Reference in New Issue
Block a user