opsi = new opsi($config);
$this->config = $config;
/* Check if we are are part of a windows workstation
*/
$this->parent = $parent;
if($parent instanceof wingeneric){
$this->standalone = FALSE;
}
/* Get hostId
*/
if($hostId != "new"){
if(preg_match("/^opsi:/",$hostId)){
$this->hostId = preg_replace("/^opsi:=([^,]*),.*$/","\\1",$hostId);
}elseif($this->parent instanceof wingeneric){
$this->hostId = $this->parent->cn;
$this->hostId = preg_replace('/\$$/',"",$this->hostId);
}
}
/* Try to plugin */
$this->init();
}
/*! \brief Try to load opsi client informations from the
gosa support daemon.
*/
private function init()
{
$err = FALSE;
$this->init_failed = FALSE;
$this->initially_was_account = FALSE;
/* We are a standalone plugin.
*/
if($this->standalone ) {
$this->is_account = TRUE;
}
/* Try to load client infos from the gosa support daemon
*/
if(!empty($this->hostId)){
$list = $this->opsi->list_clients($this->hostId);
$err |= $this->opsi->is_error();
/* Walk through all returned opsi clients and try to detect
one that matches our hostId.
#FIXME Implement an opsi method which returns infos for only one opsi client, not all.
*/
foreach($list as $entry){
if(preg_match("/^".normalizePreg($this->hostId)."$/i",$entry['NAME'][0]['VALUE'])){
$this->initially_was_account = TRUE;
$this->is_account = TRUE;
foreach(array(
"is_installed" => "LASTSEEN",
"description" => "DESCRIPTION",
"mac" => "MAC",
"note" => "NOTES") as $des => $src){
$des2 = "initial_".$des;
$this->$des2 = $this->$des = $entry[$src][0]['VALUE'];
}
break;
}
}
}
/* Read informations about available netboot products.
If not already done, before.
*/
if(!$err && !count($this->a_availableNetbootProducts)){
$this->a_availableNetbootProducts = $this->opsi->get_netboot_products();
ksort($this->a_availableNetbootProducts);
$err |= $this->opsi->is_error();
}
/* Read informations about available netboot products.
If not already done, before.
*/
if(!$err && !count($this->a_availableLocalProducts)) {
$this->a_availableLocalProducts = $this->opsi->get_local_products();
ksort($this->a_availableLocalProducts);
$err |= $this->opsi->is_error();
}
/* Get products selected by this host.
*/
if(!$err && !empty($this->hostId)) {
$tmp = array_keys($this->opsi->get_netboot_products($this->hostId));
$err |= $this->opsi->is_error();
if(count($tmp) && !$err && !isset($this->a_availableNetbootProducts[$this->s_selectedNetbootProduct]['CFG'])){
$this->s_selectedNetbootProduct = $tmp[0];
/* Read configuration for "Netboot Products" */
if(isset($this->a_availableNetbootProducts[$this->s_selectedNetbootProduct])){
$CFG = $this->opsi->get_product_properties($this->s_selectedNetbootProduct,$this->hostId);
$this->a_availableNetbootProducts[$this->s_selectedNetbootProduct]['CFG'] = $CFG;
}
}
$err |= $this->opsi->is_error();
}
/* Get all selected local products
*/
if(!$err && !empty($this->hostId) && !count($this->a_selectedLocalProducts)) {
$tmp = $this->opsi->get_local_products($this->hostId);
$err |= $this->opsi->is_error();
$this->a_selectedLocalProducts = $tmp;
}
/* Load product configuration for all already selected products.
*/
if(!$err && !empty($this->hostId)) {
foreach($this->a_selectedLocalProducts as $name => $data){
if(!$err && !isset($this->a_selectedLocalProducts[$name]['CFG'])){
$CFG = $this->opsi->get_product_properties($name,$this->hostId);
$err |= $this->opsi->is_error();
$this->a_selectedLocalProducts[$name]['CFG'] = $CFG;
}
}
}
/* Check if everything went fine else reset everything and display a retry button
*/
if($err){
$this->init_failed = TRUE;
}else{
/* Remember initial settings */
$this->a_initial_selectedLocalProducts = $this->a_selectedLocalProducts;
$this->s_initial_selectedNetbootProduct = $this->s_selectedNetbootProduct;
$this->a_initial_availableNetbootProducts = $this->a_availableNetbootProducts;
/* Ensure that a valid netboot is selected product is.
*/
if(empty($this->s_selectedNetbootProduct)){
$this->s_selectedNetbootProduct = key($this->a_availableNetbootProducts);
}
}
}
/*! \brief Check given data.
@return Array Returns an array with all issues.
*/
public function check()
{
$messages = plugin::check();
if(empty($this->hostId)){
$messages[] = msgPool::required(_("Name"));
}elseif(!preg_match("/\./",$this->hostId)){
/* The hostId must contain a domain part
*/
$messages[] = msgPool::invalid(_("Name"),$this->hostId,"",
_("The field 'Name' must contain a domain part!"));
}elseif(preg_match("/[^a-z0-9\.\-_]/",$this->hostId)){
$messages[] = msgPool::invalid(_("Name"),$this->hostId,"/[a-z0-9\.\-_]/");
}
/* Ensure that the mac address is valid
*/
if(!tests::is_mac($this->mac) || empty($this->mac)){
$messages[] = msgPool::invalid(_("MAC address"),$this->mac,"","00:0C:7F:31:33:F1");
}
return($messages);
}
/*! \brief Create the html ui of this plugin
@return String HTML content.
*/
public function execute()
{
$display ="";
/* The pluign initialization failed due to communication problems with the gosa daemon.
A retry button will be displayed here.
*/
if($this->init_failed){
$smarty = get_smarty();
$smarty->assign("standalone ", $this->standalone );
$smarty->assign("init_failed",TRUE);
$smarty->assign("message",$this->opsi->get_error());
return($smarty->fetch(get_template_path("generic.tpl",TRUE,dirname(__FILE__))));
}
/* If we are not a stand alone opsi client, we must be a samba client
which has the opsi tab enabled.
Check if the opsi is added or removed and display state buttons.
*/
if(!$this->standalone ){
/* Do we need to flip is_account state? */
if(isset($_POST['modify_state'])){
if($this->is_account && $this->acl_is_removeable()){
$this->is_account= FALSE;
}elseif(!$this->is_account && $this->acl_is_createable()){
$this->is_account= TRUE;
}
}
if($this->is_account){
$display = $this->show_disable_header(msgPool::removeFeaturesButton(_("OPSI")),
msgPool::featuresEnabled(_("OPSI")));
}else{
$display = $this->show_enable_header(msgPool::addFeaturesButton(_("OPSI")),
msgPool::featuresDisabled(_("OPSI")));
return($display);
}
}
/* Check if we have a sub dialog opened
*/
if(is_object($this->dialog)){
$this->dialog->save_object();
return($this->dialog->execute());
}
/* Create HTML output of this plugin
*/
$smarty = get_smarty();
$smarty->assign("standalone", $this->standalone );
foreach($this->attributes as $attr){
$smarty->assign($attr,$this->$attr);
}
/* Assign ACLs */
$tmp = $this->plInfo();
foreach($tmp['plProvidedAcls'] as $name => $translated){
$smarty->assign($name."ACL",$this->getacl($name));
}
$smarty->assign("is_installed", $this->is_installed);
$smarty->assign("init_failed",FALSE);
$divSLP = new divSelectBox();
$divALP = new divSelectBox();
/* Create list of available local products
*/
foreach($this->a_availableLocalProducts as $name => $data){
if(isset($this->a_selectedLocalProducts[$name])) continue;
$add_tab = array("string" => "");
$name_tab = array("string" => $name);
$desc_tab = array("string" => "
".$data['DESC']."
",
"attach" => "title='".$data['DESC']."' style='border-right:0px;'");
if($this->acl_is_writeable("localProduct")){
$divALP->AddEntry(array($add_tab,$name_tab,$desc_tab));
}else{
$divALP->AddEntry(array($name_tab,$desc_tab));
}
}
/* Create list of selected local products
*/
ksort($this->a_selectedLocalProducts);
foreach($this->a_selectedLocalProducts as $name => $data){
$name_tab = array("string" => $name);
$desc_tab = array(
"string" => "
".$data['DESC']."
",
"attach" => "title='".$data['DESC']."'");
/* Only display edit button, if there is something to edit
*/
$edit = "";
if(count($data['CFG'])){
$edit = "";
}
$del = "";
$opt_tab = array("string" => $edit.$del,
"attach" => "style='border-right:0px; width: 40px; text-align:right;'");
if($this->acl_is_writeable("localProduct")){
$divSLP->AddEntry(array($name_tab,$desc_tab,$opt_tab));
}else{
$divSLP->AddEntry(array($name_tab,$desc_tab));
}
}
/* Check if netboot product is configurable
*/
$cfg_able =FALSE;
if(isset($this->a_availableNetbootProducts[$this->s_selectedNetbootProduct]['CFG'])){
$cfg_able = count($this->a_availableNetbootProducts[$this->s_selectedNetbootProduct]['CFG']);
$cfg_able &= $this->acl_is_readable("netbootProduct");
}
$smarty->assign("netboot_configurable",$cfg_able);
$smarty->assign("hostId", $this->hostId);
$smarty->assign("divSLP", $divSLP->DrawList());
$smarty->assign("divALP", $divALP->DrawList());
$smarty->assign("SNP", $this->s_selectedNetbootProduct);
$smarty->assign("ANP", $this->a_availableNetbootProducts);
return($display.$smarty->fetch(get_template_path("generic.tpl",TRUE,dirname(__FILE__))));
}
/*! \brief Save modifications using the gosa support daemon.
*/
public function save()
{
/* Check if we have to create a new opsi client
or just have to save client modifications.
*/
if(!$this->initially_was_account && $this->is_account){
$res = $this->opsi->add_client($this->hostId,$this->mac,$this->note,$this->description);
if($this->opsi->is_error()){
msg_dialog::display(_("Error"),msgPool::siError($this->opsi->get_error()),ERROR_DIALOG);
return;
}
}else{
/* Update client modifcations.
-Only if necessary
*/
if($this->note != $this->initial_note ||
$this->description != $this->initial_description ||
$this->mac != $this->initial_mac){
$this->opsi->modify_client($this->hostId,$this->mac,$this->note,$this->description);
if($this->opsi->is_error()){
msg_dialog::display(_("Error"),msgPool::siError($this->opsi->get_error()),ERROR_DIALOG);
return;
}
}
}
/***********
Detect local netboot product changes
- Check which products were removed.
- Check which products were added.
***********/
/* Detect which products were removed an which added.
*/
$del = array_diff_assoc($this->a_initial_selectedLocalProducts,$this->a_selectedLocalProducts);
$add = array_diff_assoc($this->a_selectedLocalProducts,$this->a_initial_selectedLocalProducts);
/* Remove products from client
*/
foreach($del as $name => $data){
$this->opsi->del_product_from_client($name,$this->hostId);
if($this->opsi->is_error()){
msg_dialog::display(_("Error"),msgPool::siError($this->opsi->get_error()),ERROR_DIALOG);
return;
}
}
/* Add products to client
And set the product properties.
*/
foreach($add as $name => $data){
$this->opsi->add_product_to_client($name,$this->hostId);
if($this->opsi->is_error()){
msg_dialog::display(_("Error"),msgPool::siError($this->opsi->get_error()),ERROR_DIALOG);
return;
}
if(!empty($data['CFG'])){
$this->opsi->set_product_properties($name,$data['CFG'],$this->hostId);
if($this->opsi->is_error()){
msg_dialog::display(_("Error"),msgPool::siError($this->opsi->get_error()),ERROR_DIALOG);
return;
}
}
}
/* Save local product properties
*/
foreach($this->a_selectedLocalProducts as $name => $data){
if(isset($del[$name]) || isset($add[$name])) continue;
/* Update product properties if there are changes
*/
$diffs = $this->get_config_changes($data['CFG'],$this->a_initial_selectedLocalProducts[$name]['CFG']);
if(count($diffs)){
$this->opsi->set_product_properties($name,$diffs,$this->hostId);
if($this->opsi->is_error()){
msg_dialog::display(_("Error"),msgPool::siError($this->opsi->get_error()),ERROR_DIALOG);
return;
}
}
}
/*********
Detect Netboot product changes
- Check if another netboot product was selected.
- Check if the product properties were changes.
*********/
/* Update used netboot product.
*/
if($this->s_selectedNetbootProduct != $this->s_initial_selectedNetbootProduct){
if(!empty($this->s_initial_selectedNetbootProduct)){
$this->opsi->del_product_from_client($this->s_initial_selectedNetbootProduct,$this->hostId);
if($this->opsi->is_error()){
msg_dialog::display(_("Error"),msgPool::siError($this->opsi->get_error()),ERROR_DIALOG);
return;
}
}
$this->opsi->add_product_to_client($this->s_selectedNetbootProduct,$this->hostId);
if($this->opsi->is_error()){
msg_dialog::display(_("Error"),msgPool::siError($this->opsi->get_error()),ERROR_DIALOG);
return;
}
}
/* Check if we have to update the netboot product properties
This is the case, if this product is newly selected.
Or if there was at least one configuration attribute modified.
*/
$cfg_1 = $cfg_2 = array();
if(isset($this->a_availableNetbootProducts[$this->s_selectedNetbootProduct]['CFG'])){
$cfg_1 = $this->a_availableNetbootProducts[$this->s_selectedNetbootProduct]['CFG'];
}
if(isset($this->a_initial_availableNetbootProducts[$this->s_selectedNetbootProduct]['CFG'])){
$cfg_2 = $this->a_initial_availableNetbootProducts[$this->s_selectedNetbootProduct]['CFG'];
}
$diffs = $this->get_config_changes($cfg_1,$cfg_2);
$to_update = array();
if( !$this->initially_was_account ||
$this->s_selectedNetbootProduct != $this->s_initial_selectedNetbootProduct){
$to_update = $this->a_availableNetbootProducts[$this->s_selectedNetbootProduct]['CFG'];
}elseif(count($diffs)){
$to_update = $diffs;
}
if(count($to_update)){
$name = $this->s_selectedNetbootProduct;
$this->opsi->set_product_properties($name,$to_update,$this->hostId);
if($this->opsi->is_error()){
msg_dialog::display(_("Error"),msgPool::siError($this->opsi->get_error()),ERROR_DIALOG);
return;
}
}
}
public function get_config_changes($c1,$c2)
{
/* Get key which are not present in both entries
*/
$res = array();
foreach($c2 as $name => $value){
if(!isset($c1[$name]) || $c1[$name]['DEFAULT'] != $c2[$name]['DEFAULT']){
$res[$name] = $c2[$name];
}
}
foreach($c1 as $name => $value){
if(!isset($c2[$name]) || $c2[$name]['DEFAULT'] != $c1[$name]['DEFAULT']){
$res[$name] = $c1[$name];
}
}
return($res);
}
/*! \brief Removes the opsi client
*/
public function remove_from_parent()
{
$this->opsi->del_client($this->hostId);
if($this->opsi->is_error()){
msg_dialog::display(_("Error"),msgPool::siError($this->opsi->get_error()),ERROR_DIALOG);
return;
}
}
/*! \brief Save html posts
*/
public function save_object()
{
/* Init failed; reinit is triggered here.
*/
if(isset($_POST['reinit']) && $this->init_failed){
$this->init();
}
/* Property are currently edited, close the dialog.
*/
if(isset($_POST['cancel_properties']) && is_object($this->dialog)){
$this->dialog = NULL;
}
/* Save product property changes
*/
if(isset($_POST['save_properties']) && ($this->dialog instanceof opsiProperties)){
$this->dialog->save_object();
$pro = $this->dialog->get_product();
$CFG = $this->dialog->get_cfg();
if(isset($this->a_selectedLocalProducts[$pro])){
$this->a_selectedLocalProducts[$pro]['CFG'] = $CFG;
$this->dialog = NULL;
}elseif($this->s_selectedNetbootProduct == $pro){
$this->a_availableNetbootProducts[$pro]['CFG'] = $CFG;
$this->dialog = NULL;
}else{
trigger_error("Fatal, unknown product was configured.");
}
}
/* Save html post
*/
if(isset($_POST['opsiGeneric_posted'])){
plugin::save_object();
/* Get hostId
*/
if(isset($_POST['hostId']) && $this->standalone && $this->acl_is_writeable("hostId")){
$this->hostId = get_post('hostId');
}
/* Send actions like 'install' or 'wake' to the si server
*/
if($this->acl_is_writeable("triggerAction") &&
isset($_POST['opsi_action']) &&
isset($_POST['opsi_trigger_action']) &&
$this->standalone ){
$action = $_POST['opsi_action'];
if($action == "install"){
$this->install_client();
}
}
/* Get selected netboot product.
*/
if(isset($_POST['opsi_netboot_product']) && $this->acl_is_writeable("netbootProduct")){
$SNP = trim($_POST['opsi_netboot_product']);
if(isset($this->a_availableNetbootProducts[$SNP])){
if(!isset($this->a_availableNetbootProducts[$SNP]['CFG'])){
$CFG = $this->opsi->get_product_properties($SNP);
$this->a_availableNetbootProducts[$SNP]['CFG'] = $CFG;
if($this->opsi->is_error()){
$this->init_failed = TRUE;
return;
}
}
$this->s_selectedNetbootProduct = $SNP;
}
}
/* Add/remove/edit local products
*/
foreach($_POST as $name => $value){
/* Check if netboot product configuration is requested
*/
if(preg_match("/^configure_netboot/",$name) && $this->acl_is_readable("netbootProduct")){
$pro = $this->s_selectedNetbootProduct;
$cfg = $this->a_availableNetbootProducts[$pro]['CFG'];
$this->dialog = new opsiProperties($this->config,$pro,$cfg,$this->hostId);
break;
}
/* Add product
*/
if(preg_match("/^add_lp_/",$name) && $this->acl_is_writeable("localProduct")){
$product = preg_replace("/^add_lp_(.*)_.$/","\\1",$name);
if(isset($this->a_availableLocalProducts[$product]) && !isset($this->a_selectedLocalProducts[$product])){
$this->a_selectedLocalProducts[$product] = $this->a_availableLocalProducts[$product];
$CFG = $this->opsi->get_product_properties($product);
if($this->opsi->is_error()){
$this->init_failed = TRUE;
return;
}
$this->a_selectedLocalProducts[$product]['CFG'] = $CFG;
}
break;
}
/* Delete product
*/
if(preg_match("/^del_lp_/",$name) && $this->acl_is_writeable("localProduct")){
$product = preg_replace("/^del_lp_(.*)_.$/","\\1",$name);
if(isset($this->a_selectedLocalProducts[$product])){
unset($this->a_selectedLocalProducts[$product]);
}
break;
}
/* Edit a product
*/
if(preg_match("/^edit_lp_/",$name) && $this->acl_is_readable("localProduct")){
$product = preg_replace("/^edit_lp_(.*)_.$/","\\1",$name);
$this->dialog = new opsiProperties($this->config,
$product,$this->a_selectedLocalProducts[$product]['CFG'],$this->hostId);
break;
}
}
}
}
/* Triggers client installation
*/
function install_client()
{
$this->opsi->send_action("install",$this->hostId,$this->mac);
if($this->opsi->is_error()){
msg_dialog::display(_("Error"),msgPool::siError($this->opsi->get_error()),ERROR_DIALOG);
}
}
/* Return plugin informations for acl handling */
static function plInfo()
{
return (array(
"plShortName" => _("Generic"),
"plDescription" => _("OPSI generic"),
"plSelfModify" => FALSE,
"plDepends" => array(),
"plPriority" => 1,
"plSection" => array("administration"),
"plCategory" => array("opsi" => array("description" => _("Opsi"),
"objectClass" => "dummy_class_opsi")),
"plProvidedAcls"=> array(
"hostId" => _("Name"),
"mac" => _("MAC address"),
"description" => _("Description"),
"note" => _("Note"),
"netbootProduct" => _("Netboot product"),
"localProduct" => _("Local product"),
"triggerAction" => _("Action"))
));
}
}
// vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
?>