Compare commits
No commits in common. "main" and "ping3" have entirely different histories.
30
CHANGELOG.md
|
@ -6,36 +6,6 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [5.1.1] - 2025-05-06
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fixed URL for notifying stop to ogcore
|
|
||||||
|
|
||||||
## [5.1.0] - 2025-05-06
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Added powershell helper script for logging out from windows
|
|
||||||
|
|
||||||
## [5.0.0] - 2025-05-06
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Use TLS
|
|
||||||
|
|
||||||
## [4.0.0] - 2025-04-24
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Authn/authz to the oglive agent
|
|
||||||
|
|
||||||
## [3.3.0] - 2025-04-14
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Log stuff to a new json log
|
|
||||||
|
|
||||||
## [3.2.0] - 2025-04-10
|
## [3.2.0] - 2025-04-10
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
Before Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 43 KiB |
|
@ -1,47 +0,0 @@
|
||||||
## Crear tarea programada para matar el agente de Windows al cerrar sesión
|
|
||||||
|
|
||||||
1. Abrir el task scheduler y pinchar en Create task:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
2. Rellenar el nombre y luego pinchar en Change user or group:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
3. Pinchar en Advanced:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
4. Pinchar en Find now:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
5. Seleccionar Administrator y luego Ok, y luego Ok:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
6. De vuelta en la pantalla de crear tarea, ir a la pestaña Triggers y pinchar en New:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
7. Seleccionar "On disconnect from user session", seleccionar "Connection from local computer", y luego Ok:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
8. Ir a la pestaña "Actions" y pinchar en New:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
9. Pinchar en Browse, seleccionar C:\Program Files (x86)\OGAgent\stop-agent.ps1, y luego Ok:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
10. Ir a la pestaña Conditions y desmarcar las condiciones relativas a Power:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
11. Pinchar Ok y la tarea programada queda creada.
|
|
||||||
|
|
||||||
En caso de usar remotepc, hay que repetir todos estos pasos, es decir, crear una
|
|
||||||
tarea programada nueva, seleccionando "Connection from remote computer" en lugar
|
|
||||||
de "Connection from local computer".
|
|
|
@ -1,39 +1,3 @@
|
||||||
ogagent (5.1.1-1) stable; urgency=medium
|
|
||||||
|
|
||||||
* Fix URL for notifying stop to ogcore
|
|
||||||
|
|
||||||
-- OpenGnsys developers <info@opengnsys.es> Tue, 06 May 2025 13:31:48 +0200
|
|
||||||
|
|
||||||
ogagent (5.1.0-1) stable; urgency=medium
|
|
||||||
|
|
||||||
* Include powershell helper script for logging out of windows
|
|
||||||
|
|
||||||
-- OpenGnsys developers <info@opengnsys.es> Tue, 06 May 2025 13:30:59 +0200
|
|
||||||
|
|
||||||
ogagent (5.0.0-1) stable; urgency=medium
|
|
||||||
|
|
||||||
* Use TLS
|
|
||||||
|
|
||||||
-- OpenGnsys developers <info@opengnsys.es> Fri, 25 Apr 2025 13:09:49 +0200
|
|
||||||
|
|
||||||
ogagent (4.0.0-1) stable; urgency=medium
|
|
||||||
|
|
||||||
* Handle authn/authz in the oglive agent
|
|
||||||
|
|
||||||
-- OpenGnsys developers <info@opengnsys.es> Thu, 24 Apr 2025 13:28:57 +0200
|
|
||||||
|
|
||||||
ogagent (3.3.0-1) stable; urgency=medium
|
|
||||||
|
|
||||||
* Create an additional json log file
|
|
||||||
|
|
||||||
-- OpenGnsys developers <info@opengnsys.es> Mon, 14 Apr 2025 13:50:32 +0200
|
|
||||||
|
|
||||||
ogagent (3.2.0-1) stable; urgency=medium
|
|
||||||
|
|
||||||
* Operating system: periodically ping ogcore
|
|
||||||
|
|
||||||
-- OpenGnsys developers <info@opengnsys.es> Thu, 10 Apr 2025 11:37:35 +0200
|
|
||||||
|
|
||||||
ogagent (3.1.0-1) stable; urgency=medium
|
ogagent (3.1.0-1) stable; urgency=medium
|
||||||
|
|
||||||
* Oglive: periodically ping ogcore
|
* Oglive: periodically ping ogcore
|
||||||
|
|
|
@ -99,4 +99,3 @@ coll = COLLECT(
|
||||||
|
|
||||||
import shutil
|
import shutil
|
||||||
shutil.copytree ('cfg', '{}/{}/cfg'.format(DISTPATH, dist_name))
|
shutil.copytree ('cfg', '{}/{}/cfg'.format(DISTPATH, dist_name))
|
||||||
shutil.copy ('stop-agent.ps1', '{}/{}/stop-agent.ps1'.format(DISTPATH, dist_name))
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
5.1.1
|
3.1.0
|
||||||
|
|
|
@ -17,12 +17,6 @@ level=full
|
||||||
# Log Level, if omitted, will be set to INFO
|
# Log Level, if omitted, will be set to INFO
|
||||||
log=DEBUG
|
log=DEBUG
|
||||||
|
|
||||||
# TLS
|
|
||||||
ca=C:\Program Files (x86)\OGagent\ca.crt
|
|
||||||
crt=C:\Program Files (x86)\OGagent\ogagent.crt
|
|
||||||
key=C:\Program Files (x86)\OGagent\ogagent.key
|
|
||||||
|
|
||||||
|
|
||||||
# Module specific
|
# Module specific
|
||||||
# The sections must match the module name
|
# The sections must match the module name
|
||||||
# This section will be passes on activation to module
|
# This section will be passes on activation to module
|
||||||
|
@ -34,8 +28,3 @@ log=DEBUG
|
||||||
pathinterface=/opt/opengnsys/interfaceAdm
|
pathinterface=/opt/opengnsys/interfaceAdm
|
||||||
urlMenu={}://{}/menu-browser
|
urlMenu={}://{}/menu-browser
|
||||||
urlMsg=http://localhost/cgi-bin/httpd-log.sh
|
urlMsg=http://localhost/cgi-bin/httpd-log.sh
|
||||||
|
|
||||||
# TLS
|
|
||||||
ca=/opt/opengnsys/etc/ca.crt
|
|
||||||
crt=/opt/opengnsys/etc/ogagent.crt
|
|
||||||
key=/opt/opengnsys/etc/ogagent.key
|
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
|
||||||
import requests
|
import requests
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
|
@ -44,6 +43,7 @@ from .log import logger
|
||||||
|
|
||||||
from .utils import exceptionToMessage
|
from .utils import exceptionToMessage
|
||||||
|
|
||||||
|
VERIFY_CERT = False # Do not check server certificate
|
||||||
TIMEOUT = 5 # Connection timout, in seconds
|
TIMEOUT = 5 # Connection timout, in seconds
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,12 +58,8 @@ class ConnectionError(RESTError):
|
||||||
# Disable warnings log messages
|
# Disable warnings log messages
|
||||||
try:
|
try:
|
||||||
import urllib3 # @UnusedImport
|
import urllib3 # @UnusedImport
|
||||||
requests_log = logging.getLogger ('urllib3')
|
|
||||||
requests_log.setLevel (logging.INFO)
|
|
||||||
except Exception:
|
except Exception:
|
||||||
from requests.packages import urllib3 # @Reimport
|
from requests.packages import urllib3 # @Reimport
|
||||||
requests_log = logging.getLogger ('requests.packages.urllib3')
|
|
||||||
requests_log.setLevel (logging.INFO)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
urllib3.disable_warnings() # @UndefinedVariable
|
urllib3.disable_warnings() # @UndefinedVariable
|
||||||
|
@ -88,7 +84,7 @@ class REST(object):
|
||||||
the deserialized JSON result or raises an exception in case of error
|
the deserialized JSON result or raises an exception in case of error
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, url, ca_file=None, crt_file=None, key_file=None):
|
def __init__(self, url):
|
||||||
"""
|
"""
|
||||||
Initializes the REST helper
|
Initializes the REST helper
|
||||||
url is the full url of the REST API Base, as for example "https://example.com/rest/v1".
|
url is the full url of the REST API Base, as for example "https://example.com/rest/v1".
|
||||||
|
@ -105,26 +101,6 @@ class REST(object):
|
||||||
except Exception:
|
except Exception:
|
||||||
self.newerRequestLib = False # I no version, guess this must be an old requests
|
self.newerRequestLib = False # I no version, guess this must be an old requests
|
||||||
|
|
||||||
if not self.newerRequestLib:
|
|
||||||
logger.debug ('TLS not available: python requests library is old')
|
|
||||||
|
|
||||||
self.use_tls = url.startswith ('https')
|
|
||||||
if self.use_tls:
|
|
||||||
if not ca_file or not crt_file or not key_file:
|
|
||||||
raise Exception ('missing TLS parameters in REST constructor')
|
|
||||||
|
|
||||||
errs = 0
|
|
||||||
for f in [ca_file, crt_file, key_file]:
|
|
||||||
if not os.path.exists (f):
|
|
||||||
logger.error (f'{f}: No such file or directory')
|
|
||||||
errs += 1
|
|
||||||
if errs:
|
|
||||||
raise Exception ('TLS files not found')
|
|
||||||
|
|
||||||
self.ca_file = ca_file
|
|
||||||
self.crt_file = crt_file
|
|
||||||
self.key_file = key_file
|
|
||||||
|
|
||||||
# Disable logging requests messages except for errors, ...
|
# Disable logging requests messages except for errors, ...
|
||||||
logging.getLogger("requests").setLevel(logging.CRITICAL)
|
logging.getLogger("requests").setLevel(logging.CRITICAL)
|
||||||
# Tries to disable all warnings
|
# Tries to disable all warnings
|
||||||
|
@ -155,19 +131,14 @@ class REST(object):
|
||||||
logger.debug('Requesting using GET (no data provided) {}'.format(url))
|
logger.debug('Requesting using GET (no data provided) {}'.format(url))
|
||||||
# Old requests version does not support verify, but it do not checks ssl certificate by default
|
# Old requests version does not support verify, but it do not checks ssl certificate by default
|
||||||
if self.newerRequestLib:
|
if self.newerRequestLib:
|
||||||
if self.use_tls:
|
r = requests.get(url, verify=VERIFY_CERT, timeout=TIMEOUT)
|
||||||
r = requests.get(url, cert=(self.crt_file, self.key_file), verify=self.ca_file, timeout=TIMEOUT)
|
|
||||||
else:
|
|
||||||
r = requests.get(url, timeout=TIMEOUT)
|
|
||||||
else:
|
else:
|
||||||
r = requests.get(url)
|
r = requests.get(url)
|
||||||
else: # POST
|
else: # POST
|
||||||
logger.debug('Requesting using POST {}, data: {}'.format(url, data))
|
logger.debug('Requesting using POST {}, data: {}'.format(url, data))
|
||||||
if self.newerRequestLib:
|
if self.newerRequestLib:
|
||||||
if self.use_tls:
|
r = requests.post(url, data=data, headers={'content-type': 'application/json'},
|
||||||
r = requests.post(url, data=data, headers={'content-type': 'application/json'}, cert=(self.crt_file, self.key_file), verify=self.ca_file, timeout=TIMEOUT)
|
verify=VERIFY_CERT, timeout=TIMEOUT)
|
||||||
else:
|
|
||||||
r = requests.post(url, data=data, headers={'content-type': 'application/json'}, timeout=TIMEOUT)
|
|
||||||
else:
|
else:
|
||||||
r = requests.post(url, data=data, headers={'content-type': 'application/json'})
|
r = requests.post(url, data=data, headers={'content-type': 'application/json'})
|
||||||
|
|
||||||
|
@ -177,9 +148,7 @@ class REST(object):
|
||||||
raise Exception (f'response content-type is not "application/json" but "{ct}"')
|
raise Exception (f'response content-type is not "application/json" but "{ct}"')
|
||||||
r = json.loads(r.content) # Using instead of r.json() to make compatible with old requests lib versions
|
r = json.loads(r.content) # Using instead of r.json() to make compatible with old requests lib versions
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
code = e.response.status_code
|
raise ConnectionError(e)
|
||||||
logger.warning (f'request failed, HTTP code "{code}"')
|
|
||||||
return None
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise ConnectionError(exceptionToMessage(e))
|
raise ConnectionError(exceptionToMessage(e))
|
||||||
|
|
||||||
|
@ -191,13 +160,13 @@ class REST(object):
|
||||||
@param data: if None or omitted, message will be a GET, else it will send a POST
|
@param data: if None or omitted, message will be a GET, else it will send a POST
|
||||||
@param processData: if True, data will be serialized to json before sending, else, data will be sent as "raw"
|
@param processData: if True, data will be serialized to json before sending, else, data will be sent as "raw"
|
||||||
"""
|
"""
|
||||||
#logger.debug('Invoking post message {} with data {}'.format(msg, data))
|
logger.debug('Invoking post message {} with data {}'.format(msg, data))
|
||||||
|
|
||||||
if processData and data is not None:
|
if processData and data is not None:
|
||||||
data = json.dumps(data)
|
data = json.dumps(data)
|
||||||
|
|
||||||
url = self._getUrl(msg)
|
url = self._getUrl(msg)
|
||||||
#logger.debug('Requesting {}'.format(url))
|
logger.debug('Requesting {}'.format(url))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
res = self._request(url, data)
|
res = self._request(url, data)
|
||||||
|
|
|
@ -34,8 +34,6 @@ import logging
|
||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from ..log_format import JsonFormatter
|
|
||||||
|
|
||||||
# Logging levels
|
# Logging levels
|
||||||
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in range(6))
|
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in range(6))
|
||||||
|
|
||||||
|
@ -50,25 +48,15 @@ class LocalLogger(object):
|
||||||
|
|
||||||
for logDir in ('/var/log', os.path.expanduser('~'), tempfile.gettempdir()):
|
for logDir in ('/var/log', os.path.expanduser('~'), tempfile.gettempdir()):
|
||||||
try:
|
try:
|
||||||
fname1 = os.path.join (logDir, 'opengnsys.log')
|
fname = os.path.join(logDir, 'opengnsys.log')
|
||||||
fmt1 = logging.Formatter (fmt='%(levelname)s %(asctime)s (%(threadName)s) (%(funcName)s) %(message)s')
|
logging.basicConfig(
|
||||||
fh1 = logging.FileHandler (filename=fname1, mode='a')
|
filename=fname,
|
||||||
fh1.setFormatter (fmt1)
|
filemode='a',
|
||||||
fh1.setLevel (logging.DEBUG)
|
format='%(levelname)s %(asctime)s (%(threadName)s) (%(funcName)s) %(message)s',
|
||||||
|
level=logging.DEBUG
|
||||||
fname2 = os.path.join (logDir, 'opengnsys.json.log')
|
)
|
||||||
fmt2 = JsonFormatter ({"timestamp": "asctime", "severity": "levelname", "threadName": "threadName", "function": "funcName", "message": "message"}, time_format='%Y-%m-%d %H:%M:%S', msec_format='')
|
|
||||||
fh2 = logging.FileHandler (filename=fname2, mode='a')
|
|
||||||
fh2.setFormatter (fmt2)
|
|
||||||
fh2.setLevel (logging.DEBUG)
|
|
||||||
|
|
||||||
self.logger = logging.getLogger('opengnsys')
|
self.logger = logging.getLogger('opengnsys')
|
||||||
self.logger.setLevel (logging.DEBUG)
|
os.chmod(fname, 0o0600)
|
||||||
self.logger.addHandler (fh1)
|
|
||||||
self.logger.addHandler (fh2)
|
|
||||||
|
|
||||||
os.chmod (fname1, 0o0600)
|
|
||||||
os.chmod (fname2, 0o0600)
|
|
||||||
return
|
return
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
import json
|
|
||||||
import logging
|
|
||||||
|
|
||||||
class JsonFormatter(logging.Formatter):
|
|
||||||
"""
|
|
||||||
Formatter that outputs JSON strings after parsing the LogRecord.
|
|
||||||
|
|
||||||
@param dict fmt_dict: Key: logging format attribute pairs. Defaults to {"message": "message"}.
|
|
||||||
@param str time_format: time.strftime() format string. Default: "%Y-%m-%dT%H:%M:%S"
|
|
||||||
@param str msec_format: Microsecond formatting. Appended at the end. Default: "%s.%03dZ"
|
|
||||||
"""
|
|
||||||
def __init__(self, fmt_dict: dict = None, time_format: str = "%Y-%m-%dT%H:%M:%S", msec_format: str = "%s.%03dZ"):
|
|
||||||
self.fmt_dict = fmt_dict if fmt_dict is not None else {"message": "message"}
|
|
||||||
self.default_time_format = time_format
|
|
||||||
self.default_msec_format = msec_format
|
|
||||||
self.datefmt = None
|
|
||||||
|
|
||||||
def usesTime(self) -> bool:
|
|
||||||
"""
|
|
||||||
Overwritten to look for the attribute in the format dict values instead of the fmt string.
|
|
||||||
"""
|
|
||||||
return "asctime" in self.fmt_dict.values()
|
|
||||||
|
|
||||||
def formatMessage(self, record) -> dict:
|
|
||||||
"""
|
|
||||||
Overwritten to return a dictionary of the relevant LogRecord attributes instead of a string.
|
|
||||||
KeyError is raised if an unknown attribute is provided in the fmt_dict.
|
|
||||||
"""
|
|
||||||
return {fmt_key: record.__dict__[fmt_val] for fmt_key, fmt_val in self.fmt_dict.items()}
|
|
||||||
|
|
||||||
def format(self, record) -> str:
|
|
||||||
"""
|
|
||||||
Mostly the same as the parent's class method, the difference being that a dict is manipulated and dumped as JSON
|
|
||||||
instead of a string.
|
|
||||||
"""
|
|
||||||
record.message = record.getMessage()
|
|
||||||
|
|
||||||
if self.usesTime():
|
|
||||||
record.asctime = self.formatTime(record, self.datefmt)
|
|
||||||
|
|
||||||
message_dict = self.formatMessage(record)
|
|
||||||
|
|
||||||
if record.exc_info:
|
|
||||||
# Cache the traceback text to avoid converting it multiple times
|
|
||||||
# (it's constant anyway)
|
|
||||||
if not record.exc_text:
|
|
||||||
record.exc_text = self.formatException(record.exc_info)
|
|
||||||
|
|
||||||
if record.exc_text:
|
|
||||||
message_dict["exc_info"] = record.exc_text
|
|
||||||
|
|
||||||
if record.stack_info:
|
|
||||||
message_dict["stack_info"] = self.formatStack(record.stack_info)
|
|
||||||
|
|
||||||
return json.dumps(message_dict, default=str)
|
|
|
@ -131,13 +131,10 @@ class OpenGnSysWorker(ServerWorker):
|
||||||
# Ensure cfg has required configuration variables or an exception will be thrown
|
# Ensure cfg has required configuration variables or an exception will be thrown
|
||||||
try:
|
try:
|
||||||
url = self.service.config.get(self.name, 'remote')
|
url = self.service.config.get(self.name, 'remote')
|
||||||
ca_file = self.service.config.get(self.name, 'ca')
|
|
||||||
crt_file = self.service.config.get(self.name, 'crt')
|
|
||||||
key_file = self.service.config.get(self.name, 'key')
|
|
||||||
except NoOptionError as e:
|
except NoOptionError as e:
|
||||||
logger.error("Configuration error: {}".format(e))
|
logger.error("Configuration error: {}".format(e))
|
||||||
raise e
|
raise e
|
||||||
self.REST = REST (url, ca_file=ca_file, crt_file=crt_file, key_file=key_file)
|
self.REST = REST(url)
|
||||||
# Execution level ('full' by default)
|
# Execution level ('full' by default)
|
||||||
try:
|
try:
|
||||||
self.exec_level = self.service.config.get(self.name, 'level')
|
self.exec_level = self.service.config.get(self.name, 'level')
|
||||||
|
@ -177,7 +174,7 @@ class OpenGnSysWorker(ServerWorker):
|
||||||
logger.warn (str (e))
|
logger.warn (str (e))
|
||||||
# Trying to initialize on alternative server, if defined
|
# Trying to initialize on alternative server, if defined
|
||||||
# (used in "exam mode" from the University of Seville)
|
# (used in "exam mode" from the University of Seville)
|
||||||
self.REST = REST(self.service.config.get(self.name, 'altremote'), ca_file=ca_file, crt_file=crt_file, key_file=key_file)
|
self.REST = REST(self.service.config.get(self.name, 'altremote'))
|
||||||
self.REST.sendMessage('ogagent/started', {'mac': self.interface.mac, 'ip': self.interface.ip,
|
self.REST.sendMessage('ogagent/started', {'mac': self.interface.mac, 'ip': self.interface.ip,
|
||||||
'secret': self.random, 'ostype': operations.os_type,
|
'secret': self.random, 'ostype': operations.os_type,
|
||||||
'osversion': operations.os_version, 'alt_url': True,
|
'osversion': operations.os_version, 'alt_url': True,
|
||||||
|
|
|
@ -33,15 +33,14 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
|
#import threading
|
||||||
|
#import time
|
||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
import string
|
|
||||||
import random
|
|
||||||
import subprocess
|
import subprocess
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from urllib.parse import unquote
|
from urllib.parse import unquote
|
||||||
|
|
||||||
from opengnsys import VERSION
|
|
||||||
from opengnsys.log import logger
|
from opengnsys.log import logger
|
||||||
from opengnsys.workers import ogLiveWorker
|
from opengnsys.workers import ogLiveWorker
|
||||||
|
|
||||||
|
@ -51,41 +50,22 @@ def check_secret (fnc):
|
||||||
Decorator to check for received secret key and raise exception if it isn't valid.
|
Decorator to check for received secret key and raise exception if it isn't valid.
|
||||||
"""
|
"""
|
||||||
def wrapper (*args, **kwargs):
|
def wrapper (*args, **kwargs):
|
||||||
try:
|
|
||||||
this, path, get_params, post_params, server = args
|
|
||||||
|
|
||||||
if not server: ## this happens on startup, eg. onActivation->autoexecCliente->ejecutaArchivo->popup->check_secret
|
|
||||||
return fnc (*args, **kwargs)
|
return fnc (*args, **kwargs)
|
||||||
|
#try:
|
||||||
if this.random == server.headers['Authorization']:
|
# this, path, get_params, post_params, server = args
|
||||||
return fnc (*args, **kwargs)
|
# # Accept "status" operation with no arguments or any function with Authorization header
|
||||||
else:
|
# if fnc.__name__ == 'process_status' and not get_params:
|
||||||
raise Exception ('Unauthorized operation')
|
# return fnc (*args, **kwargs)
|
||||||
except Exception as e:
|
# elif this.random == server.headers['Authorization']:
|
||||||
logger.error (str (e))
|
# return fnc (*args, **kwargs)
|
||||||
raise Exception (e)
|
# else:
|
||||||
|
# raise Exception ('Unauthorized operation')
|
||||||
|
#except Exception as e:
|
||||||
|
# logger.error (str (e))
|
||||||
|
# raise Exception (e)
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
# Check if operation is permitted
|
|
||||||
def execution_level(level):
|
|
||||||
def check_permitted(fnc):
|
|
||||||
def wrapper(*args, **kwargs):
|
|
||||||
levels = ['status', 'halt', 'full']
|
|
||||||
this = args[0]
|
|
||||||
try:
|
|
||||||
if levels.index(level) <= levels.index(this.exec_level):
|
|
||||||
return fnc(*args, **kwargs)
|
|
||||||
else:
|
|
||||||
raise Exception('Unauthorized operation')
|
|
||||||
except Exception as e:
|
|
||||||
logger.debug (str(e))
|
|
||||||
raise Exception(e)
|
|
||||||
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
return check_permitted
|
|
||||||
|
|
||||||
class ogAdmClientWorker (ogLiveWorker):
|
class ogAdmClientWorker (ogLiveWorker):
|
||||||
name = 'ogAdmClient' # Module name
|
name = 'ogAdmClient' # Module name
|
||||||
REST = None # REST object
|
REST = None # REST object
|
||||||
|
@ -95,9 +75,63 @@ class ogAdmClientWorker (ogLiveWorker):
|
||||||
Sends OGAgent stopping notification to OpenGnsys server
|
Sends OGAgent stopping notification to OpenGnsys server
|
||||||
"""
|
"""
|
||||||
logger.debug ('onDeactivation')
|
logger.debug ('onDeactivation')
|
||||||
self.REST.sendMessage ('ogagent/stopped', {'mac': self.mac, 'ip': self.IPlocal, 'idcentro': self.idcentro, 'idaula': self.idaula,
|
self.REST.sendMessage ('ogAdmClient/stopped', {'mac': self.mac, 'ip': self.IPlocal, 'idcentro': self.idcentro, 'idaula': self.idaula,
|
||||||
'idordenador': self.idordenador, 'nombreordenador': self.nombreordenador})
|
'idordenador': self.idordenador, 'nombreordenador': self.nombreordenador})
|
||||||
|
|
||||||
|
#def processClientMessage (self, message, data):
|
||||||
|
# logger.debug ('Got OpenGnsys message from client: {}, data {}'.format (message, data))
|
||||||
|
|
||||||
|
#def onLogin (self, data):
|
||||||
|
# logger.warning ('in onLogin, should not happen')
|
||||||
|
|
||||||
|
#def onLogout (self, user):
|
||||||
|
# logger.warning ('in onLogout, should not happen')
|
||||||
|
|
||||||
|
#@check_secret
|
||||||
|
#def process_reboot (self, path, get_params, post_params, server):
|
||||||
|
# """
|
||||||
|
# Launches a system reboot operation
|
||||||
|
# :param path:
|
||||||
|
# :param get_params:
|
||||||
|
# :param post_params:
|
||||||
|
# :param server: authorization header
|
||||||
|
# :return: JSON object {"op": "launched"}
|
||||||
|
# """
|
||||||
|
# logger.debug ('Received reboot operation')
|
||||||
|
|
||||||
|
# # Rebooting thread
|
||||||
|
# def rebt():
|
||||||
|
# operations.reboot()
|
||||||
|
# threading.Thread (target=rebt).start()
|
||||||
|
# return {'op': 'launched'}
|
||||||
|
|
||||||
|
#@check_secret
|
||||||
|
#def process_poweroff (self, path, get_params, post_params, server):
|
||||||
|
# """
|
||||||
|
# Launches a system power off operation
|
||||||
|
# :param path:
|
||||||
|
# :param get_params:
|
||||||
|
# :param post_params:
|
||||||
|
# :param server: authorization header
|
||||||
|
# :return: JSON object {"op": "launched"}
|
||||||
|
# """
|
||||||
|
# logger.debug ('Received poweroff operation')
|
||||||
|
|
||||||
|
# # Powering off thread
|
||||||
|
# def pwoff():
|
||||||
|
# time.sleep (2)
|
||||||
|
# operations.poweroff()
|
||||||
|
# threading.Thread (target=pwoff).start()
|
||||||
|
# return {'op': 'launched'}
|
||||||
|
|
||||||
|
## process_* are invoked from opengnsys/httpserver.py:99 "data = module.processServerMessage (path, get_params, post_params, self)" (via opengnsys/workers/server_worker.py)
|
||||||
|
## process_client_* are invoked from opengnsys/service.py:123 "v.processClientMessage (message, json.loads (data))" (via opengnsys/workers/server_worker.py)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -168,7 +202,7 @@ class ogAdmClientWorker (ogLiveWorker):
|
||||||
logger.warning ('Ha ocurrido algún problema en el proceso de inclusión del cliente')
|
logger.warning ('Ha ocurrido algún problema en el proceso de inclusión del cliente')
|
||||||
logger.error ('LeeConfiguracion() failed')
|
logger.error ('LeeConfiguracion() failed')
|
||||||
return False
|
return False
|
||||||
res = self.enviaMensajeServidor ('InclusionCliente', { 'cfg': self.cfg2obj (cfg), 'secret': self.random, 'agent_version': VERSION })
|
res = self.enviaMensajeServidor ('InclusionCliente', { 'cfg': self.cfg2obj (cfg) })
|
||||||
logger.debug ('res ({})'.format (res))
|
logger.debug ('res ({})'.format (res))
|
||||||
|
|
||||||
## RESPUESTA_InclusionCliente
|
## RESPUESTA_InclusionCliente
|
||||||
|
@ -274,9 +308,6 @@ class ogAdmClientWorker (ogLiveWorker):
|
||||||
|
|
||||||
def onActivation (self):
|
def onActivation (self):
|
||||||
super().onActivation()
|
super().onActivation()
|
||||||
self.exec_level = 'full'
|
|
||||||
self.random = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(32))
|
|
||||||
|
|
||||||
logger.info ('Inicio de sesion')
|
logger.info ('Inicio de sesion')
|
||||||
logger.info ('Abriendo sesión en el servidor de Administración')
|
logger.info ('Abriendo sesión en el servidor de Administración')
|
||||||
if (not self.inclusionCliente()):
|
if (not self.inclusionCliente()):
|
||||||
|
@ -303,10 +334,35 @@ class ogAdmClientWorker (ogLiveWorker):
|
||||||
|
|
||||||
logger.info ('onActivation ok')
|
logger.info ('onActivation ok')
|
||||||
|
|
||||||
|
@check_secret
|
||||||
|
def process_status (self, path, get_params, post_params, server):
|
||||||
|
logger.debug ('in process_status, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
|
full_config = 'full-config' in post_params and post_params['full-config']
|
||||||
|
thr_status = {}
|
||||||
|
for k in self.thread_list:
|
||||||
|
thr_status[k] = {
|
||||||
|
'running': self.thread_list[k]['running'],
|
||||||
|
'result': self.thread_list[k]['result'],
|
||||||
|
}
|
||||||
|
ret = {
|
||||||
|
'nfn': 'RESPUESTA_status',
|
||||||
|
'mac': self.mac,
|
||||||
|
'st': 'OGL',
|
||||||
|
'ip': self.IPlocal,
|
||||||
|
'threads': thr_status,
|
||||||
|
}
|
||||||
|
if full_config:
|
||||||
|
cfg = self.LeeConfiguracion()
|
||||||
|
ret['cfg'] = self.cfg2obj (cfg)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
@check_secret
|
||||||
|
def process_popup (self, path, get_params, post_params, server):
|
||||||
|
logger.debug ('in process_popup, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
|
logger.debug ('type(post_params) "{}"'.format (type (post_params)))
|
||||||
|
## in process_popup, should not happen, path "[]" get_params "{}" post_params "{'title': 'mi titulo', 'message': 'mi mensaje'}" server "<opengnsys.httpserver.HTTPServerHandler object at 0x7fa788cb8fa0>"
|
||||||
|
## type(post_params) "<class 'dict'>"
|
||||||
|
return {'debug':'test'}
|
||||||
|
|
||||||
def do_CrearImagen (self, post_params):
|
def do_CrearImagen (self, post_params):
|
||||||
for k in ['dsk', 'par', 'cpt', 'idi', 'nci', 'ipr', 'nfn', 'ids']:
|
for k in ['dsk', 'par', 'cpt', 'idi', 'nci', 'ipr', 'nfn', 'ids']:
|
||||||
|
@ -699,54 +755,16 @@ class ogAdmClientWorker (ogLiveWorker):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@execution_level('status')
|
|
||||||
def process_status (self, path, get_params, post_params, server):
|
|
||||||
logger.debug ('in process_status, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
|
||||||
full_config = 'full-config' in post_params and post_params['full-config']
|
|
||||||
thr_status = {}
|
|
||||||
for k in self.thread_list:
|
|
||||||
thr_status[k] = {
|
|
||||||
'running': self.thread_list[k]['running'],
|
|
||||||
'result': self.thread_list[k]['result'],
|
|
||||||
}
|
|
||||||
ret = {
|
|
||||||
'nfn': 'RESPUESTA_status',
|
|
||||||
'mac': self.mac,
|
|
||||||
'st': 'OGL',
|
|
||||||
'ip': self.IPlocal,
|
|
||||||
'threads': thr_status,
|
|
||||||
}
|
|
||||||
if full_config:
|
|
||||||
cfg = self.LeeConfiguracion()
|
|
||||||
ret['cfg'] = self.cfg2obj (cfg)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
@check_secret
|
|
||||||
def process_popup (self, path, get_params, post_params, server):
|
|
||||||
logger.debug ('in process_popup, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
|
||||||
logger.debug ('type(post_params) "{}"'.format (type (post_params)))
|
|
||||||
## in process_popup, should not happen, path "[]" get_params "{}" post_params "{'title': 'mi titulo', 'message': 'mi mensaje'}" server "<opengnsys.httpserver.HTTPServerHandler object at 0x7fa788cb8fa0>"
|
|
||||||
## type(post_params) "<class 'dict'>"
|
|
||||||
return {'debug':'test'}
|
|
||||||
|
|
||||||
@execution_level('full')
|
|
||||||
@check_secret
|
|
||||||
def process_Actualizar (self, path, get_params, post_params, server):
|
def process_Actualizar (self, path, get_params, post_params, server):
|
||||||
logger.debug ('in process_Actualizar, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
logger.debug ('in process_Actualizar, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
return self._long_running_job ('Actualizar', self.do_Actualizar, args=(post_params,))
|
return self._long_running_job ('Actualizar', self.do_Actualizar, args=(post_params,))
|
||||||
|
|
||||||
@execution_level('full')
|
|
||||||
@check_secret
|
|
||||||
def process_Purgar (self, path, get_params, post_params, server):
|
def process_Purgar (self, path, get_params, post_params, server):
|
||||||
logger.debug ('in process_Purgar, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
logger.debug ('in process_Purgar, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
os.kill (os.getpid(), signal.SIGTERM)
|
os.kill (os.getpid(), signal.SIGTERM)
|
||||||
return {}
|
return {}
|
||||||
#exit (0) ## ogAdmClient.c:905
|
#exit (0) ## ogAdmClient.c:905
|
||||||
|
|
||||||
@execution_level('full')
|
|
||||||
@check_secret
|
|
||||||
def process_Comando (self, path, get_params, post_params, server):
|
def process_Comando (self, path, get_params, post_params, server):
|
||||||
logger.debug ('in process_Comando, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
logger.debug ('in process_Comando, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
return self._long_running_job ('Comando', self.do_Comando, args=(post_params,))
|
return self._long_running_job ('Comando', self.do_Comando, args=(post_params,))
|
||||||
|
@ -755,14 +773,10 @@ class ogAdmClientWorker (ogLiveWorker):
|
||||||
logger.debug ('in process_Sondeo, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
logger.debug ('in process_Sondeo, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
return {} ## ogAdmClient.c:920
|
return {} ## ogAdmClient.c:920
|
||||||
|
|
||||||
@execution_level('full')
|
|
||||||
@check_secret
|
|
||||||
def process_ConsolaRemota (self, path, get_params, post_params, server):
|
def process_ConsolaRemota (self, path, get_params, post_params, server):
|
||||||
logger.debug ('in process_ConsolaRemota, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
logger.debug ('in process_ConsolaRemota, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
return self._long_running_job ('ConsolaRemota', self.do_ConsolaRemota, args=(post_params,))
|
return self._long_running_job ('ConsolaRemota', self.do_ConsolaRemota, args=(post_params,))
|
||||||
|
|
||||||
@execution_level('full')
|
|
||||||
@check_secret
|
|
||||||
def process_Arrancar (self, path, get_params, post_params, server):
|
def process_Arrancar (self, path, get_params, post_params, server):
|
||||||
logger.debug ('in process_Arrancar, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
logger.debug ('in process_Arrancar, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
|
|
||||||
|
@ -779,38 +793,26 @@ class ogAdmClientWorker (ogLiveWorker):
|
||||||
}
|
}
|
||||||
return self.respuestaEjecucionComando (cmd, 0, ids)
|
return self.respuestaEjecucionComando (cmd, 0, ids)
|
||||||
|
|
||||||
@execution_level('halt')
|
|
||||||
@check_secret
|
|
||||||
def process_Apagar (self, path, get_params, post_params, server):
|
def process_Apagar (self, path, get_params, post_params, server):
|
||||||
logger.debug ('in process_Apagar, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
logger.debug ('in process_Apagar, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
return self._long_running_job ('Apagar', self.do_Apagar, args=(post_params,))
|
return self._long_running_job ('Apagar', self.do_Apagar, args=(post_params,))
|
||||||
|
|
||||||
@execution_level('halt')
|
|
||||||
@check_secret
|
|
||||||
def process_Reiniciar (self, path, get_params, post_params, server):
|
def process_Reiniciar (self, path, get_params, post_params, server):
|
||||||
logger.debug ('in process_Reiniciar, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
logger.debug ('in process_Reiniciar, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
return self._long_running_job ('Reiniciar', self.do_Reiniciar, args=(post_params,))
|
return self._long_running_job ('Reiniciar', self.do_Reiniciar, args=(post_params,))
|
||||||
|
|
||||||
@execution_level('full')
|
|
||||||
@check_secret
|
|
||||||
def process_IniciarSesion (self, path, get_params, post_params, server):
|
def process_IniciarSesion (self, path, get_params, post_params, server):
|
||||||
logger.debug ('in process_IniciarSesion, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
logger.debug ('in process_IniciarSesion, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
return self._long_running_job ('IniciarSesion', self.do_IniciarSesion, args=(post_params,))
|
return self._long_running_job ('IniciarSesion', self.do_IniciarSesion, args=(post_params,))
|
||||||
|
|
||||||
@execution_level('full')
|
|
||||||
@check_secret
|
|
||||||
def process_EjecutarScript (self, path, get_params, post_params, server):
|
def process_EjecutarScript (self, path, get_params, post_params, server):
|
||||||
logger.debug ('in process_EjecutarScript, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
logger.debug ('in process_EjecutarScript, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
return self._long_running_job ('EjecutarScript', self.do_EjecutarScript, args=(post_params,))
|
return self._long_running_job ('EjecutarScript', self.do_EjecutarScript, args=(post_params,))
|
||||||
|
|
||||||
@execution_level('full')
|
|
||||||
@check_secret
|
|
||||||
def process_EjecutaComandosPendientes (self, path, get_params, post_params, server):
|
def process_EjecutaComandosPendientes (self, path, get_params, post_params, server):
|
||||||
logger.debug ('in process_EjecutaComandosPendientes, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
logger.debug ('in process_EjecutaComandosPendientes, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
return {'true':'true'} ## ogAdmClient.c:2138
|
return {'true':'true'} ## ogAdmClient.c:2138
|
||||||
|
|
||||||
@execution_level('full')
|
|
||||||
@check_secret
|
|
||||||
def process_CrearImagen (self, path, get_params, post_params, server):
|
def process_CrearImagen (self, path, get_params, post_params, server):
|
||||||
logger.debug ('in process_CrearImagen, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
logger.debug ('in process_CrearImagen, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
logger.debug ('type(post_params) "{}"'.format (type (post_params)))
|
logger.debug ('type(post_params) "{}"'.format (type (post_params)))
|
||||||
|
@ -826,8 +828,6 @@ class ogAdmClientWorker (ogLiveWorker):
|
||||||
# logger.warning ('this method has been removed')
|
# logger.warning ('this method has been removed')
|
||||||
# raise Exception ({ '_httpcode': 404, '_msg': 'This method has been removed' })
|
# raise Exception ({ '_httpcode': 404, '_msg': 'This method has been removed' })
|
||||||
|
|
||||||
@execution_level('full')
|
|
||||||
@check_secret
|
|
||||||
def process_RestaurarImagen (self, path, get_params, post_params, server):
|
def process_RestaurarImagen (self, path, get_params, post_params, server):
|
||||||
logger.debug ('in process_RestaurarImagen, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
logger.debug ('in process_RestaurarImagen, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
logger.debug ('type(post_params) "{}"'.format (type (post_params)))
|
logger.debug ('type(post_params) "{}"'.format (type (post_params)))
|
||||||
|
@ -844,27 +844,18 @@ class ogAdmClientWorker (ogLiveWorker):
|
||||||
# logger.warning ('this method has been removed')
|
# logger.warning ('this method has been removed')
|
||||||
# raise Exception ({ '_httpcode': 404, '_msg': 'This method has been removed' })
|
# raise Exception ({ '_httpcode': 404, '_msg': 'This method has been removed' })
|
||||||
|
|
||||||
## una partición + cache en disco de 30 Gb:
|
|
||||||
@execution_level('full')
|
|
||||||
@check_secret
|
|
||||||
def process_Configurar (self, path, get_params, post_params, server):
|
def process_Configurar (self, path, get_params, post_params, server):
|
||||||
logger.debug ('in process_Configurar, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
logger.debug ('in process_Configurar, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
return self._long_running_job ('Configurar', self.do_Configurar, args=(post_params,))
|
return self._long_running_job ('Configurar', self.do_Configurar, args=(post_params,))
|
||||||
|
|
||||||
@execution_level('full')
|
|
||||||
@check_secret
|
|
||||||
def process_InventarioHardware (self, path, get_params, post_params, server):
|
def process_InventarioHardware (self, path, get_params, post_params, server):
|
||||||
logger.debug ('in process_InventarioHardware, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
logger.debug ('in process_InventarioHardware, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
return self._long_running_job ('InventarioHardware', self.do_InventarioHardware, args=(post_params,))
|
return self._long_running_job ('InventarioHardware', self.do_InventarioHardware, args=(post_params,))
|
||||||
|
|
||||||
@execution_level('full')
|
|
||||||
@check_secret
|
|
||||||
def process_InventarioSoftware (self, path, get_params, post_params, server):
|
def process_InventarioSoftware (self, path, get_params, post_params, server):
|
||||||
logger.debug ('in process_InventarioSoftware, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
logger.debug ('in process_InventarioSoftware, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
return self._long_running_job ('InventarioSoftware', self.do_InventarioSoftware, args=(post_params,))
|
return self._long_running_job ('InventarioSoftware', self.do_InventarioSoftware, args=(post_params,))
|
||||||
|
|
||||||
@execution_level('full')
|
|
||||||
@check_secret
|
|
||||||
def process_KillJob (self, path, get_params, post_params, server):
|
def process_KillJob (self, path, get_params, post_params, server):
|
||||||
logger.debug ('in process_KillJob, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
logger.debug ('in process_KillJob, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||||
jid = post_params['job_id']
|
jid = post_params['job_id']
|
||||||
|
|
|
@ -36,8 +36,6 @@ import logging
|
||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from ..log_format import JsonFormatter
|
|
||||||
|
|
||||||
# Valid logging levels, from UDS Broker (uds.core.utils.log)
|
# Valid logging levels, from UDS Broker (uds.core.utils.log)
|
||||||
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in range(6))
|
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in range(6))
|
||||||
|
|
||||||
|
@ -46,24 +44,13 @@ class LocalLogger(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# tempdir is different for "user application" and "service"
|
# tempdir is different for "user application" and "service"
|
||||||
# service wil get c:\windows\temp, while user will get c:\users\XXX\appdata\local\temp
|
# service wil get c:\windows\temp, while user will get c:\users\XXX\appdata\local\temp
|
||||||
|
logging.basicConfig(
|
||||||
fname1 = os.path.join (tempfile.gettempdir(), 'opengnsys.log')
|
filename=os.path.join(tempfile.gettempdir(), 'opengnsys.log'),
|
||||||
fmt1 = logging.Formatter (fmt='%(levelname)s %(asctime)s (%(threadName)s) (%(funcName)s) %(message)s')
|
filemode='a',
|
||||||
fh1 = logging.FileHandler (filename=fname1, mode='a')
|
format='%(levelname)s %(asctime)s (%(threadName)s) (%(funcName)s) %(message)s',
|
||||||
fh1.setFormatter (fmt1)
|
level=logging.DEBUG
|
||||||
fh1.setLevel (logging.DEBUG)
|
)
|
||||||
|
|
||||||
fname2 = os.path.join (tempfile.gettempdir(), 'opengnsys.json.log')
|
|
||||||
fmt2 = JsonFormatter ({"timestamp": "asctime", "severity": "levelname", "threadName": "threadName", "function": "funcName", "message": "message"}, time_format='%Y-%m-%d %H:%M:%S', msec_format='')
|
|
||||||
fh2 = logging.FileHandler (filename=fname2, mode='a')
|
|
||||||
fh2.setFormatter (fmt2)
|
|
||||||
fh2.setLevel (logging.DEBUG)
|
|
||||||
|
|
||||||
self.logger = logging.getLogger('opengnsys')
|
self.logger = logging.getLogger('opengnsys')
|
||||||
self.logger.setLevel (logging.DEBUG)
|
|
||||||
self.logger.addHandler (fh1)
|
|
||||||
self.logger.addHandler (fh2)
|
|
||||||
|
|
||||||
self.serviceLogger = False
|
self.serviceLogger = False
|
||||||
|
|
||||||
def log(self, level, message):
|
def log(self, level, message):
|
||||||
|
|
|
@ -198,7 +198,7 @@ class ogLiveWorker(ServerWorker):
|
||||||
progress = None
|
progress = None
|
||||||
for i in ary:
|
for i in ary:
|
||||||
if m := re.search (r'^\[([0-9]+)\]', i): ## look for strings like '[10]', '[60]'
|
if m := re.search (r'^\[([0-9]+)\]', i): ## look for strings like '[10]', '[60]'
|
||||||
#logger.debug (f"matched regex, m.groups ({m.groups()})")
|
logger.debug (f"matched regex, m.groups ({m.groups()})")
|
||||||
progress = float (m.groups()[0]) / 100
|
progress = float (m.groups()[0]) / 100
|
||||||
return progress
|
return progress
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ class ogLiveWorker(ServerWorker):
|
||||||
for k in self.thread_list:
|
for k in self.thread_list:
|
||||||
elem = self.thread_list[k]
|
elem = self.thread_list[k]
|
||||||
if 'thread' not in elem: continue
|
if 'thread' not in elem: continue
|
||||||
#logger.debug (f'considering thread ({k})')
|
logger.debug (f'considering thread ({k})')
|
||||||
|
|
||||||
if self.pid_q:
|
if self.pid_q:
|
||||||
if not self.pid_q.empty():
|
if not self.pid_q.empty():
|
||||||
|
@ -240,20 +240,11 @@ class ogLiveWorker(ServerWorker):
|
||||||
time.sleep (1)
|
time.sleep (1)
|
||||||
n += 1
|
n += 1
|
||||||
if not n % 10:
|
if not n % 10:
|
||||||
alive_threads = []
|
|
||||||
for k in self.thread_list:
|
|
||||||
elem = self.thread_list[k]
|
|
||||||
if 'thread' not in elem: continue
|
|
||||||
alive_threads.append (k)
|
|
||||||
if alive_threads:
|
|
||||||
s = ','.join (alive_threads)
|
|
||||||
logger.debug (f'alive threads: {s}')
|
|
||||||
|
|
||||||
body = {
|
body = {
|
||||||
'iph': self.IPlocal,
|
'iph': self.IPlocal,
|
||||||
'timestamp': int (time.time()),
|
'timestamp': int (time.time()),
|
||||||
}
|
}
|
||||||
#logger.debug (f'about to send ping ({body})')
|
logger.debug (f'about to send ping ({body})')
|
||||||
self.REST.sendMessage ('clients/status/webhook', body)
|
self.REST.sendMessage ('clients/status/webhook', body)
|
||||||
|
|
||||||
def interfaceAdmin (self, method, parametros=[]):
|
def interfaceAdmin (self, method, parametros=[]):
|
||||||
|
@ -286,8 +277,7 @@ class ogLiveWorker(ServerWorker):
|
||||||
self.pid_q.put (p.pid)
|
self.pid_q.put (p.pid)
|
||||||
else:
|
else:
|
||||||
## esto sucede por ejemplo cuando arranca el agente, que estamos en interfaceAdmin() en el mismo hilo, sin _long_running_job ni hilo separado
|
## esto sucede por ejemplo cuando arranca el agente, que estamos en interfaceAdmin() en el mismo hilo, sin _long_running_job ni hilo separado
|
||||||
#logger.debug ('no queue--not writing any PID to it')
|
logger.debug ('no queue--not writing any PID to it')
|
||||||
pass
|
|
||||||
|
|
||||||
sout = serr = ''
|
sout = serr = ''
|
||||||
while p.poll() is None:
|
while p.poll() is None:
|
||||||
|
@ -303,12 +293,12 @@ class ogLiveWorker(ServerWorker):
|
||||||
serr = serr.strip()
|
serr = serr.strip()
|
||||||
|
|
||||||
## DEBUG
|
## DEBUG
|
||||||
logger.debug (f'stdout follows:')
|
logger.info (f'stdout follows:')
|
||||||
for l in sout.splitlines():
|
for l in sout.splitlines():
|
||||||
logger.debug (f' {l}')
|
logger.info (f' {l}')
|
||||||
#logger.debug (f'stderr follows:')
|
logger.info (f'stderr follows:')
|
||||||
#for l in serr.splitlines():
|
for l in serr.splitlines():
|
||||||
# logger.debug (f' {l}')
|
logger.info (f' {l}')
|
||||||
## /DEBUG
|
## /DEBUG
|
||||||
if 0 != p.returncode:
|
if 0 != p.returncode:
|
||||||
cmd_txt = ' '.join (proc)
|
cmd_txt = ' '.join (proc)
|
||||||
|
@ -347,7 +337,9 @@ class ogLiveWorker(ServerWorker):
|
||||||
res = self.REST.sendMessage ('/'.join ([self.name, path]), obj)
|
res = self.REST.sendMessage ('/'.join ([self.name, path]), obj)
|
||||||
|
|
||||||
if (type (res) is not dict):
|
if (type (res) is not dict):
|
||||||
logger.error (f'response is not a dict ({res})')
|
#logger.error ('No se ha podido establecer conexión con el Servidor de Administración') ## Error de conexión con el servidor
|
||||||
|
logger.debug (f'res ({res})')
|
||||||
|
logger.error ('Error al enviar trama ***send() fallo')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
@ -374,7 +366,9 @@ class ogLiveWorker(ServerWorker):
|
||||||
p = subprocess.Popen (['/usr/bin/browser', '-qws', url])
|
p = subprocess.Popen (['/usr/bin/browser', '-qws', url])
|
||||||
try:
|
try:
|
||||||
p.wait (2) ## if the process dies before 2 seconds...
|
p.wait (2) ## if the process dies before 2 seconds...
|
||||||
logger.error ('Error al ejecutar browser, return code "{}"'.format (p.returncode))
|
logger.error ('Error al ejecutar la llamada a la interface de administración')
|
||||||
|
logger.error ('Error en la creación del proceso hijo')
|
||||||
|
logger.error ('return code "{}"'.format (p.returncode))
|
||||||
return False
|
return False
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
pass
|
pass
|
||||||
|
@ -394,7 +388,7 @@ class ogLiveWorker(ServerWorker):
|
||||||
logger.error (e)
|
logger.error (e)
|
||||||
logger.error ('No se ha podido recuperar la dirección IP del cliente')
|
logger.error ('No se ha podido recuperar la dirección IP del cliente')
|
||||||
return None
|
return None
|
||||||
#logger.debug ('parametroscfg ({})'.format (parametroscfg))
|
logger.debug ('parametroscfg ({})'.format (parametroscfg))
|
||||||
return parametroscfg
|
return parametroscfg
|
||||||
|
|
||||||
def cfg2obj (self, cfg):
|
def cfg2obj (self, cfg):
|
||||||
|
@ -449,16 +443,13 @@ class ogLiveWorker(ServerWorker):
|
||||||
self.urlMenu = self.service.config.get (self.name, 'urlMenu')
|
self.urlMenu = self.service.config.get (self.name, 'urlMenu')
|
||||||
self.urlMsg = self.service.config.get (self.name, 'urlMsg')
|
self.urlMsg = self.service.config.get (self.name, 'urlMsg')
|
||||||
|
|
||||||
ca_file = self.service.config.get (self.name, 'ca')
|
|
||||||
crt_file = self.service.config.get (self.name, 'crt')
|
|
||||||
key_file = self.service.config.get (self.name, 'key')
|
|
||||||
url = url.format (ogcore_scheme, ogcore_ip_port)
|
url = url.format (ogcore_scheme, ogcore_ip_port)
|
||||||
self.urlMenu = self.urlMenu.format (urlmenu_scheme, urlmenu_ip_port)
|
self.urlMenu = self.urlMenu.format (urlmenu_scheme, urlmenu_ip_port)
|
||||||
except NoOptionError as e:
|
except NoOptionError as e:
|
||||||
logger.error ("Configuration error: {}".format (e))
|
logger.error ("Configuration error: {}".format (e))
|
||||||
raise e
|
raise e
|
||||||
logger.setLevel (loglevel)
|
logger.setLevel (loglevel)
|
||||||
self.REST = REST (url, ca_file=ca_file, crt_file=crt_file, key_file=key_file)
|
self.REST = REST (url)
|
||||||
|
|
||||||
if not self.tomaIPlocal():
|
if not self.tomaIPlocal():
|
||||||
raise Exception ('Se han generado errores. No se puede continuar la ejecución de este módulo')
|
raise Exception ('Se han generado errores. No se puede continuar la ejecución de este módulo')
|
||||||
|
|