@ -161,8 +161,15 @@ def OrchestratorSessionSave(inGSettings=None): ## Orchestrator session save
if lL : lL . info (
if lL : lL . info (
f " Orchestrator has dump the RDP list before the restart. The RDP List is { inGSettings [ ' RobotRDPActive ' ] [ ' RDPList ' ] } " )
f " Orchestrator has dump the RDP list before the restart. The RDP List is { inGSettings [ ' RobotRDPActive ' ] [ ' RDPList ' ] } " )
return True
return True
#Check is client is has access for the key list
def UACKeyListCheck ( inRequest , inRoleKeyList ) :
return inRequest . UACClientCheck ( inRoleKeyList = inRoleKeyList )
# Update user access
# Update user access
def OrchestratorUACUpdate ( inGSettings , inADLoginStr , inADStr = " " , inADIsDefaultBool = True , inURLList = [ ] , inCPAllowKeyList = [ ] , inRoleHierarchyAllowedDict = { } ) :
def UACUpdate( inGSettings , inADLoginStr , inADStr = " " , inADIsDefaultBool = True , inURLList = [ ] , inCPAllowKeyList = [ ] , inRoleHierarchyAllowedDict = { } ) :
lUserTurple = ( inADStr . upper ( ) , inADLoginStr . upper ( ) ) # Create turple key for inGSettings["Server"]["AccessUsers"]["RuleDomainUserDict"]
lUserTurple = ( inADStr . upper ( ) , inADLoginStr . upper ( ) ) # Create turple key for inGSettings["Server"]["AccessUsers"]["RuleDomainUserDict"]
if inURLList == [ ] and lUserTurple not in inGSettings [ " Server " ] [ " AccessUsers " ] [ " RuleDomainUserDict " ] : # Backward compatibility if user is not exist
if inURLList == [ ] and lUserTurple not in inGSettings [ " Server " ] [ " AccessUsers " ] [ " RuleDomainUserDict " ] : # Backward compatibility if user is not exist
inURLList = [
inURLList = [
@ -198,16 +205,19 @@ def OrchestratorUACUpdate(inGSettings, inADLoginStr, inADStr="", inADIsDefaultBo
inGSettings [ " Server " ] [ " AccessUsers " ] [ " RuleDomainUserDict " ] . update ( { ( " " , inADLoginStr . upper ( ) ) : lRuleDomainUserDict } )
inGSettings [ " Server " ] [ " AccessUsers " ] [ " RuleDomainUserDict " ] . update ( { ( " " , inADLoginStr . upper ( ) ) : lRuleDomainUserDict } )
# Add supertoken for the all access (it is need for the robot communication without human)
# Add supertoken for the all access (it is need for the robot communication without human)
def Orchestrator UACSuperTokenUpdate( inGSettings , inSuperTokenStr ) :
def UACSuperTokenUpdate( inGSettings , inSuperTokenStr ) :
lLoginStr = " SUPERTOKEN "
lLoginStr = " SUPERTOKEN "
Orchestrator UACUpdate( inGSettings = inGSettings , inADLoginStr = lLoginStr )
UACUpdate( inGSettings = inGSettings , inADLoginStr = lLoginStr )
inGSettings [ " Server " ] [ " AccessUsers " ] [ " AuthTokensDict " ] . update (
inGSettings [ " Server " ] [ " AccessUsers " ] [ " AuthTokensDict " ] . update (
{ inSuperTokenStr : { " User " : lLoginStr , " Domain " : " " , " TokenDatetime " : datetime . datetime . now ( ) , " FlagDoNotExpire " : True } }
{ inSuperTokenStr : { " User " : lLoginStr , " Domain " : " " , " TokenDatetime " : datetime . datetime . now ( ) , " FlagDoNotExpire " : True } }
)
)
# OrchestratorWEB
# # # # # # # # # # # # # # # # # # # # # # #
# OrchestratorWeb defs
# # # # # # # # # # # # # # # # # # # # # # #
# Add control panel HTML, JSON generator or JS when page init
# Add control panel HTML, JSON generator or JS when page init
def OrchestratorWebCPUpdate ( inGSettings , inCPKeyStr , inHTMLRenderDef = None , inJSONGeneratorDef = None , inJSInitGeneratorDef = None ) :
def WebCPUpdate( inGSettings , inCPKeyStr , inHTMLRenderDef = None , inJSONGeneratorDef = None , inJSInitGeneratorDef = None ) :
# Create Struct if the re is current key
# Create Struct if the re is current key
if inCPKeyStr not in inGSettings [ " CPDict " ] :
if inCPKeyStr not in inGSettings [ " CPDict " ] :
inGSettings [ " CPDict " ] [ inCPKeyStr ] = { " HTMLRenderDef " : None , " JSONGeneratorDef " : None , " JSInitGeneratorDef " : None }
inGSettings [ " CPDict " ] [ inCPKeyStr ] = { " HTMLRenderDef " : None , " JSONGeneratorDef " : None , " JSInitGeneratorDef " : None }
@ -221,6 +231,16 @@ def OrchestratorWebCPUpdate(inGSettings, inCPKeyStr, inHTMLRenderDef=None, inJSO
if inJSInitGeneratorDef is not None :
if inJSInitGeneratorDef is not None :
inGSettings [ " CPDict " ] [ inCPKeyStr ] [ " JSInitGeneratorDef " ] = inJSInitGeneratorDef
inGSettings [ " CPDict " ] [ inCPKeyStr ] [ " JSInitGeneratorDef " ] = inJSInitGeneratorDef
# Return User info about request Return {"DomainUpperStr":"", "UserNameUpperStr": ""}
def WebUserInfoGet ( inRequest ) :
lDomainUpperStr = inRequest . OpenRPA [ " Domain " ] . upper ( )
lUserUpperStr = inRequest . OpenRPA [ " User " ] . upper ( )
return { " DomainUpperStr " : lDomainUpperStr , " UserNameUpperStr " : lUserUpperStr }
# Return User UAC Hierarchy DICT Return {...}
def WebUserUACHierarchyGet ( inRequest ) :
return inRequest . UserRoleHierarchyGet ( )
## GSettings defs
## GSettings defs
def GSettingsKeyListValueSet ( inGSettings , inValue , inKeyList = [ ] ) : # Set value in GSettings by the key list
def GSettingsKeyListValueSet ( inGSettings , inValue , inKeyList = [ ] ) : # Set value in GSettings by the key list
lDict = inGSettings
lDict = inGSettings
@ -269,6 +289,19 @@ def GSettingsKeyListValueOperatorPlus(inGSettings, inValue, inKeyList=[]): # Ope
lDict [ inKeyList [ - 1 ] ] + = inValue #Set value
lDict [ inKeyList [ - 1 ] ] + = inValue #Set value
return True
return True
# Add Activity item in Processor list
def ProcessorActivityItemAppend ( inGSettings , inDef , inArgList = [ ] , inArgDict = { } , inArgGSettingsStr = None , inArgLoggerStr = None ) :
lActivityList = [
{
" Def " : inDef , # def link or def alias (look gSettings["Processor"]["AliasDefDict"])
" ArgList " : inArgList , # Args list
" ArgDict " : inArgDict , # Args dictionary
" ArgGSettings " : inArgGSettingsStr , # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
" ArgLogger " : inArgLoggerStr # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
} ,
]
inGSettings [ " ProcessorDict " ] [ " ActivityList " ] + = lActivityList
## Process defs
## Process defs
def ProcessIsStarted ( inProcessNameWOExeStr ) : # Check if process is started
def ProcessIsStarted ( inProcessNameWOExeStr ) : # Check if process is started
'''
'''
@ -356,8 +389,22 @@ def PythonStart(inModulePathStr, inDefNameStr, inArgList=[], inArgDict={}, inLog
except Exception as e :
except Exception as e :
if inLogger : inLogger . exception ( " Loop activity error: module/function not founded " )
if inLogger : inLogger . exception ( " Loop activity error: module/function not founded " )
# # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # #
# Scheduler
# # # # # # # # # # # # # # # # # # # # # # #
# Add activity in time weekly
def SchedulerActivityTimeAddWeekly ( inGSettings , inTimeHHMMStr = " 23:55: " , inWeekdayList = [ ] , inActivityList = [ ] ) :
lActivityTimeItemDict = {
" TimeHH:MMStr " : inTimeHHMMStr , # Time [HH:MM] to trigger activity
" WeekdayList " : inWeekdayList , # List of the weekday index when activity is applicable, Default [1,2,3,4,5,6,7]
" ActivityList " : inActivityList ,
" GUID " : None # # Will be filled in Orchestrator automatically - is needed for detect activity completion
} ,
inGSettings [ " SchedulerDict " ] [ " ActivityTimeList " ] . append ( lActivityTimeItemDict )
# # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # #
# RDPSession
# RDPSession
# # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # #
@ -698,7 +745,7 @@ def Orchestrator(inGSettings):
if lL : lL . warning ( f " RDP Session List was restored from previous Orchestrator session " )
if lL : lL . warning ( f " RDP Session List was restored from previous Orchestrator session " )
#Инициализация настроечных параметров
#Инициализация настроечных параметров
lDaemonLoopSeconds = gSettingsDict [ " Scheduler " ] [ " ActivityTimeCheckLoopSeconds " ]
lDaemonLoopSeconds = gSettingsDict [ " Scheduler Dict " ] [ " CheckIntervalSecFloat " ]
lDaemonActivityLogDict = { } #Словарь отработанных активностей, ключ - кортеж (<activityType>, <datetime>, <processPath || processName>, <processArgs>)
lDaemonActivityLogDict = { } #Словарь отработанных активностей, ключ - кортеж (<activityType>, <datetime>, <processPath || processName>, <processArgs>)
lDaemonLastDateTime = datetime . datetime . now ( )
lDaemonLastDateTime = datetime . datetime . now ( )
gSettingsDict [ " Server " ] [ " WorkingDirectoryPathStr " ] = os . getcwd ( ) # Set working directory in g settings
gSettingsDict [ " Server " ] [ " WorkingDirectoryPathStr " ] = os . getcwd ( ) # Set working directory in g settings
@ -762,74 +809,81 @@ def Orchestrator(inGSettings):
gDaemonActivityLogDictRefreshSecInt = 10 # The second period for clear lDaemonActivityLogDict from old items
gDaemonActivityLogDictRefreshSecInt = 10 # The second period for clear lDaemonActivityLogDict from old items
gDaemonActivityLogDictLastTime = time . time ( ) # The second perioad for clean lDaemonActivityLogDict from old items
gDaemonActivityLogDictLastTime = time . time ( ) # The second perioad for clean lDaemonActivityLogDict from old items
while True :
while True :
lCurrentDateTime = datetime . datetime . now ( )
try :
#Циклический обход правил
lCurrentDateTime = datetime . datetime . now ( )
lFlagSearchActivityType = True
#Циклический обход правил
# Periodically clear the lDaemonActivityLogDict
lFlagSearchActivityType = True
if time . time ( ) - gDaemonActivityLogDictLastTime > = gDaemonActivityLogDictRefreshSecInt :
# Periodically clear the lDaemonActivityLogDict
gDaemonActivityLogDictLastTime = time . time ( ) # Update the time
if time . time ( ) - gDaemonActivityLogDictLastTime > = gDaemonActivityLogDictRefreshSecInt :
for lIndex , lItem in enumerate ( lDaemonActivityLogDict ) :
gDaemonActivityLogDictLastTime = time . time ( ) # Update the time
if lItem [ " ActivityEndDateTime " ] and lCurrentDateTime < = lItem [ " ActivityEndDateTime " ] :
for lIndex , lItem in enumerate ( lDaemonActivityLogDict ) :
pass
if lItem [ " ActivityEndDateTime " ] and lCurrentDateTime < = lItem [ " ActivityEndDateTime " ] :
# Activity is actual - do not delete now
pass
else :
# Activity is actual - do not delete now
# remove the activity - not actual
else :
lDaemonActivityLogDict . pop ( lIndex , None )
# remove the activity - not actual
lIterationLastDateTime = lDaemonLastDateTime # Get current datetime before iterator (need for iterate all activities in loop)
lDaemonActivityLogDict . pop ( lIndex , None )
# Iterate throught the activity list
lIterationLastDateTime = lDaemonLastDateTime # Get current datetime before iterator (need for iterate all activities in loop)
for lIndex , lItem in enumerate ( gSettingsDict [ " Scheduler " ] [ " ActivityTimeList " ] ) :
# Iterate throught the activity list
# Prepare GUID of the activity
for lIndex , lItem in enumerate ( gSettingsDict [ " SchedulerDict " ] [ " ActivityTimeList " ] ) :
lGUID = None
try :
if " GUID " in lItem and lItem [ " GUID " ] :
# Prepare GUID of the activity
lGUID = lItem [ " GUID " ]
lGUID = None
else :
if " GUID " in lItem and lItem [ " GUID " ] :
lGUID = str ( uuid . uuid4 ( ) )
lGUID = lItem [ " GUID " ]
lItem [ " GUID " ] = lGUID
else :
lGUID = str ( uuid . uuid4 ( ) )
#Проверка дней недели, в рамках которых можно запускать активность
lItem [ " GUID " ] = lGUID
lItemWeekdayList = lItem . get ( " WeekdayList " , [ 0 , 1 , 2 , 3 , 4 , 5 , 6 ] )
if lCurrentDateTime . weekday ( ) in lItemWeekdayList :
#Проверка дней недели, в рамках которых можно запускать активность
if lFlagSearchActivityType :
lItemWeekdayList = lItem . get ( " WeekdayList " , [ 0 , 1 , 2 , 3 , 4 , 5 , 6 ] )
#######################################################################
if lCurrentDateTime . weekday ( ) in lItemWeekdayList :
#Branch 1 - if has TimeHH:MM
if lFlagSearchActivityType :
#######################################################################
#######################################################################
if " TimeHH:MM " in lItem :
#Branch 1 - if has TimeHH:MM
#Вид активности - запуск процесса
#######################################################################
#Сформировать временной штамп, относительно которого надо будет проверять время
if " TimeHH:MM " in lItem :
#часовой пояс пока не учитываем
#Вид активности - запуск процесса
lActivityDateTime = datetime . datetime . strptime ( lItem [ " TimeHH:MM " ] , " % H: % M " )
#Сформировать временной штамп, относительно которого надо будет проверять время
lActivityDateTime = lActivityDateTime . replace ( year = lCurrentDateTime . year , month = lCurrentDateTime . month , day = lCurrentDateTime . day )
#часовой пояс пока не учитываем
#Убедиться в том, что время наступило
lActivityDateTime = datetime . datetime . strptime ( lItem [ " TimeHH:MM " ] , " % H: % M " )
if (
lActivityDateTime = lActivityDateTime . replace ( year = lCurrentDateTime . year , month = lCurrentDateTime . month , day = lCurrentDateTime . day )
lActivityDateTime > = lDaemonLastDateTime and
#Убедиться в том, что время наступило
lCurrentDateTime > = lActivityDateTime ) :
if (
# Log info about activity
lActivityDateTime > = lDaemonLastDateTime and
if lL : lL . info ( f " Scheduler:: Activity is started. Scheduler item: { lItem } " ) #Logging
lCurrentDateTime > = lActivityDateTime ) :
# Do the activity
# Log info about activity
Processor . ActivityListOrDict ( lItem [ " Activity " ] )
if lL : lL . info ( f " Scheduler:: Activity list is started in new thread. Scheduler item: { lItem } " ) #Logging
lIterationLastDateTime = datetime . datetime . now ( ) # Set the new datetime for the new processor activity
# Do the activity
#######################################################################
lThread = threading . Thread ( target = Processor . ActivityListExecute , kwargs = { " inGSettings " : inGSettings , " inActivityList " : lItem [ " ActivityList " ] } )
#Branch 2 - if TimeHH:MMStart, TimeHH:MMStop, ActivityIntervalSeconds
lThread . start ( )
#######################################################################
lIterationLastDateTime = datetime . datetime . now ( ) # Set the new datetime for the new processor activity
if " TimeHH:MMStart " in lItem and " TimeHH:MMStop " in lItem and " ActivityIntervalSeconds " in lItem :
#######################################################################
#Сформировать временной штамп, относительно которого надо будет проверять время
#Branch 2 - if TimeHH:MMStart, TimeHH:MMStop, ActivityIntervalSeconds
#часовой пояс пока не учитываем
#######################################################################
lActivityDateTime = datetime . datetime . strptime ( lItem [ " TimeHH:MMStart " ] , " % H: % M " )
if " TimeHH:MMStart " in lItem and " TimeHH:MMStop " in lItem and " ActivityIntervalSeconds " in lItem :
lActivityDateTime = lActivityDateTime . replace ( year = lCurrentDateTime . year , month = lCurrentDateTime . month , day = lCurrentDateTime . day )
#Сформировать временной штамп, относительно которого надо будет проверять время
lActivityTimeEndDateTime = datetime . datetime . strptime ( lItem [ " TimeHH:MMStop " ] , " % H: % M " )
#часовой пояс пока не учитываем
lActivityTimeEndDateTime = lActivityTimeEndDateTime . replace ( year = lCurrentDateTime . year , month = lCurrentDateTime . month , day = lCurrentDateTime . day )
lActivityDateTime = datetime . datetime . strptime ( lItem [ " TimeHH:MMStart " ] , " % H: % M " )
#Убедиться в том, что время наступило
lActivityDateTime = lActivityDateTime . replace ( year = lCurrentDateTime . year , month = lCurrentDateTime . month , day = lCurrentDateTime . day )
if (
lActivityTimeEndDateTime = datetime . datetime . strptime ( lItem [ " TimeHH:MMStop " ] , " % H: % M " )
lCurrentDateTime < lActivityTimeEndDateTime and
lActivityTimeEndDateTime = lActivityTimeEndDateTime . replace ( year = lCurrentDateTime . year , month = lCurrentDateTime . month , day = lCurrentDateTime . day )
lCurrentDateTime > = lActivityDateTime and
#Убедиться в том, что время наступило
( lGUID , lActivityDateTime ) not in lDaemonActivityLogDict ) :
if (
#Запись в массив отработанных активностей
lCurrentDateTime < lActivityTimeEndDateTime and
lDaemonActivityLogDict [ ( lGUID , lActivityDateTime ) ] = { " ActivityStartDateTime " : lCurrentDateTime , " ActivityEndDateTime " : lActivityTimeEndDateTime }
lCurrentDateTime > = lActivityDateTime and
#Запуск циклической процедуры
( lGUID , lActivityDateTime ) not in lDaemonActivityLogDict ) :
Timer . activityLoopStart ( lItem [ " ActivityIntervalSeconds " ] , lActivityTimeEndDateTime , lItem [ " Activity " ] )
#Запись в массив отработанных активностей
lDaemonLastDateTime = lIterationLastDateTime # Set the new datetime for the new processor activity
lDaemonActivityLogDict [ ( lGUID , lActivityDateTime ) ] = { " ActivityStartDateTime " : lCurrentDateTime , " ActivityEndDateTime " : lActivityTimeEndDateTime }
#Уснуть до следующего прогона
#Запуск циклической процедуры
time . sleep ( lDaemonLoopSeconds )
Timer . activityLoopStart ( lItem [ " ActivityIntervalSeconds " ] , lActivityTimeEndDateTime , lItem [ " Activity " ] )
except Exception as e :
if lL : lL . exception ( f " Scheduler: Exception has been catched in Scheduler module when activity time item was initialising. ActivityTimeItem is { lItem } " )
lDaemonLastDateTime = lIterationLastDateTime # Set the new datetime for the new processor activity
#Уснуть до следующего прогона
time . sleep ( lDaemonLoopSeconds )
except Exception as e :
if lL : lL . exception ( f " Scheduler: Exception has been catched in Scheduler module. Global error " )
# Backward compatibility below to 1.2.0
# Backward compatibility below to 1.2.0
def __deprecated_orchestrator_start__ ( ) :
def __deprecated_orchestrator_start__ ( ) :