dev in progress - need update for GUID -do not create it

+- Add absolute/relative import for the control panels
+- Add new Orchestrator defs:
+- - def OrchestratorAccessUserUpdate(inGSettings, inADLoginStr, inADStr="", inADIsDefaultBool=True, inURLList=[], inCPAllowKeyList=[]): - Update user access
+- - def OrchestratorAccessSuperTokenAdd(inGSettings, inSuperTokenStr): # Add supertoken for the all access (it is need for the robot communication without human)
dev-linux
Ivan Maslov 4 years ago
parent 921f8f72a2
commit a0e85bb795

@ -0,0 +1,47 @@
import psutil, datetime, logging, os, sys # stdout from logging
# Config settings
lPyOpenRPASourceFolderPathStr = r"..\Sources" # Path for test pyOpenRPA package
# INFO Relative/Absolute import see below - after settings init
# Template for import CP - Control Panels
# ATTENTION - Pay attention to CP names! Orchestrator is one for the all control panels per one machine
## !!! For Absolute import !!!
# sys.path.insert(0,os.path.abspath(os.path.join(r"..\ROBOT\Builds")))
# import pyRobot_CP
# pyRobot_CP.SettingsUpdate(inGSettings=gSettings)
## !!! For Relative import !!!
# sys.path.insert(0,os.path.abspath(os.path.join(r"..\ROBOT\Builds")))
# from pyRobot_CP import ControlPanel
# ControlPanel.SettingsUpdate(inGSettings=gSettings)
# Operations
if lPyOpenRPASourceFolderPathStr != "": sys.path.insert(0,os.path.abspath(os.path.join(lPyOpenRPASourceFolderPathStr))) # Path for test pyOpenRPA package
# Start import after config the pyOpenRPA folder
from pyOpenRPA.Orchestrator import SettingsTemplate # Import functionallity
if __name__ == "__main__": # New init way - allow run as module -m PyOpenRPA.Orchestrator
from pyOpenRPA.Orchestrator import Orchestrator # Import orchestrator main
gSettings = SettingsTemplate.Create(inModeStr="BASIC") # Create GSettings with basic configuration
# TEST Add User ND - Add Login ND to superuser of the Orchestrator
Orchestrator.OrchestratorAccessUserUpdate(inGSettings=gSettings, inADLoginStr="ND", inADStr="", inADIsDefaultBool=True, inURLList=[],inCPAllowKeyList=[])
# TEST Add User IMaslov - Add Login IMaslov to superuser of the Orchestrator
Orchestrator.OrchestratorAccessUserUpdate(inGSettings=gSettings, inADLoginStr="IMaslov", inADStr="", inADIsDefaultBool=True, inURLList=[],inCPAllowKeyList=[])
# TEST Add Supertoken for the all access between robots
Orchestrator.OrchestratorAccessSuperTokenAdd(inGSettings=gSettings, inSuperTokenStr="1992-04-03-0643-ru-b4ff-openrpa52zzz")
## !!! For Relative import !!! CP Version Check
sys.path.insert(0,os.path.abspath(os.path.join(r"")))
from ControlPanel import CP_VersionCheck
CP_VersionCheck.SettingsUpdate(inGSettings=gSettings)
# Call the orchestrator def
Orchestrator.Orchestrator(inGSettings=gSettings)
else:
print("!WARNING! Current orchestrator settings do not support old type of the Orchestrator start. Use new Orchestrator type start (see v1.2.0)")

@ -1,32 +0,0 @@
# Init Section
gUserNameStr = "IMaslov" # User name
gDomainNameStr = "" # DOMAIN or EMPTY str
gDomainIsDefaultBool = True # If domain is exist and is default (default = you can type login without domain name)
def SettingsUpdate(inDict):
lRuleDomainUserDict = {
"MethodMatchURLBeforeList": [
{
"Method":"GET",
"MatchType":"Beginwith",
"URL":"/",
#"FlagAccessDefRequestGlobalAuthenticate": TestDef
"FlagAccess": True
},
{
"Method":"POST",
"MatchType":"Beginwith",
"URL":"/",
#"FlagAccessDefRequestGlobalAuthenticate": TestDef
"FlagAccess": True
}
],
"ControlPanelKeyAllowedList": ["TestControlPanel", "RobotRDPActive","RobotScreenActive", "ControlPanel_Template"] # If empty - all is allowed
}
# Case add domain + user
inDict["Server"]["AccessUsers"]["RuleDomainUserDict"].update({(gDomainNameStr.upper(),gUserNameStr.upper()):lRuleDomainUserDict})
if gDomainIsDefaultBool:
# Case add default domain + user
inDict["Server"]["AccessUsers"]["RuleDomainUserDict"].update({("",gUserNameStr.upper()):lRuleDomainUserDict})
#Return current dict
return inDict

@ -1,32 +0,0 @@
# Init Section
gUserNameStr = "ND" # User name
gDomainNameStr = "" # DOMAIN or EMPTY str
gDomainIsDefaultBool = True # If domain is exist and is default (default = you can type login without domain name)
def SettingsUpdate(inDict):
lRuleDomainUserDict = {
"MethodMatchURLBeforeList": [
{
"Method":"GET",
"MatchType":"Beginwith",
"URL":"/",
#"FlagAccessDefRequestGlobalAuthenticate": TestDef
"FlagAccess": True
},
{
"Method":"POST",
"MatchType":"Beginwith",
"URL":"/",
#"FlagAccessDefRequestGlobalAuthenticate": TestDef
"FlagAccess": True
}
],
"ControlPanelKeyAllowedList": ["TestControlPanel", "RobotRDPActive","RobotScreenActive", "ControlPanel_Template"] # If empty - all is allowed
}
# Case add domain + user
inDict["Server"]["AccessUsers"]["RuleDomainUserDict"].update({(gDomainNameStr.upper(),gUserNameStr.upper()):lRuleDomainUserDict})
if gDomainIsDefaultBool:
# Case add default domain + user
inDict["Server"]["AccessUsers"]["RuleDomainUserDict"].update({("",gUserNameStr.upper()):lRuleDomainUserDict})
#Return current dict
return inDict

@ -1,40 +0,0 @@
import datetime
# Init Section
gUserNameStr = "SUPERTOKEN" # User name
gDomainNameStr = "" # DOMAIN or EMPTY str
gDomainIsDefaultBool = False # If domain is exist and is default (default = you can type login without domain name)
gAuthTokenPermanentStr = "1992-04-03-0643-ru-b4ff-openrpa52zzz" # Set the permanent Auth token if it is needed, or empty
def SettingsUpdate(inDict):
lRuleDomainUserDict = {
"MethodMatchURLBeforeList": [
{
"Method":"GET",
"MatchType":"Beginwith",
"URL":"/",
#"FlagAccessDefRequestGlobalAuthenticate": TestDef
"FlagAccess": True
},
{
"Method":"POST",
"MatchType":"Beginwith",
"URL":"/",
#"FlagAccessDefRequestGlobalAuthenticate": TestDef
"FlagAccess": True
}
],
"ControlPanelKeyAllowedList": ["TestControlPanel", "RobotRDPActive","RobotScreenActive", "ControlPanel_Template"] # If empty - all is allowed
}
# Case add domain + user
inDict["Server"]["AccessUsers"]["RuleDomainUserDict"].update({(gDomainNameStr.upper(),gUserNameStr.upper()):lRuleDomainUserDict})
if gDomainIsDefaultBool:
# Case add default domain + user
inDict["Server"]["AccessUsers"]["RuleDomainUserDict"].update({("",gUserNameStr.upper()):lRuleDomainUserDict})
#"<AuthToken>":{"User":"", "Domain":"", "TokenDatetime":<Datetime>}
#!!!!!!!!!!!!!!!!!!!!!!!
#Attention: default supertoken is 1992-04-03-0643-ru-b4ff-openrpa52zzz - please change it when you will customize OpenRPA in your company
#!!!!!!!!!!!!!!!!!!!!!!!
inDict["Server"]["AccessUsers"]["AuthTokensDict"].update(
{gAuthTokenPermanentStr:{"User":gUserNameStr, "Domain":gDomainNameStr, "TokenDatetime": datetime.datetime.now(), "FlagDoNotExpire":True}}
)
#Return current dict
return inDict

@ -1,390 +0,0 @@
import psutil
import datetime
import logging
import sys # stdout fro logging
import os
# Init variables
gControlPanelPyFilePathList = [ # .py file path list for call SettingsUpdate
#r""
]
def RenderRobotR01(inGlobalConfiguration):
#Subheader Variants
lSubheaderRunTrueText="Состояние: <span style=\"color:green\">Работает</span>"
lSubheaderRunFalseText="Состояние: <span style=\"color:red\">Не работает</span>"
#Run button
#Такое большое количество слэшей связано с тем, что этот текст отправляется сначала в браузер, рендерится там, а потом отправляется на процессор оркестратора
lOnClickRunButton="""mGlobal.Controller.CMDRunText('C:\\test.png');"""
#Force close button
lOnClickForceCloseButton="""mGlobal.Controller.CMDRunText('taskkill /F /im Robot_R01.exe');"""
#Result template
lResultDict={
"HeaderLeftText":"Автозагрузка заявок на расход",
"HeaderRightText":"R01",
"DataStorageKey":"R01_Data", #Use key for set current dict in mGlobal.DataStorage["DtaaStorageKey"] on client side
"SubheaderText":lSubheaderRunFalseText,
"BodyKeyValueList":[
#Дата запуска: 10:00:09 01.09.2019
{"Key":"Дата запуска","Value":"Не запущен"},
{"Key":"Текущий шаг","Value":"Не запущен"},
{"Key":"Время выполнения шага","Value":"--с."},
{"Key":"Отчет робота","Value":"<a href=\"filemanager/r01/report.xlsx\">Скачать</a>"}
],
"FooterText":"Дата изменения: 9:38:00 09.10.2019",
"FooterButtonX2List":[
{"Text":"Ручной запуск", "Color":"green", "Link":"", "OnClick": lOnClickRunButton.replace("\\","\\\\")},
{"Text":"Безопасная остановка", "Color disabled":"orange", "Link":""}
],
"FooterButtonX1List":[
{"Text":"Принудительная остановка", "Color":"red", "Link":"", "OnClick": lOnClickForceCloseButton.replace("\\","\\\\")}
]
}
#Check if process running
if CheckIfProcessRunning("Robot_R01"):
lResultDict["SubheaderText"]=lSubheaderRunTrueText
#Fill robot info from Storage - R01
if "Robot_R01" in inGlobalConfiguration.get("Storage",{}):
lItemDict=inGlobalConfiguration["Storage"]["Robot_R01"]
#lResultDict["HeaderLeftText"]=lItemDict["Name"]
#lResultDict["HeaderRightText"]=lItemDict["Code"]
lResultDict["BodyKeyValueList"][0]["Value"]=lItemDict.get("RunDateTimeString","Не запущен")
lResultDict["BodyKeyValueList"][1]["Value"]=lItemDict.get("StepCurrentName","Не запущен")
lResultDict["BodyKeyValueList"][2]["Value"]=lItemDict.get("StepCurrentDuration","--с.")
else:
#Process not running
lResultDict["FooterText"]=f'Дата изменения: {datetime.datetime.now().strftime("%H:%M:%S %d.%m.%Y")}'
else:
#Process not running
lResultDict["FooterText"]=f'Дата изменения: {datetime.datetime.now().strftime("%H:%M:%S %d.%m.%Y")}'
return lResultDict
def CheckIfProcessRunning(processName):
'''
Check if there is any running process that contains the given name processName.
'''
#Iterate over the all the running process
for proc in psutil.process_iter():
try:
# Check if process name contains the given name string.
if processName.lower() in proc.name().lower():
return True
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
pass
return False;
#Orchestrator settings
def Settings():
import os
import pyOpenRPA.Orchestrator
lOrchestratorFolder = "\\".join(pyOpenRPA.Orchestrator.__file__.split("\\")[:-1])
mDict = {
"Autocleaner": { # Some gurbage is collecting in g settings. So you can configure autocleaner to periodically clear gSettings
"IntervalSecFloat": 600.0, # Sec float to periodically clear gsettings
},
"Client":{ # Settings about client web orchestrator
"Session":{ # Settings about web session. Session algorythms works only for special requests (URL in ServerSettings)
"LifetimeSecFloat": 600.0, # Client Session lifetime in seconds. after this time server will forget about this client session
"LifetimeRequestSecFloat": 120.0, # 1 client request lifetime in server in seconds
"ControlPanelRefreshIntervalSecFloat": 1.5, # Interval to refresh control panels for session,
"TechnicalSessionGUIDCache": { # TEchnical cache. Fills when web browser is requesting
#"SessionGUIDStr":{ # Session with some GUID str. On client session guid stored in cookie "SessionGUIDStr"
# "InitDatetime": None, # Datetime when session GUID was created
# "DatasetLast": {
# "ControlPanel": {
# "Data": None, # Struct to check with new iterations. None if starts
# "ReturnBool": False # flag to return, close request and return data as json
# }
# },
# "ClientRequestHandler": None, # Last client request handler
# "UserADStr": None, # User, who connect. None if user is not exists
# "DomainADStr": None, # Domain of the user who connect. None if user is not exists
#}
}
}
},
"Server": {
"WorkingDirectoryPathStr": None , # Will be filled automatically
"RequestTimeoutSecFloat": 300, # Time to handle request in seconds
"ListenPort_": "Порт, по которому можно подключиться к демону",
"ListenPort": 80,
"ListenURLList": [
{
"Description": "Local machine test",
"URL_": "Сетевое расположение сервера демона",
"URL": ""
}
],
"AccessUsers": { #Default - all URL is blocked
"FlagCredentialsAsk": True, #Turn on Authentication
"RuleDomainUserDict": {
#("DOMAIN", "USER"): { !!!!! only in upper case !!!!
# "MethodMatchURLBeforeList": [
# {
# "Method":"GET|POST",
# "MatchType":"BeginWith|Contains|Equal|EqualCase",
# "URL":"",
# "FlagAccessDefRequestGlobalAuthenticate": None, #Return bool
# "FlagAccess": True
# }
# ],
# "ControlPanelKeyAllowedList":[], # If empty - all is allowed
# "RoleHierarchyAllowedDict": {
# "Orchestrator":{
# "Controls": {
# "RestartOrchestrator": {}, # Feature to restart orchestrator on virtual machine
# "LookMachineScreenshots": {} # Feature to look machina screenshots
# },
# "RDPActive": { # Robot RDP active module
# "ListRead": {} # Access to read RDP session list
# }
# }
# }
# }
},
"RuleMethodMatchURLBeforeList": [ #General MethodMatchURL list (no domain/user)
# {
# "Method":"GET|POST",
# "MatchType":"BeginWith|Contains|Equal|EqualCase",
# "URL":"",
# "FlagAccessDefRequestGlobalAuthenticate": None, #Return bool
# "FlagAccess": True
# }
],
"AuthTokensDict": {
#"<AuthToken>":{"User":"", "Domain":"", "TokenDatetime":<Datetime>, "FlagDoNotExpire":True}
}
},
"URLList":[ #List of available URLs with the orchestrator server
#{
# "Method":"GET|POST",
# "URL": "/index", #URL of the request
# "MatchType": "", #"BeginWith|Contains|Equal|EqualCase",
# "ResponseFilePath": "", #Absolute or relative path
# "ResponseFolderPath": "", #Absolute or relative path
# "ResponseContentType": "", #HTTP Content-type
# "ResponseDefRequestGlobal": None #Function with str result
#}
{
"Method":"GET",
"URL": "/test/", #URL of the request
"MatchType": "BeginWith", #"BeginWith|Contains|Equal|EqualCase",
#"ResponseFilePath": "", #Absolute or relative path
"ResponseFolderPath": "C:\Abs\Archive\scopeSrcUL\OpenRPA\Orchestrator\Settings", #Absolute or relative path
#"ResponseContentType": "", #HTTP Content-type
#"ResponseDefRequestGlobal": None #Function with str result
}
]
},
"OrchestratorStart":{
"DefSettingsUpdatePathList":[], # List of the .py files which should be loaded before init the algorythms
"ActivityList":[
#{
# "Type": "ProcessStop", #Activity type
# "Name": "OpenRPARobotDaemon.exe", #Process name
# "FlagForce": True, #Force process close
# "User": "%username%" #Empty, user or %username%
#},
#{
# "Type": "ProcessStartIfTurnedOff", #Activity type
# "CheckTaskName": "notepad.exe", #Python function module name
# "Path": "notepad", #Python function name
# "ArgList": [] #Input python function args
#},
# {
# "Type": "RDPSessionConnect", #Activity type - start/connect RDP Session
# "RDPSessionKeyStr": "notepad.exe", #Python function module name
# "RDPConfigurationDict": {}
# },
# {
# "Type": "RDPSessionLogoff", #Activity type - logoff RDP Session
# "RDPSessionKeyStr": "notepad.exe", #Python function module name
# },
# {
# "Type": "RDPSessionDisconnect", #Activity type - disconnect the RDP Session without logoff
# "RDPSessionKeyStr": "notepad.exe", #Python function module name
# },
# {
# "Type": "RDPSessionFileSend", #Activity type - send file to RDP session
# ...
# },
# {
# "Type": "RDPSessionFileRecieve", #Activity type - recieve file from rdp session
# ...
# },
# {
# "Type": "RDPSessionProcessStart", #Activity type -
# ...
# },
]
},
"Scheduler": {
"ActivityTimeCheckLoopSeconds":5, #Количество секунд, между циклами проверки действий
"ActivityTimeList": [
{
"TimeHH:MM": "22:23", #Time [HH:MM] to trigger activity
"WeekdayList": [1,2,3,4,5,6,7], #List of the weekday index when activity is applicable, Default [1,2,3,4,5,6,7]
"Activity":{
"Type": "ProcessStart", #Activity type
"Path": "start", #Executable file path
"ArgList": ["cmd.exe","/c","PIPUpgrade.cmd"] #List of the arguments
},
"GUID": None #Will be fied in Orchestrator automatically - is needed for detect activity completion
},
{
"TimeHH:MM": "19:20", #Time [HH:MM] to trigger activity
"WeekdayList": [1, 2, 3], #List of the weekday index when activity is applicable, Default [1,2,3,4,5,6,7]
"Activity":{
"Type": "ProcessStop", #Activity type
"Name": "OpenRPARobotDaemon.exe", #Process name
"FlagForce": True, #Force process close
"User": "%username%" #Empty, user or %username%
},
"GUID": None #Will be fied in Orchestrator automatically - is needed for detect activity completion
},
{
"TimeHH:MMStart": "12:40", #Time [HH:MM] to trigger activity
"TimeHH:MMStop": "12:40",
"ActivityIntervalSeconds": 2,
"WeekdayList": [1, 2, 3, 4, 5, 6, 7], #List of the weekday index when activity is applicable, Default [1,2,3,4,5,6,7]
"Activity":{
"Type": "ProcessStartIfTurnedOff", #Activity type
"CheckTaskName": "notepad.exe", #Python function module name
"Path": "notepad", #Python function name
"ArgList": [] #Input python function args
},
"GUID": None #Will be fied in Orchestrator automatically - is needed for detect activity completion
}
]
},
"ProcessorDict": { # Has been changed. New general processor (one threaded) v.1.2.0
"ActivityList": [ # List of the activities
# {
# "Def":"DefAliasTest", # def link or def alias (look gSettings["Processor"]["AliasDefDict"])
# "ArgList":[1,2,3], # Args list
# "ArgDict":{"ttt":1,"222":2,"dsd":3} # Args dictionary
# "ArgGSettings": # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
# },
],
"AliasDefDict": {}, # Storage for def with Str alias. To use it see pyOpenRPA.Orchestrator.ControlPanel
"CheckIntervalSecFloat": 1.0, # Interval for check gSettings in ProcessorDict > ActivityList
"ExecuteBool": True, # Flag to execute thread processor
"ThreadIdInt": None # Technical field - will be setup when processor init
},
"ControlPanelDict": {
"RefreshSeconds": 5, # deprecated parameter
"RobotList": [
{
"RenderFunction": RenderRobotR01,
"KeyStr":"TestControlPanelKey"
}
]
},
# # # # # # # # # # # # # #
"RobotRDPActive":{
"RDPList": {
#"RDPSessionKey":{
# "Host": "77.77.22.22", # Host address
# "Port": "3389", # RDP Port
# "Login": "test", # Login
# "Password": "test", # Password
# "Screen": {
# "Width": 1680, # Width of the remote desktop in pixels
# "Height": 1050, # Height of the remote desktop in pixels
# # "640x480" or "1680x1050" or "FullScreen". If Resolution not exists set full screen
# "FlagUseAllMonitors": False, # True or False
# "DepthBit": "32" # "32" or "24" or "16" or "15"
# },
# "SharedDriveList": ["c"], # List of the Root sesion hard drives
# ###### Will updated in program ############
# "SessionHex": "", # Hex is created when robot runs
# "SessionIsWindowExistBool": False, # Flag if the RDP window is exist, old name "FlagSessionIsActive". Check every n seconds
# "SessionIsWindowResponsibleBool": False, # Flag if RDP window is responsible (recieve commands). Check every nn seconds. If window is Responsible - window is Exist too
# "SessionIsIgnoredBool": False # Flag to ignore RDP window False - dont ignore, True - ignore
#}
},
"ResponsibilityCheckIntervalSec": None,
# Seconds interval when Robot check the RDP responsibility. if None - dont check
"FullScreenRDPSessionKeyStr": None, # RDPSessionKeyStr of the current session which is full screened, None is no session in fullscreen
"ActivityList":[ # Technical Activity list for RobotRDPActive thread - equal to Main activity list, apply only RDP activity
# {
# "DefNameStr":"test", # Function name in RobotRDPActive.Processor
# "ArgList":[1,2,3], # Args list
# "ArgDict":{"ttt":1,"222":2,"dsd":3} # Args dictionary
# },
#{
# "DefNameStr": "RDPSessionConnect", # Function name in RobotRDPActive.Processor
# "ArgList": [], # Args list
# "ArgDict": {"inRDPSessionKeyStr": "TestRDP", "inHostStr": "77.44.33.22", "inPortStr": "3389",
# "inLoginStr": "login", "inPasswordStr": "pass"} # Args dictionary
#},
# {
# "DefNameStr": "RDPSessionDisconnect", # Disconnect the RDP session without logoff. Function name in RobotRDPActive.Processor
# "ArgList": [], # Args list
# "ArgDict": {"inRDPSessionKeyStr": "TestRDP"}
# },
# {
# "DefNameStr": "RDPSessionReconnect", # Disconnect the RDP session without logoff. Function name in RobotRDPActive.Processor
# "ArgList": [], # Args list
# "ArgDict": {"inRDPSessionKeyStr": "TestRDP"}
# }
]
},
# # # # # # # # # # # # # #
"FileManager": {
"FileURLFilePathDict_help": "https://localhost:8081/filemanager/<file URL>. All FileURL s must be set in lowercase",
"FileURLFilePathDict": {
"r01/report.xlsx": "C:\\RPA\\R01_IntegrationOrderOut\\Data\\Reestr_otgruzok.xlsx"
}
},
"Logger": logging.getLogger("Orchestrator"),
"Storage": {
"Robot_R01_help": "Robot data storage in orchestrator env",
"Robot_R01": {},
"R01_OrchestratorToRobot":{"Test2":"Test2"}
}
}
#Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):
os.makedirs("Reports")
##########################
#Подготовка логгера Robot
#########################
mRobotLogger=mDict["Logger"]
mRobotLogger.setLevel(logging.INFO)
# create the logging file handler
mRobotLoggerFH = logging.FileHandler("Reports\ReportOrchestrator_"+datetime.datetime.now().strftime("%Y_%m_%d")+".log")
mRobotLoggerFormatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
mRobotLoggerFH.setFormatter(mRobotLoggerFormatter)
# add handler to logger object
mRobotLogger.addHandler(mRobotLoggerFH)
####################Add console output
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(mRobotLoggerFormatter)
mRobotLogger.addHandler(handler)
############################################
###################################
#Init .py files from Settings folder
####################################
#Get file list from Settings folder
#lFunction to call in subfiles
lSubmoduleFunctionName = "SettingsUpdate"
#lSettingsPath = os.path.join(inSettingsFolderPath, "Settings")
lSettingsPath = "\\".join(os.path.join(os.getcwd(),__file__).split("\\")[:-1])
#lSettingsPath = os.path.join(os.getcwd(), "Settings")
#Lambda function to get files .py from settings folder except Settings.py
lFileList = [f for f in os.listdir(lSettingsPath) if os.path.isfile(os.path.join(lSettingsPath, f)) and f.split(".")[-1] == "py" and os.path.join(lSettingsPath, f) != __file__]
import importlib.util
for lModuleFilePathItem in lFileList + gControlPanelPyFilePathList: # UPD 2020 04 27 Add gControlPanelPyFilePathList to import py files from Robots
try: # Try to init - go next if error and log in logger
lModuleName = lModuleFilePathItem[0:-3]
lFileFullPath = os.path.join(lSettingsPath, lModuleFilePathItem)
lTechSpecification = importlib.util.spec_from_file_location(lModuleName, lFileFullPath)
lTechModuleFromSpec = importlib.util.module_from_spec(lTechSpecification)
lTechSpecificationModuleLoader = lTechSpecification.loader.exec_module(lTechModuleFromSpec)
if lSubmoduleFunctionName in dir(lTechModuleFromSpec):
#Run SettingUpdate function in submodule
getattr(lTechModuleFromSpec, lSubmoduleFunctionName)(mDict)
except Exception as e:
if mRobotLogger: mRobotLogger.exception(f"Error when init .py file in orchestrator '{lModuleFilePathItem}'. Exception is below:")
return mDict

@ -1,4 +1,4 @@
cd %~dp0\..\Sources
copy /Y ..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe ..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_Orchestrator.exe
.\..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_Orchestrator.exe -m pyOpenRPA.Orchestrator "..\Orchestrator\Settings\SettingsOrchestratorExample.py"
cd %~dp0
copy /Y ..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe ..\Resources\WPy64-3720\python-3.7.2.amd64\pyOpenRPA_Orchestrator.exe
.\..\Resources\WPy64-3720\python-3.7.2.amd64\pyOpenRPA_Orchestrator.exe "OrchestratorSettings.py"
pause >nul

@ -1,2 +1,2 @@
cd %~dp0
start pyOpenRPA.Orchestrator_x64_shortcut_admin.lnk
start pyOpenRPA.Orchestrator_x64_administrator.lnk

@ -61,6 +61,44 @@ def OrchestratorSessionSave(inGSettings=None): ## Orchestrator session save
if lL: lL.info(
f"Orchestrator has dump the RDP list before the restart. The RDP List is {inGSettings['RobotRDPActive']['RDPList']}")
return True
# Update user access
def OrchestratorAccessUserUpdate(inGSettings, inADLoginStr, inADStr="", inADIsDefaultBool=True, inURLList=[], inCPAllowKeyList=[]):
# Backward compatibility
if inURLList==[]:
inURLList=[
{
"Method": "GET",
"MatchType": "Beginwith",
"URL": "/",
# "FlagAccessDefRequestGlobalAuthenticate": TestDef
"FlagAccess": True
},
{
"Method": "POST",
"MatchType": "Beginwith",
"URL": "/",
# "FlagAccessDefRequestGlobalAuthenticate": TestDef
"FlagAccess": True
}
]
# Create Access item
lRuleDomainUserDict = {
"MethodMatchURLBeforeList": inURLList,
"ControlPanelKeyAllowedList": inCPAllowKeyList, #["TestControlPanel", "RobotRDPActive","RobotScreenActive", "ControlPanel_Template"] # If empty - all is allowed
}
# Case add domain + user
inGSettings["Server"]["AccessUsers"]["RuleDomainUserDict"].update({(inADStr.upper(),inADLoginStr.upper()):lRuleDomainUserDict})
if inADIsDefaultBool:
# Case add default domain + user
inGSettings["Server"]["AccessUsers"]["RuleDomainUserDict"].update({("",inADLoginStr.upper()):lRuleDomainUserDict})
# Add supertoken for the all access (it is need for the robot communication without human)
def OrchestratorAccessSuperTokenAdd(inGSettings, inSuperTokenStr):
lLoginStr = "SUPERTOKEN"
OrchestratorAccessUserUpdate(inGSettings=inGSettings, inADLoginStr=lLoginStr)
inGSettings["Server"]["AccessUsers"]["AuthTokensDict"].update(
{inSuperTokenStr:{"User":lLoginStr, "Domain":"", "TokenDatetime": datetime.datetime.now(), "FlagDoNotExpire":True}}
)
## GSettings defs
def GSettingsKeyListValueSet(inGSettings, inValue, inKeyList=[]): # Set value in GSettings by the key list

@ -25,6 +25,10 @@
- Orchestrator WEB fix: Don't request screenshot if no modal is active in front
- Add Version field in Orchestrator back + front
- Add front autorefresh if front/back pyOpenRPA versions are differs (see CP_VersionCheck.py)
- Add absolute/relative import for the control panels
- Add new Orchestrator defs:
- - def OrchestratorAccessUserUpdate(inGSettings, inADLoginStr, inADStr="", inADIsDefaultBool=True, inURLList=[], inCPAllowKeyList=[]): - Update user access
- - def OrchestratorAccessSuperTokenAdd(inGSettings, inSuperTokenStr): # Add supertoken for the all access (it is need for the robot communication without human)
[1.1.0]
After 2 month test prefinal with new improovements (+RobotRDPActive in Orchestrator + Easy ControlPanelTemplate)
Beta before 1.1.0 (new way of OpenRPA with improvements. Sorry, but no backward compatibility)/ Backward compatibility will start from 1.0.1

Loading…
Cancel
Save