diff --git a/Orchestrator/Settings/CP_VersionCheck.py b/Orchestrator/ControlPanel/CP_VersionCheck.py similarity index 100% rename from Orchestrator/Settings/CP_VersionCheck.py rename to Orchestrator/ControlPanel/CP_VersionCheck.py diff --git a/Orchestrator/OrchestratorSettings.py b/Orchestrator/OrchestratorSettings.py new file mode 100644 index 00000000..c7e3d7b9 --- /dev/null +++ b/Orchestrator/OrchestratorSettings.py @@ -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)") + diff --git a/Orchestrator/HowToConfigureOrchestrator.txt b/Orchestrator/Readme/HowToConfigureOrchestrator.txt similarity index 100% rename from Orchestrator/HowToConfigureOrchestrator.txt rename to Orchestrator/Readme/HowToConfigureOrchestrator.txt diff --git a/Orchestrator/ProcessorTypes.txt b/Orchestrator/Readme/ProcessorTypes.txt similarity index 100% rename from Orchestrator/ProcessorTypes.txt rename to Orchestrator/Readme/ProcessorTypes.txt diff --git a/Orchestrator/Settings/AccessUser_IMaslov.py b/Orchestrator/Settings/AccessUser_IMaslov.py deleted file mode 100644 index f3dc2507..00000000 --- a/Orchestrator/Settings/AccessUser_IMaslov.py +++ /dev/null @@ -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 \ No newline at end of file diff --git a/Orchestrator/Settings/AccessUser_ND.py b/Orchestrator/Settings/AccessUser_ND.py deleted file mode 100644 index 7f359fc7..00000000 --- a/Orchestrator/Settings/AccessUser_ND.py +++ /dev/null @@ -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 \ No newline at end of file diff --git a/Orchestrator/Settings/AccessUser_SuperToken.py b/Orchestrator/Settings/AccessUser_SuperToken.py deleted file mode 100644 index 16674c0e..00000000 --- a/Orchestrator/Settings/AccessUser_SuperToken.py +++ /dev/null @@ -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}) - #"":{"User":"", "Domain":"", "TokenDatetime":} - #!!!!!!!!!!!!!!!!!!!!!!! - #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 \ No newline at end of file diff --git a/Orchestrator/Settings/SettingsOrchestratorExample.py b/Orchestrator/Settings/SettingsOrchestratorExample.py deleted file mode 100644 index 813e09df..00000000 --- a/Orchestrator/Settings/SettingsOrchestratorExample.py +++ /dev/null @@ -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="Состояние: Работает" - lSubheaderRunFalseText="Состояние: Не работает" - #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":"Скачать"} - ], - "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": { - #"":{"User":"", "Domain":"", "TokenDatetime":, "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/. 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 \ No newline at end of file diff --git a/Orchestrator/Settings/__init__.py b/Orchestrator/Settings/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/Orchestrator/pyOpenRPA.Orchestrator_x64.cmd b/Orchestrator/pyOpenRPA.Orchestrator_x64.cmd index e13afe15..ddb14a81 100644 --- a/Orchestrator/pyOpenRPA.Orchestrator_x64.cmd +++ b/Orchestrator/pyOpenRPA.Orchestrator_x64.cmd @@ -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 \ No newline at end of file diff --git a/Orchestrator/pyOpenRPA.Orchestrator_x64_administrator_startup.cmd b/Orchestrator/pyOpenRPA.Orchestrator_x64_administrator_startup.cmd index 186aa981..2b98f0ea 100644 --- a/Orchestrator/pyOpenRPA.Orchestrator_x64_administrator_startup.cmd +++ b/Orchestrator/pyOpenRPA.Orchestrator_x64_administrator_startup.cmd @@ -1,2 +1,2 @@ cd %~dp0 -start pyOpenRPA.Orchestrator_x64_shortcut_admin.lnk \ No newline at end of file +start pyOpenRPA.Orchestrator_x64_administrator.lnk \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/pyOpenRPA_Orchestrator.exe b/Resources/WPy64-3720/python-3.7.2.amd64/pyOpenRPA_Orchestrator.exe new file mode 100644 index 00000000..66a6265c Binary files /dev/null and b/Resources/WPy64-3720/python-3.7.2.amd64/pyOpenRPA_Orchestrator.exe differ diff --git a/Sources/pyOpenRPA/Orchestrator/Orchestrator.py b/Sources/pyOpenRPA/Orchestrator/Orchestrator.py index a7527947..b18fbbff 100644 --- a/Sources/pyOpenRPA/Orchestrator/Orchestrator.py +++ b/Sources/pyOpenRPA/Orchestrator/Orchestrator.py @@ -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 diff --git a/changelog.md b/changelog.md index 3c7dee7b..d73ee49f 100644 --- a/changelog.md +++ b/changelog.md @@ -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