ACC SHELL

Path : /usr/share/YaST2/include/iscsi-client/
File Upload :
Current File : //usr/share/YaST2/include/iscsi-client/widgets.ycp

{
 textdomain "iscsi-client";
 import "IP";

 boolean stat = false;
 list<string> curr_rec = [];
 boolean bg_finish = false;
// string initiatorname="";
// function for run command in background
list <string> runInBg(string command){
    bg_finish=false;
    y2milestone("Start command %1 in background", command);
    list <string> stdout = [];
    integer return_code = nil;
    boolean started = (boolean)SCR::Execute(.background.run_output_err, command);
    if (!started) {
        y2error("Cannot run command");
	stat = false;
        return [];
    }
    integer time_spent = 0;
    boolean cont_loop = true;
    integer script_time_out = 10000;
    integer sleep_step = 20;
    while (cont_loop && ((boolean) SCR::Read(.background.output_open))) {
        if (time_spent >= script_time_out) {
            Popup::Error(_("Command timed out"));
            cont_loop = false;
        }
        time_spent = time_spent + sleep_step;
        sleep(sleep_step);
    }
    y2milestone("Time spent: %1 msec", time_spent);
    stdout = (list<string>)(SCR::Read(.background.newout));
    if (cont_loop) {
	return_code = (integer) SCR::Read(.background.status);
	if (return_code == 255) {
		stat = false;
		Popup::Error( ( (list<string>)SCR::Read(.background.newerr) )[0]:"" );
		}
		else stat = true;
	}
      else {
        // killing the process if it still runs
        if ((boolean) SCR::Read(.background.output_open)) SCR::Execute(.background.kill, "");
    }
 bg_finish=true;
 return stdout;
}

// validation for authentication dialog entry
boolean checkAuthEntry(){
 y2milestone("Check entries for authentication");
 boolean ret = true;
 boolean auth_none = (boolean) UI::QueryWidget(`id(`auth_none), `Value);
 boolean auth_in = (boolean) UI::QueryWidget(`id(`auth_in), `Value);
 boolean auth_out = (boolean) UI::QueryWidget(`id(`auth_out), `Value);
 string user_in = tostring( UI::QueryWidget(`id(`user_in), `Value) );
 string pass_in = tostring( UI::QueryWidget(`id(`pass_in), `Value) );
 string user_out = tostring( UI::QueryWidget(`id(`user_out), `Value) );
 string pass_out = tostring( UI::QueryWidget(`id(`pass_out), `Value) );
 if (auth_none) return true;
  else {
   if  (auth_in){
    if (size(user_in)==0) {
     Popup::Error(_("Insert the username."));
     UI::SetFocus(`id(`user_in));
     return false;
    }
    if(size(pass_in)==0) {
     Popup::Error(_("Insert the password."));
     UI::SetFocus(`id(`pass_in));
     return false;
    }
   }
   if  (auth_out){
    if (size(user_out)==0) {
     Popup::Error(_("Insert the username."));
     UI::SetFocus(`id(`user_out));
     return false;
    }
    if(size(pass_out)==0) {
     Popup::Error(_("Insert the password."));
     UI::SetFocus(`id(`pass_out));
     return false;
    }
   }
  }
 return ret;
}

// init table of connected sessions
void initConnectedTable(string key){
    if (IscsiClientLib::readSessions()== false) Popup::Error(_("Error While Connecting iscsid"));
     integer row_current = (integer) UI::QueryWidget(`connected, `CurrentItem);
     list <term> items = [];
     integer row = 0;
     foreach(string s, IscsiClientLib::sessions, {
     IscsiClientLib::currentRecord = splitstring(s, " ");
	items = add(items, `item(`id(row), IscsiClientLib::currentRecord[0]:"", IscsiClientLib::currentRecord[1]:"", IscsiClientLib::getStartupStatus()));
      row = row + 1;
     });
        UI::ChangeWidget (`id (`connected), `Items, items);
	UI::ChangeWidget(`connected, `CurrentItem, row_current);
        UI::SetFocus (`id (`connected));
}

// get record identificator from selected row
list<string> setRecord(){
 IscsiClientLib::currentRecord = [];
 any sel_item = UI::QueryWidget(`id(`connected), `CurrentItem);
 if (sel_item != nil){
	 integer current = tointeger(sel_item);
	 IscsiClientLib::currentRecord = splitstring(IscsiClientLib::sessions[current]:"", " " );
//	 record = deletechars(record, "[]");
	} else
	   if (size(IscsiClientLib::sessions)>0)
			 IscsiClientLib::currentRecord = splitstring(IscsiClientLib::sessions[0]:"", " " );
 return IscsiClientLib::currentRecord;
}

// handle for table of connected sessions
symbol handleConnectedTable (string key, map event){
 if (event["EventReason"]:"" == "Activated"){
 list<string> record = [];
 switch((symbol)event["ID"]:nil){
  case(`add):
		// add a new target, discovery
		// goto DiscAuthDialog("client")) ()
		y2milestone("Goto dicovered authentication dialog");
		return `add;
  case(`del):
		// delete (logout from) connected target
		record = setRecord();
		if (size( record )>0){
		  if (Popup::ContinueCancel(_("Really log out from the selected target?")))
		    if ( !(IscsiClientLib::deleteRecord()) ) Popup::Error(_("Error occurred while logging out from the selected target."));
			else {
				y2milestone("Delete record %1", record);
				initConnectedTable("");
			     }
		} else Popup::Error(_("No record found."));
		break;
  case(`edit):
		record = setRecord();
		return `edit;
		break;
  case(`toggle):
		// change manual/onboot status of connected target
		// don't use automatic anymore (replaced by onboot) (bnc#449108)
		record = setRecord();
		if (size( record )>0){
		y2milestone("toggle record %1", record);
		string startup = IscsiClientLib::getStartupStatus();
		if (size(startup)>0){
		// toggle all 3 possible values (bnc#457252)
		 list <string> options = ["manual", "onboot", "automatic"];
		 integer pos=0;
		 foreach(string option, options, {
		   if (startup==option){
		     startup=options[(size(options)>pos+1) ? pos+1 : 0]:"";
		     y2milestone("Changing state from %1 to %2", option, startup );
		     IscsiClientLib::setStartupStatus(startup);
		     break;
		   }
		   pos=pos+1;
		 });
		  initConnectedTable("");
		 }
		} else Popup::Error(_("No record found."));
		break;
  }
 }
 // if nothing selected - disable some buttons, otherwise enable them
 if( setRecord() == []){
   UI::ChangeWidget (`id (`del), `Enabled, false);
   UI::ChangeWidget (`id (`edit), `Enabled, false);

  } else {
   UI::ChangeWidget (`id (`del), `Enabled, true);
   UI::ChangeWidget (`id (`edit), `Enabled, true);

	}
 return nil;
}

void initISNS(string key){
 foreach(map<string, any> row, IscsiClientLib::getConfig(), {
  if (row["name"]:""=="isns.address") UI::ChangeWidget(`isns_address, `Value, row["value"]:"");
  if (row["name"]:""=="isns.port")    UI::ChangeWidget(`isns_port,    `Value, row["value"]:"");
 });
 UI::ChangeWidget(`isns_port, `ValidChars, "0123456789");
}

boolean validateISNS(string key, map event){
 string address = (string)UI::QueryWidget(`isns_address, `Value);
 string port	= (string)UI::QueryWidget(`isns_port,	 `Value);
 if (size(address)==0 && size(port)==0) return true;
 if(!IP::Check4(address)){
  Popup::Error(_("No valid IP address"));
  UI::SetFocus(`isns_address);
  return false;
 }
 if (size(port)==0){
  Popup::Error(_("Port field cannot be empty"));
  UI::SetFocus(`isns_port);
  return false;
 }
 return true;
}


symbol storeISNS (string key, map event){
 string address = (string)UI::QueryWidget(`isns_address, `Value);
 string port    = (string)UI::QueryWidget(`isns_port,    `Value);
 boolean found_addr = false;
 boolean found_port = false;
 list tmp_config=[];

 foreach(map<string, any> row, IscsiClientLib::getConfig(), {
  if (row["name"]:""=="isns.address") {
	 row["value"]=address;
	 found_addr = true;
	}
  if (row["name"]:""=="isns.port") {
	 row["value"]=port;
	 found_port = true;
	}
  if (((row["name"]:""=="isns.address" || row["name"]:""=="isns.port")&&(size(address)>0&&size(port)>0))
	|| (row["name"]:""!="isns.address"&&row["name"]:""!="isns.port"))  tmp_config = add(tmp_config, row);
 });
 if (size(address)>0&&size(port)>0){
  if (!found_addr) tmp_config = add(tmp_config, $["name":"isns.address", "value":address, "kind":"value", "type":1, "comment":""]);
  if (!found_port) tmp_config = add(tmp_config, $["name":"isns.port",    "value":port, "kind":"value", "type":1, "comment":""]);
 }

 IscsiClientLib::setConfig(tmp_config);
 IscsiClientLib::oldConfig();
 return nil;
}



void initInitName(string key){
    y2milestone("initiatorname %1", IscsiClientLib::initiatorname);
    UI::ChangeWidget(`initiator_name, `Value, IscsiClientLib::initiatorname);
  if (size(IscsiClientLib::getiBFT()["iSCSI_INITIATOR_NAME"]:"")>0){
   UI::ChangeWidget(`initiator_name, `Enabled, false);
   UI::ChangeWidget(`write, `Enabled, false);
  }
}

boolean validateInitName(string key, map event){
/*
 Targets definitions start with "Target" and the target name.
 The target name must be a globally unique name, the iSCSI
 standard defines the "iSCSI Qualified Name" as follows:

 iqn.yyyy-mm.reversed domain name[:identifier]

 "yyyy-mm" is the date at which the domain is valid and the identifier
 is freely selectable. For further details please check the iSCSI spec.
*/

 string i_name = (string)UI::QueryWidget(`initiator_name, `Value);
 // regexp for "yyyy-mm."
 string reg1 = "[[:digit:]]\{4\}\-[[:digit:]]\{2\}\.";
 // regexp for "cz.suse" or just "suse", "cz.su-se"
 string reg2 = "[[:alnum:]\.\:-]*";

 boolean correct = regexpmatch(i_name, sformat("^iqn\.%1%2$", reg1, reg2)) ||
			regexpmatch(i_name, sformat("^eui\.%1%2$", reg1, reg2));

 if (!correct) Popup::Warning(_("Incorrect InitiatorName.
The correct syntax is
iqn.yyyy-mm.reversed.domain.name[:identifier]
or eui.yyyy-mm.reversed.domain.name[:identifier]

Example:
iqn.2007-04.cz.server:storage.disk.sdb
"));

 return correct;
}


symbol storeInitName (string key, map event){
 if ((string)UI::QueryWidget(`initiator_name, `Value) != IscsiClientLib::initiatorname){
	// write initiatorname
	IscsiClientLib::writeInitiatorName((string)UI::QueryWidget(`initiator_name, `Value));
	if (Stage::initial()){
	 SCR::Execute(.target.bash, "killproc /sbin/iscsid");
	 IscsiClientLib::startIScsid();
	}
		else SCR::Execute(.target.bash, "rcopen-iscsi restart");
	y2milestone("write initiatorname %1", IscsiClientLib::initiatorname);
 }
 return nil;
}
// ***************** iBFT table **************************
void initiBFT(string key){
 list<term> items = [];
 foreach(string key, any value, IscsiClientLib::hidePassword(IscsiClientLib::getiBFT()), {
  items = add(items, `item(`id(size(items)), key, value));
 });
 UI::ChangeWidget(`bios, `Items, items);

}
// ***************** add table ***************************

// set incoming widget status
/*
void setAuthIn(boolean status){
 UI::ChangeWidget(`id(`user_in),`Enabled, status );
 UI::ChangeWidget(`id(`pass_in),`Enabled, status );
 UI::ChangeWidget(`id(`auth_in),`Value, status );
 if(status) UI::ChangeWidget(`id(`auth_none),`Value, !status );
}
*/

// set outgoing widget status
/*
void setAuthOut(boolean status){
 UI::ChangeWidget(`id(`user_out),`Enabled, status );
 UI::ChangeWidget(`id(`pass_out),`Enabled, status );
 UI::ChangeWidget(`id(`auth_out),`Value, status );
 if(status) UI::ChangeWidget(`id(`auth_none),`Value, !status );
}
*/

// disable both incoming and outgoing
void initDiscAuth(string key){
// setAuthIn(false);
// setAuthOut(false);
}

void initConnAuth(string key){
// setAuthIn(false);
// setAuthOut(false);
 map<string, any> auth = IscsiClientLib::getNode();
 if (size(auth)>0)
  {
    UI::ChangeWidget(`id(`user_in),`Value, auth["username_in"]:"" );
    UI::ChangeWidget(`id(`pass_in),`Value, auth["password_in"]:"" );
//   if ((size(auth["username_in"]:"")>0)&&(size(auth["password_in"]:"")>0)) setAuthOut(true);
   UI::ChangeWidget(`id(`user_out),`Value, auth["username"]:"" );
   UI::ChangeWidget(`id(`pass_out),`Value, auth["password"]:"" );
//   if ((size(auth["username"]:"")>0)&&(size(auth["password"]:"")>0)) setAuthOut(true);
  }
 string startup=IscsiClientLib::getStartupStatus();
 if(size(startup)>0) UI::ChangeWidget(`id("startup"), `Value, startup);
}
// handle for enable/disable widgets in authentication dialog
symbol handleDiscAuth(string key, map event){
 if (event["EventReason"]:"" == "ValueChanged"){
 boolean status = false;
 switch((symbol)event["ID"]:nil){
  case(`auth_none):
		status = (boolean)UI::QueryWidget(`id(`auth_none), `Value);
//		setAuthIn(!status);
//		setAuthOut(!status);
		break;
  case(`auth_in):
		status = (boolean)UI::QueryWidget(`id(`auth_in), `Value);
//		setAuthIn(status);
		break;
  case(`auth_out):
		status = (boolean)UI::QueryWidget(`id(`auth_out), `Value);
//		setAuthOut(status);
		break;
  }
 }
 return nil;
}

boolean validateDiscAuth(string key, map event){
 return checkAuthEntry();
}
// *******************Server Location ***********************

void initServerLocation(string key){
y2internal("is iSNS %1", IscsiClientLib::useISNS());
 if (IscsiClientLib::useISNS()){
  UI::ChangeWidget(`hostname, `Enabled, false);
  UI::ChangeWidget(`port, `Enabled, false);
 }
}

// do discovery to selected portal
boolean validateServerLocation(string key, map event){
 boolean ret = true;
 string ip = tostring(UI::QueryWidget(`hostname, `Value));
 string port = tostring(UI::QueryWidget(`port, `Value));
 // validate IP address
if (!IscsiClientLib::useISNS())
 {
  if (size(ip)>0){
      if (!IP::Check4(ip)) {
		map<string, any> output = (map<string, any>)SCR::Execute(.target.bash_output, sformat("host -4 %1|tr -d '\n'", ip));
		list<string> out=splitstring(output["stdout"]:"", " ");
		ip=out[size(out)-1]:"";
		y2internal("%1", out);
		if (output["exit"]:-1==0){
		} else {
		  Popup::Error(output["stdout"]:"");
		  UI::SetFocus(`hostname);
		  return false;
		 }
		}
   } else{
	Popup::Error(_("Insert the IP address."));
	UI::SetFocus(`ip);
	return false;
   }
   // validate port number
   if (size(port)==0) {
		Popup::Error(_("Insert the port."));
		UI::SetFocus(`port);
		return false;
		}
  }
 // store old config
 IscsiClientLib::getConfig();

 boolean auth_none = (boolean) UI::QueryWidget(`id(`auth_none), `Value);
 string user_in = tostring( UI::QueryWidget(`id(`user_in), `Value) );
 string pass_in = tostring( UI::QueryWidget(`id(`pass_in), `Value) );
 string user_out = tostring( UI::QueryWidget(`id(`user_out), `Value) );
 string pass_out = tostring( UI::QueryWidget(`id(`pass_out), `Value) );
 boolean auth_in = (!auth_none && size(user_in)>0 && size(pass_in)>0);
 boolean auth_out = (!auth_none && size(user_out)>0 && size(pass_out)>0);

 if (auth_none){
  user_in  = "";
  pass_in  = "";
  user_out = "";
  pass_out = "";
 }
 if (!auth_in){
  user_in  = "";
  pass_in  = "";
 }
 if (!auth_out){
  user_out  = "";
  pass_out  = "";
 }

 // write authentication data
 IscsiClientLib::saveConfig(user_in, pass_in, user_out, pass_out);
//y2internal("auth: %1/%2, %3/%4", user_in, pass_in, user_out, pass_out);
 bg_finish=false;
 // ` with authentication
 string command = IscsiClientLib::useISNS()? "iscsiadm -m discovery -t isns" : sformat("iscsiadm -m discovery -t st -p %1:%2", ip, port);
 list<string>trg_list = runInBg( command );
 IscsiClientLib::targets = [];
foreach(string row, trg_list, {
 list<string> tmp_list=splitstring(row, " ");
 if (issubstring(tmp_list[0]:"", sformat("%1:%2",ip,port))) IscsiClientLib::targets=add(IscsiClientLib::targets, sformat("%1 %2", tmp_list[0]:"", tmp_list[1]:""));
});
 while(!bg_finish){};
 // restore old config
 IscsiClientLib::oldConfig();

 return stat;
}


// ********************* discovered table *******************

// enable [ connect, delete ] buttons only for not connected items
boolean setDiscoveredButtons(){
   list <string> params = [];
   any selected = UI::QueryWidget(`discovered, `CurrentItem);
   if (selected != nil) { params = splitstring( IscsiClientLib::discovered[tointeger(selected)]:"", " " ); }
        else  { params = []; }
 IscsiClientLib::currentRecord = [ splitstring(params[0]:"", ",")[0]:"", params[1]:""];
 if ((params==[])||(IscsiClientLib::connected( true ))){
   UI::ChangeWidget (`id (`connect), `Enabled, false);
   UI::ChangeWidget (`id (`delete), `Enabled, false);
  } else{
	   UI::ChangeWidget (`id (`connect), `Enabled, true);
	   UI::ChangeWidget (`id (`delete), `Enabled, true);
	}
}

// initialize widget with discovered targets
void initDiscoveredTable(string key){
     list <term> items = [];
     integer row = 0;
     foreach(string s, IscsiClientLib::getDiscovered(), {
     IscsiClientLib::currentRecord = splitstring(s, " ");
//        string record = deletechars(row_in_string[0]:"", "[]");
        items = add(items, `item(`id(row), IscsiClientLib::currentRecord[0]:"", IscsiClientLib::currentRecord[1]:"",
		(IscsiClientLib::connected( true ))?_("True"):_("False") ));
      row = row + 1;
     });

  UI::ChangeWidget (`id (`discovered), `Items, items);
  UI::SetFocus (`id (`discovered));
  setDiscoveredButtons();
}

// handling widget with discovered targets
symbol handleDiscoveredTable (string key, map event){
   list <string> params = [];
   any selected = UI::QueryWidget(`discovered, `CurrentItem);
   if (selected != nil) { params = splitstring( IscsiClientLib::discovered[tointeger(selected)]:"", " " ); }
	else  { params = []; }
   IscsiClientLib::currentRecord = [ splitstring(params[0]:"", ",")[0]:"", params[1]:"" ] ;
//    params = curr_rec;
 if ( event["EventReason"]:"" == "Activated" ){
  // connect new target
  if ( event["ID"]:nil == `connect) {
   // check if not already connected
   if ( IscsiClientLib::connected( false) == true){
     if (!Popup::AnyQuestion(Label::WarningMsg(), _("The target with this TargetName is already connected. Make sure that multipathing is enabled to prevent data corruption."), _("Continue"), _("Cancel"), `focus_yes)) return nil;
    }

   // goto ConnAuthDialog("discovered") (initDiscAuth)
   return `conn;
  }
  // discovery target ConnAuthDialog("client") (initDiscAuth)
  if ( event["ID"]:nil == `discovery) {
   return `disc;
  }
  // delete connected item
  if ( event["ID"]:nil == `delete) {
   if ((params == [])||(!IscsiClientLib::connected( true ))){
         string cmd = sformat("iscsiadm -m node -T %1 -p %2 --op=delete", params[1]:"", params[0]:"");
	 y2milestone("%1 : %2", cmd, SCR::Execute (.target.bash_output,cmd,  $[] ));
	 IscsiClientLib::readSessions();
	 initDiscoveredTable("");
   if (selected != nil) { params = splitstring( IscsiClientLib::discovered[tointeger(selected)]:"", " " ); }
        else  { params = []; }
	}
  }
 }
 setDiscoveredButtons();
 return nil;
}

//******************* target table *************************

// initialize dialog for all targets from portal (connected/disconnected)
void initTargetTable(string key){
     list <term> items = [];
     integer row = 0;
     foreach(string s, IscsiClientLib::targets, {
     IscsiClientLib::currentRecord = splitstring(s, " ");
        items = add(items, `item(`id(row), IscsiClientLib::currentRecord[0]:"", IscsiClientLib::currentRecord[1]:"",
		(IscsiClientLib::connected( true ))?_("True"):_("False") ));
      row = row + 1;
     });
        UI::ChangeWidget (`id (`targets), `Items, items);
        UI::SetFocus (`id (`targets));
}

// handle dialog for all targets from portal (connected/disconnected) - only connect button ;)
symbol handleTargetTable (string key, map event){
 //enable/disable connect button according target is or not already connected
 list <term> items =(list <term>)UI::QueryWidget(`targets, `Items);
 if ((items[(integer)UI::QueryWidget(`targets, `CurrentItem)]:nil)[3]:"" == _("True")) UI::ChangeWidget(`connect, `Enabled, false);
	else UI::ChangeWidget(`connect, `Enabled, true);


 if ( event["EventReason"]:"" == "Activated" ){
  if ( event["ID"]:nil == `connect) {
   // check if is not already connected
   IscsiClientLib::currentRecord = splitstring( IscsiClientLib::targets[(integer)UI::QueryWidget(`targets, `CurrentItem)]:"", " " );
   if ( IscsiClientLib::connected( true ) == true){
    Popup::Error(_("The target is already connected."));
   } else {
   // check if not already connected
   if ( IscsiClientLib::connected(false) == true){
     if (!Popup::AnyQuestion(Label::WarningMsg(), _("The target with this TargetName is already connected. Make sure that multipathing is enabled to prevent data corruption."), _("Continue"), _("Cancel"), `focus_yes)) return nil;
    }

	// goto ConnAuthDialog("discovered") (initDiscAuth())
	 return `conn_auth;
	}
  }
 }
 return nil;
}

//***************** connection autentication *******************

// login to target with authentication
boolean validateConnAuth(string key, map event){
 boolean auth_none = (boolean) UI::QueryWidget(`id(`auth_none), `Value);
 string  user_in = tostring( UI::QueryWidget(`id(`user_in), `Value) );
 string  pass_in = tostring( UI::QueryWidget(`id(`pass_in), `Value) );
 string  user_out = tostring( UI::QueryWidget(`id(`user_out), `Value) );
 string  pass_out = tostring( UI::QueryWidget(`id(`pass_out), `Value) );

 map<string, any> target=$[
		"target" : IscsiClientLib::currentRecord[1]:"",
		"portal" : IscsiClientLib::currentRecord[0]:"",
		"authmethod" : (auth_none)?"None":"CHAP",
		"username" : user_out,
		"password" : pass_out,
		"username_in" : user_in,
		"password_in" : pass_in
		];
  if (IscsiClientLib::connected(false) || IscsiClientLib::loginIntoTarget(target)) {
//		IscsiClientLib::currentRecord = [target["portal"]:"", target["target"]:""];
		IscsiClientLib::setStartupStatus((string)UI::QueryWidget(`id("startup"), `Value));
		 IscsiClientLib::readSessions();
		 return true;
		}
	else return false;
}

}

ACC SHELL 2018