From 2efdf8b12d522b844c18d4dd298b6d67018a9525 Mon Sep 17 00:00:00 2001 From: "Ramón M. Gómez" Date: Tue, 14 May 2019 15:56:12 +0200 Subject: #908: Fix bug when execution outputs have UTF-8 characters. --- .../opengnsys/modules/server/OpenGnSys/__init__.py | 46 ++++------------------ 1 file changed, 8 insertions(+), 38 deletions(-) diff --git a/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py b/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py index 2d233150..fd6c1cba 100644 --- a/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py +++ b/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py @@ -39,6 +39,7 @@ import threading import time import urllib import signal + from opengnsys import REST from opengnsys import operations from opengnsys.log import logger @@ -136,18 +137,19 @@ class OpenGnSysWorker(ServerWorker): if os_type == 'oglive': menu_url = self.browser['url'] self._launch_browser('http://localhost/cgi-bin/httpd-log.sh') - # Executing command + # Execute the code (stat, out, err) = operations.exec_command(code) - # Removing command from the list + # Remove command from the list for c in self.commands: if c.getName() == op_id: self.commands.remove(c) - # Removing the REST API prefix, if needed + # Remove the REST API prefix, if needed if route.startswith(self.REST.endpoint): route = route[len(self.REST.endpoint):] - # Sending results + # Send back exit status and outputs (base64-encoded) self.REST.sendMessage(route, {'mac': self.interface.mac, 'ip': self.interface.ip, 'trace': op_id, - 'status': stat, 'output': out.encode('base64'), 'error': err.encode('base64')}) + 'status': stat, 'output': out.encode('utf8').encode('base64'), + 'error': err.encode('utf8').encode('base64')}) # Show latest menu, if OGAgent runs on ogLive if os_type == 'oglive': self._launch_browser(menu_url) @@ -446,41 +448,9 @@ class OpenGnSysWorker(ServerWorker): # Logging warnings logger.warn('Configuration data error: {}'.format(cols)) warnings += 1 - # Returning configuration data and count of warnings + # Return configuration data and count of warnings return {'serialno': serialno, 'storage': storage, 'warnings': warnings} - def process_command(self, path, get_params, post_params, server): - """ - Launches a thread to executing a command - :param path: ignored - :param get_params: ignored - :param post_params: object with format: - id: operation id. - script: command code - redirect_url: callback REST route - :param server: headers data - :rtype: object with launching status - """ - logger.debug('Received command operation with params: {}'.format(post_params)) - self._check_secret(server) - # Processing data - try: - script = post_params.get('script') - op_id = post_params.get('id') - route = post_params.get('redirect_url') - # Checking if the thread id. exists - for c in self.commands: - if c.getName() == str(op_id): - raise Exception('Task id. already exists: {}'.format(op_id)) - # Launching a new thread - thr = threading.Thread(name=op_id, target=self.task_command, args=(script, route, op_id)) - thr.start() - self.commands.append(thr) - except Exception as e: - logger.error('Got exception {}'.format(e)) - return {'error': e} - return {'op': 'launched'} - def process_execinfo(self, path, get_params, post_params, server): """ Returns running commands information -- cgit v1.2.3-18-g5258 From 4c47182a3e6c7d9e09042e6d60f7578f52339a8a Mon Sep 17 00:00:00 2001 From: "Ramón M. Gómez" Date: Tue, 14 May 2019 18:37:54 +0200 Subject: #908: Fix bug when killing the old browser before launching the new one. --- .../src/opengnsys/modules/server/OpenGnSys/__init__.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py b/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py index fd6c1cba..04c7ebc5 100644 --- a/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py +++ b/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py @@ -118,9 +118,14 @@ class OpenGnSysWorker(ServerWorker): :param url: URL to show """ logger.debug('Launching browser with URL: {}'.format(url)) - if hasattr(self.browser, 'process'): - self.browser['process'].kill() - os.kill(self.browser['process'].pid, signal.SIGINT) + # Trying to kill an old browser + try: + os.kill(self.browser['process'].pid, signal.SIGKILL) + except OSError: + logger.warn('Cannot kill the old browser process') + except KeyError: + # There is no previous browser + pass self.browser['url'] = url self.browser['process'] = subprocess.Popen(['browser', '-qws', url]) -- cgit v1.2.3-18-g5258 From e157720ae79fb76cdbfc6eff738ff1797c7cb722 Mon Sep 17 00:00:00 2001 From: "Ramón M. Gómez" Date: Wed, 15 May 2019 09:17:55 +0200 Subject: #761 Fix access bug from web frontend to a repository. --- .../frontend/src/app/api/repository.service.ts | 54 +++++++++++----------- .../frontend/src/environments/environment.ts | 6 +-- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/admin/WebConsole3/frontend/src/app/api/repository.service.ts b/admin/WebConsole3/frontend/src/app/api/repository.service.ts index 1561f41a..55fd88a0 100644 --- a/admin/WebConsole3/frontend/src/app/api/repository.service.ts +++ b/admin/WebConsole3/frontend/src/app/api/repository.service.ts @@ -1,27 +1,27 @@ -import { Injectable } from '@angular/core'; -import { HttpClient} from '@angular/common/http'; - -import { environment } from '../../environments/environment'; -import { Repository } from '../model/repository'; -import { RepositorySerializer } from '../serializer/repository.serializer'; - -import {ResourceService} from 'globunet-angular/core/providers/api/resource.service'; -import {Observable} from 'rxjs'; - - -@Injectable({ - providedIn: 'root' -}) -export class RepositoryService extends ResourceService { - - constructor(http: HttpClient) { - super(http, environment.API_URL, 'repositories', new RepositorySerializer()); - } - - getInfo(repository: Repository) { - const url = 'https://' + repository.ip + '/' + environment.BASE_DIR + environment.API_BASE_URL; - return this.httpClient.get(url, {headers: { - Authorization: repository.password - }}); - } -} +import { Injectable } from '@angular/core'; +import { HttpClient} from '@angular/common/http'; + +import { environment } from '../../environments/environment'; +import { Repository } from '../model/repository'; +import { RepositorySerializer } from '../serializer/repository.serializer'; + +import {ResourceService} from 'globunet-angular/core/providers/api/resource.service'; +import {Observable} from 'rxjs'; + + +@Injectable({ + providedIn: 'root' +}) +export class RepositoryService extends ResourceService { + + constructor(http: HttpClient) { + super(http, environment.API_URL, 'repositories', new RepositorySerializer()); + } + + getInfo(repository: Repository) { + const url = 'https://' + repository.ip + '/' + environment.BASE_DIR + environment.API_BASE_URL; + return this.httpClient.get(url, {headers: { + Authorization: repository.randomId + }}); + } +} diff --git a/admin/WebConsole3/frontend/src/environments/environment.ts b/admin/WebConsole3/frontend/src/environments/environment.ts index 16b61e25..ef17e26d 100644 --- a/admin/WebConsole3/frontend/src/environments/environment.ts +++ b/admin/WebConsole3/frontend/src/environments/environment.ts @@ -1,7 +1,7 @@ // This file can be replaced during build by using the `fileReplacements` array. // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. // The list of file replacements can be found in `angular.json`. -const url = 'https://172.16.140.210/opengnsys3'; +const url = 'https://SERVERIP/opengnsys3'; export const environment = { production: false, BASE_URL: url, @@ -9,8 +9,8 @@ export const environment = { API_PUBLIC_URL: url + '/api', API_BASE_URL: '/backend/web/app_dev.php/api', OAUTH_DOMAIN: '/backend/web/app_dev.php/oauth/v2/token', - OAUTH_CLIENT_ID: '1_23amzbdp4kskg80444oscko4w0w8wokocs88k0g8w88o4oggs4', - OAUTH_CLIENT_SECRET: '46rttt2trwo4gocgoc4w80k4s8ok48sg8s84kk0cw48csks8o8', + OAUTH_CLIENT_ID: 'CLIENTID', + OAUTH_CLIENT_SECRET: 'CLIENTSECRET', BASE_DIR: 'opengnsys3', clientstatus: ['off', 'initializing', 'oglive', 'busy', 'linux', 'linux_session', 'macos', 'windows', 'windows_session'], windowsboots: ['reboot', 'directo (kexec)'], -- cgit v1.2.3-18-g5258 From 85db11d8588b69ed6e56cd952df43ade5d511c59 Mon Sep 17 00:00:00 2001 From: "Ramón M. Gómez" Date: Thu, 16 May 2019 08:12:13 +0200 Subject: #761 New Vagrantfile to deploy an OpenGnsys 3 virtual laboratory. --- installer/vagrant/Vagrantfile-webconsole3-vbox | 171 +++++++++++++++++++++++++ server/bin/setserveraddr | 83 ++---------- 2 files changed, 181 insertions(+), 73 deletions(-) create mode 100644 installer/vagrant/Vagrantfile-webconsole3-vbox diff --git a/installer/vagrant/Vagrantfile-webconsole3-vbox b/installer/vagrant/Vagrantfile-webconsole3-vbox new file mode 100644 index 00000000..6cf4f037 --- /dev/null +++ b/installer/vagrant/Vagrantfile-webconsole3-vbox @@ -0,0 +1,171 @@ +# Vagrantfile to prepare virtual environment using VirtualBox provider to develop new AngularJS-based web interface. + +VAGRANTFILE_API_VERSION = "2" +ENV['VAGRANT_DEFAULT_PROVIDER'] = "virtualbox" +LANGUAGE = "es_ES" +ENV['LC_ALL'] = LANGUAGE + ".UTF-8" +SERVERMEM = 2048 +SERVERCPUS = 2 +CLIENTMEM = 512 +NCLIENTS = 4 +REPODISK = "repo.vdi" +REPOSIZE = 50 +MACPREFIX = "08:00:27:0e:65" +NETPREFIX = "192.168.2" +SERVERIP = "#{NETPREFIX}.10" +LOCALWEBPORT = 8443 + + +# OpenGnsys Server provisioning script. +SCRIPT = < /etc/default/locale +echo "LANG=\"$LANG\"" >> /etc/environment +echo "LANGUAGE=\"$LANG\"" >> /etc/environment +echo "LC_ALL=\"$LANG\"" >> /etc/environment +echo "LC_CTYPE=\"$LANG\"" >> /etc/environment +locale-gen --lang #{LANGUAGE} +sed -i "s/XKBLAYOUT=.*/XKBLAYOUT=\"${LANG%_*}\"/" /etc/default/keyboard +dpkg-reconfigure -fnoninteractive console-setup +# Exit if OpenGnsys is installed. +[ -f /opt/opengnsys/doc/VERSION.json ] && echo "Cannot provision, OpenGnsys is alread +y installed." && exit 1 +# Create repository disk using LVM, if necesary. +if [ -z "$(blkid /dev/mapper/og-images | grep ext4)" ]; then + pvcreate /dev/sdb + vgcreate og /dev/sdb + vgchange -ay + lvcreate -ay -n images -l 100%VG og + mkfs -t ext4 /dev/mapper/og-images + mkdir -p /opt/opengnsys/images + echo "/dev/mapper/og-images /opt/opengnsys/images ext4 defaults 0 0" >> /etc/fstab + mount -a +fi +# Update repositories. +add-apt-repository -y ppa:webupd8team/atom +apt-get update +# Install main dependencies. +apt-get install -y xfce4 gnome-icon-theme-full tango-icon-theme linux-headers-$(uname -r) firefox atom virtualbox-guest-dkms virtualbox-guest-utils virtualbox-guest-x11 +echo "allowed_users=anybody" > /etc/X11/Xwrapper.config +# Install OpenGnsys Server +tar xpvzf /vagrant/opengnsys3.tar.gz -C /tmp +/tmp/opengnsys/installer/opengnsys_installer.sh +echo y | /opt/opengnsys/bin/setserveraddr eth1 +# Configure the virtual lab. +read -e APIID APISECRET <<<$(/opt/opengnsys/www3/backend/app/console doctrine:query:sql "SELECT random_id, secret FROM og_core__clients WHERE id=1;" | awk -F\\" '$2~/^(random_id|secret)$/ {getline; printf("%s ", $2)}') +rm -fr /opt/opengnsys/www3/backend/var/cache/* +REQ=$(curl -sk 'https://localhost/opengnsys3/backend/web/app_dev.php/oauth/v2/token?client_id=1_'"$APIID"'&client_secret='"$APISECRET"'&grant_type=password&username=admin&password=admin') +TOKEN="$(echo $REQ | jq -r .access_token)" +REQ=$(curl -sk -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"name":"Repositorio virtual", "ip":"#{SERVERIP}", "password":"'$(php -r 'echo md5(uniqid(rand(), true));')'", "configurationpath":"/", "adminpath":"/", "pxepath":"/", "port":0 }' https://localhost/opengnsys3/backend/web/app_dev.php/api/private/repositories) +REPOID=$(echo $REQ | jq -r .id) +REQ=$(curl -sk -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"name":"Aula virtual", "description":"Despliegue virtual con Vagrant.", "networkSettings":{"mcastMode":"full-duplex", "mcastIp":"239.194.2.11", "mcastPort":9000, "mcastPort":9000, "mcastSpeed":100, "netmask":"#{NETPREFIX}.0", "router":"#{NETPREFIX}.1", "p2pMode":"peer", "p2pTime":60} }' https://localhost/opengnsys3/backend/web/app_dev.php/api/private/organizationalunits) +OUID=$(echo $REQ | jq -r .id) +for ((i=11; i<=10+#{NCLIENTS}; i++)); do + sed -i "/^}$/ i host pc${i} { hardware ethernet #{MACPREFIX}:${i}; fixed-address #{NETPREFIX}.${i}; }" /etc/dhcp/dhcpd.conf + [ $i == 11 ] && BOOTID=5 || BOOTID=6 + REQ=$(curl -sk -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"name":"pc'$i'", "ip":"#{NETPREFIX}.'$i'", "mac":"#{MACPREFIX}:'$i'", "serialno":"", "netiface":"eth0", "netdriver":"generic", "netboot":'"$BOOTID"', "organizationalUnit":'"$OUID"', "repository":'"$REPOID"'}' https://localhost/opengnsys3/backend/web/app_dev.php/api/private/clients) +done +systemctl restart isc-dhcp-server +#/opt/opengnsys/bin/setclientmode ogLiveAdmin pc11 PERM +#for ((i=12; i<=#{NCLIENTS+10}; i++)); do +# /opt/opengnsys/bin/setclientmode ogLive pc$i PERM +#done +sed -i "s,\(url = 'https://\)[^/]*,\1localhost:#{LOCALWEBPORT}," /opt/opengnsys/www3/frontend/main.js +sed -i "s,\(url = 'https://\)[^/]*,\1localhost:#{LOCALWEBPORT}," /opt/opengnsys/www3/frontend/main.js.map +echo "Notes:" +echo "- New OpenGnsys Server URL: https://localhost:#{LOCALWEBPORT}/opengnsys3/frontend/" +EOT + +# Client 1 OS provisioning script. +OGAGENTPKG = "ogagent_1.1.1_all.deb" +MODELSCRIPT = <&2 - exit 2 - fi - # Updating configuration variables (if URLs does not contain "localhost"). - sed -e "s,ServidorAdm=.*,ServidorAdm=$SERVERIP," \ - -e "s,IPlocal=.*,IPlocal=$SERVERIP," \ - -e "s,UrlMenu=https?://\([^/]*\)/\(.*\),UrlMenu=https://$SERVERIP/\2," \ - -e '/localhost/!s,https\?://[^/]*/\(.*\),https://'$SERVERIP'/\1,' $f >$tmpfile - file="${f/./-$SERVERDEV.}" - # Copying updated file, if needed. - if [ ! $f -ef $file ] || ! diff -q $tmpfile $file &>/dev/null; then - cp $tmpfile $file - ln -f $file $f - CHANGE=1 - fi - done - - # Processing when something has changed. - if [ $CHANGE == 1 ]; then - # Restart OpenGnsys services. - /etc/init.d/opengnsys restart - # If Repository is active, generating a new API token. - source $DEFAULTFILE - if [ "$RUN_OGADMREPO" == "yes" ]; then - REPOKEY=$(php -r 'echo md5(uniqid(rand(), true));') - sed -i -e "s/ApiToken=.*/ApiToken=$REPOKEY/" $OPENGNSYS/etc/ogAdmRepo.cfg - fi - # If OpenGnsys Server is active, updating the database. - if [ "$RUN_OGADMSERVER" == "yes" ]; then - source $OPENGNSYS/etc/ogAdmServer.cfg - # Creating credentials file. - cat << EOT > $MYCNF -[client] -user=$USUARIO -password=$PASSWORD -EOT - # Updating OpenGnsys Server IP address. - mysql --defaults-extra-file=$MYCNF -D "$CATALOG" -e \ - "UPDATE entornos - SET ipserveradm='$SERVERIP' - WHERE identorno=1" - # If OpenGnsys Repository is active, updating IP address and API token. - if [ "$RUN_OGADMREPO" == "yes" ]; then - mysql --defaults-extra-file=$MYCNF -D "$CATALOG" -e \ - "UPDATE repositorios - SET ip='$SERVERIP', apikey='$REPOKEY' - WHERE ip='$OLDSERVERIP'" - unset REPOKEY - fi - # Updating all menu URLs. - mysql --defaults-extra-file=$MYCNF -D "$CATALOG" -e \ - "UPDATE menus - SET htmlmenupub = REPLACE(htmlmenupub, '$OLDSERVERIP', '$SERVERIP'), - htmlmenupri = REPLACE(htmlmenupri, '$OLDSERVERIP', '$SERVERIP');" - # Updating all PXE files. - find $PXEDIR -name "01-*" -exec sed -i -e "s/$OLDSERVERIP/$SERVERIP/g" {} \; - fi - + OLDSERVERIP=$(jq -r .server.ip $CONFIGFILE) + if [ "$SERVERIP" != "$OLDSERVERIP" ]; then + # Updating configuration file. + jq ".server.ip=\"$SERVERIP\"" $CONFIGFILE | sponge $CONFIGFILE + # Updating all PXE files. + find $PXEDIR -name "01-*" -exec sed -i -e "s/$OLDSERVERIP/$SERVERIP/g" {} \; # Showing manual task to do after execution. cat << EOT Default server interface set to: $SERVERDEV ($SERVERIP) @@ -161,7 +99,6 @@ Manual tasks: - Check PXE files. - Log-in as Web Console user: - Check menu URLs. -${REPOKEY:+" - Update repository API token"} EOT else # Showing message if nothing changes. @@ -173,6 +110,6 @@ else exit 1 fi -# Removing temporary files. -rm -f $tmpfile $MYCNF +# Removing temporary file. +rm -f $tmpfile -- cgit v1.2.3-18-g5258 From e848ab462bf599171a87e24e10f365fa7fe9d643 Mon Sep 17 00:00:00 2001 From: "Ramón M. Gómez" Date: Thu, 16 May 2019 08:14:14 +0200 Subject: #908: OGAgent uses a new Python decorator to check the REST access token. --- .../opengnsys/modules/server/OpenGnSys/__init__.py | 104 ++++++++++++++------- 1 file changed, 70 insertions(+), 34 deletions(-) diff --git a/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py b/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py index 04c7ebc5..6e729046 100644 --- a/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py +++ b/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py @@ -47,6 +47,25 @@ from opengnsys.workers import ServerWorker from six.moves.urllib import parse +# Check authorization header decorator +def check_secret(fnc): + """ + Decorator to check for received secret key and raise exception if it isn't valid. + """ + def wrapper(*args, **kwargs): + try: + this, path, get_params, post_params, server = args # @UnusedVariable + if this.random == server.headers['Authorization']: + fnc(*args, **kwargs) + else: + raise Exception('Unauthorized operation') + except Exception as e: + logger.error(e) + raise Exception(e) + + return wrapper + + # Error handler decorator. def catch_background_error(fnc): def wrapper(*args, **kwargs): @@ -93,7 +112,6 @@ class OpenGnSysWorker(ServerWorker): interface = None # Bound interface for OpenGnsys REST = None # REST object loggedin = False # User session flag - locked = {} # Locked partitions browser = {} # Browser info commands = [] # Running commands random = None # Random string for secure connections @@ -101,17 +119,6 @@ class OpenGnSysWorker(ServerWorker): access_token = refresh_token = None # Server authorization tokens grant_type = 'http://opengnsys.es/grants/og_client' - def _check_secret(self, server): - """ - Checks for received secret key and raise exception if it isn't valid. - """ - try: - if self.random != server.headers['Authorization']: - raise Exception('Unauthorized operation') - except Exception as e: - logger.error(e) - raise Exception(e) - def _launch_browser(self, url): """ Launchs the Browser with specified URL @@ -238,7 +245,7 @@ class OpenGnSysWorker(ServerWorker): -

Initializing...

+

OpenGnsys 3

""" f = open('/tmp/init.html', 'w') @@ -319,7 +326,12 @@ class OpenGnSysWorker(ServerWorker): def process_status(self, path, get_params, post_params, server): """ - Returns client status (OS type and login status). + Returns client status (OS type or execution status) and login status. + :param path: + :param get_params: + :param post_params: + :param server: + :return: JSON object {"status": "status_code", "loggedin": boolean} """ res = {'loggedin': self.loggedin} try: @@ -327,32 +339,42 @@ class OpenGnSysWorker(ServerWorker): except KeyError: res['status'] = '' # Check if OpenGnsys Client is busy - if res['status'] == 'oglive' and self.locked: + if res['status'] == 'oglive' and len(self.commands) > 0: res['status'] = 'busy' return res + @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') - self._check_secret(server) - # Rebooting thread. + # 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') - self._check_secret(server) - # Powering off thread. + # Powering off thread def pwoff(): time.sleep(2) operations.poweroff() @@ -360,18 +382,23 @@ class OpenGnSysWorker(ServerWorker): threading.Thread(target=pwoff).start() return {'op': 'launched'} + @check_secret def process_script(self, path, get_params, post_params, server): """ Processes an script execution (script should be encoded in base64) + :param path: + :param get_params: + :param post_params: JSON object {"redirect_uri, "uri", "script": "commands", "id": trace_id} + :param server: authorization header + :return: JSON object {"op": "launched"} or {"error": "message"} """ logger.debug('Processing script request') - self._check_secret(server) # Processing data try: script = urllib.unquote(post_params.get('script').decode('base64')).decode('utf8') op_id = post_params.get('id') route = post_params.get('redirect_uri') - # Checking if the thread id. exists + # Check if the thread id. exists for c in self.commands: if c.getName() == str(op_id): raise Exception('Task id. already exists: {}'.format(op_id)) @@ -388,43 +415,43 @@ class OpenGnSysWorker(ServerWorker): return {'error': e} return {'op': 'launched'} + @check_secret def process_logoff(self, path, get_params, post_params, server): """ Closes user session. """ logger.debug('Received logoff operation') - self._check_secret(server) - # Sending log off message to OGAgent client. + # Send log off message to OGAgent client. self.sendClientMessage('logoff', {}) return {'op': 'sent to client'} + @check_secret def process_popup(self, path, get_params, post_params, server): """ Shows a message popup on the user's session. """ logger.debug('Received message operation') - self._check_secret(server) - # Sending popup message to OGAgent client. + # Send popup message to OGAgent client. self.sendClientMessage('popup', post_params) return {'op': 'launched'} def process_client_popup(self, params): self.REST.sendMessage('popup_done', params) + @check_secret def process_config(self, path, get_params, post_params, server): """ Returns client configuration :param path: :param get_params: :param post_params: - :param server: - :return: object + :param server: authorization header + :return: JSON object """ serialno = '' # Serial number storage = [] # Storage configuration warnings = 0 # Number of warnings logger.debug('Received getconfig operation') - # self._check_secret(server) # Processing data for row in operations.get_configuration().split(';'): cols = row.split(':') @@ -450,33 +477,42 @@ class OpenGnSysWorker(ServerWorker): logger.warn('Configuration parameter error: {}'.format(cols)) warnings += 1 else: - # Logging warnings + # Log warnings logger.warn('Configuration data error: {}'.format(cols)) warnings += 1 # Return configuration data and count of warnings return {'serialno': serialno, 'storage': storage, 'warnings': warnings} + @check_secret def process_execinfo(self, path, get_params, post_params, server): """ Returns running commands information :param path: :param get_params: :param post_params: - :param server: - :return: object + :param server: authorization header + :return: JSON array: [["callback_url", "commands", trace_id], ...] """ data = [] logger.debug('Received execinfo operation') - self._check_secret(server) - # Returning the arguments of all running threads + # Return the arguments of all running threads for c in self.commands: if c.is_alive(): data.append(c.__dict__['_Thread__args']) return data + @check_secret def process_stopcmd(self, path, get_params, post_params, server): + """ + Stops a running process identified by its trace id. + :param path: + :param get_params: + :param post_params: JSON object {"trace": trace_id} + :param server: authorization header + :return: JSON object: {"stopped": trace_id} + """ logger.debug('Received stopcmd operation with params {}:'.format(post_params)) - self._check_secret(server) + # Find operation id. and stop the thread op_id = post_params.get('trace') for c in self.commands: if c.is_alive() and c.getName() == str(op_id): -- cgit v1.2.3-18-g5258 From 06432724ce17c0dedbe540cc4e3d8a621705014e Mon Sep 17 00:00:00 2001 From: "jm.bardallo" Date: Fri, 17 May 2019 11:41:01 +0200 Subject: Solucionado pantalla de perfil software Revisados los comandos para enviar el parametro sendConfig --- .../src/app/api/software-component.service.ts | 2 +- .../frontend/src/app/api/software-type.service.ts | 36 +++++-- .../core/header-inner/header-inner.component.html | 4 +- .../app/form-type/software-profile.form-type.ts | 12 +++ .../WebConsole3/frontend/src/app/model/command.ts | 3 +- .../frontend/src/app/model/software-profile.ts | 14 +-- .../create-image-command.component.ts | 4 +- .../delete-cache-image-command.component.ts | 6 +- .../format-command/format-command.component.ts | 13 ++- .../partition-format-command.component.scss | 6 +- .../partition-format-command.component.ts | 3 +- .../software-profile.component.html | 84 ++++++++++++++- .../software-profile/software-profile.component.ts | 117 ++++++++++++++++++--- .../src/app/service/og-commands.service.ts | 15 ++- .../frontend/src/app/service/og-common.service.ts | 16 ++- 15 files changed, 269 insertions(+), 66 deletions(-) create mode 100644 admin/WebConsole3/frontend/src/app/form-type/software-profile.form-type.ts diff --git a/admin/WebConsole3/frontend/src/app/api/software-component.service.ts b/admin/WebConsole3/frontend/src/app/api/software-component.service.ts index b154d41a..515f1cb4 100644 --- a/admin/WebConsole3/frontend/src/app/api/software-component.service.ts +++ b/admin/WebConsole3/frontend/src/app/api/software-component.service.ts @@ -14,7 +14,7 @@ import {ResourceService} from "globunet-angular/core/providers/api/resource.serv export class SoftwareComponentService extends ResourceService { constructor(http: HttpClient){ - super(http, environment.API_URL,"softwarecomponents", new SoftwareComponentSerializer()); + super(http, environment.API_URL,"softwares", new SoftwareComponentSerializer()); } } diff --git a/admin/WebConsole3/frontend/src/app/api/software-type.service.ts b/admin/WebConsole3/frontend/src/app/api/software-type.service.ts index ccc6eb8f..1c250b91 100644 --- a/admin/WebConsole3/frontend/src/app/api/software-type.service.ts +++ b/admin/WebConsole3/frontend/src/app/api/software-type.service.ts @@ -1,20 +1,36 @@ -import { Injectable } from '@angular/core'; -import { HttpClient} from '@angular/common/http'; +import {Injectable} from '@angular/core'; +import {HttpClient} from '@angular/common/http'; -import { environment } from '../../environments/environment'; -import { SoftwareType } from "../model/software-type"; -import { SoftwareTypeSerializer } from "../serializer/software-type.serializer"; +import {environment} from '../../environments/environment'; +import {SoftwareType} from '../model/software-type'; +import {SoftwareTypeSerializer} from '../serializer/software-type.serializer'; -import {ResourceService} from "globunet-angular/core/providers/api/resource.service"; +import {ResourceService} from 'globunet-angular/core/providers/api/resource.service'; +import {QueryOptions} from 'globunet-angular/core/providers/api/query-options'; +import {Observable} from 'rxjs'; +import {OgCommonService} from '../service/og-common.service'; @Injectable({ - providedIn: 'root' + providedIn: 'root' }) export class SoftwareTypeService extends ResourceService { - constructor(http: HttpClient){ - super(http, environment.API_URL,"softwaretypes", new SoftwareTypeSerializer()); - } + constructor(http: HttpClient, private ogCommonService: OgCommonService) { + super(http, environment.API_URL, 'softwaretypes', new SoftwareTypeSerializer()); + } + + list(queryOptions?: QueryOptions): Observable { + return new Observable((observer) => { + this.ogCommonService.loadEngineConfig().subscribe( + data => { + observer.next(data.constants.sofwaretypes); + }, + error => { + observer.error(error); + } + ); + }); + } } diff --git a/admin/WebConsole3/frontend/src/app/core/header-inner/header-inner.component.html b/admin/WebConsole3/frontend/src/app/core/header-inner/header-inner.component.html index 31b4286d..23cdb7e0 100644 --- a/admin/WebConsole3/frontend/src/app/core/header-inner/header-inner.component.html +++ b/admin/WebConsole3/frontend/src/app/core/header-inner/header-inner.component.html @@ -9,7 +9,7 @@
  • - +
  • @@ -21,7 +21,7 @@ - A + {{task.client.name}} ({{task.client.ip}})
    {{task.commandType|translate}} diff --git a/admin/WebConsole3/frontend/src/app/form-type/software-profile.form-type.ts b/admin/WebConsole3/frontend/src/app/form-type/software-profile.form-type.ts new file mode 100644 index 00000000..baa16afe --- /dev/null +++ b/admin/WebConsole3/frontend/src/app/form-type/software-profile.form-type.ts @@ -0,0 +1,12 @@ +import {GlobunetFormType} from './globunet.form-type'; +import {SoftwareProfile} from '../model/software-profile'; + + +export class SoftwareProfileFormType extends GlobunetFormType { + getForm() { + const formType = GlobunetFormType.getForm(new SoftwareProfile()); + this.setFieldType(formType, 'description', 'textarea'); + this.removeField(formType, 'softwares'); + return formType; + } +} diff --git a/admin/WebConsole3/frontend/src/app/model/command.ts b/admin/WebConsole3/frontend/src/app/model/command.ts index 2c5697aa..5fc44734 100644 --- a/admin/WebConsole3/frontend/src/app/model/command.ts +++ b/admin/WebConsole3/frontend/src/app/model/command.ts @@ -1,9 +1,10 @@ import { Resource } from 'globunet-angular/core/models/api/resource'; -export class Excecution { +export class Execution { script = ''; clients = ''; type = ''; + sendConfig = false; } export class Command extends Resource { diff --git a/admin/WebConsole3/frontend/src/app/model/software-profile.ts b/admin/WebConsole3/frontend/src/app/model/software-profile.ts index 5b3ba732..6d411f20 100644 --- a/admin/WebConsole3/frontend/src/app/model/software-profile.ts +++ b/admin/WebConsole3/frontend/src/app/model/software-profile.ts @@ -1,6 +1,8 @@ -import { Resource } from 'globunet-angular/core/models/api/resource'; - -export class SoftwareProfile extends Resource { - description: string; - comments: string; -} +import { Resource } from 'globunet-angular/core/models/api/resource'; +import {SoftwareComponent} from './software-component'; + +export class SoftwareProfile extends Resource { + description = ''; + comments = ''; + public softwares: SoftwareComponent[] = []; +} diff --git a/admin/WebConsole3/frontend/src/app/pages/command/create-image-command/create-image-command.component.ts b/admin/WebConsole3/frontend/src/app/pages/command/create-image-command/create-image-command.component.ts index 8f018e33..e97d20fa 100644 --- a/admin/WebConsole3/frontend/src/app/pages/command/create-image-command/create-image-command.component.ts +++ b/admin/WebConsole3/frontend/src/app/pages/command/create-image-command/create-image-command.component.ts @@ -10,7 +10,7 @@ import {User} from '../../../model/user'; import {OGCommandsService} from '../../../service/og-commands.service'; import {CommandService} from '../../../api/command.service'; import {Image} from '../../../model/image'; -import {Command, Excecution} from '../../../model/command'; +import {Command, Execution} from '../../../model/command'; import {Client, Partition} from '../../../model/client'; import {Repository} from '../../../model/repository'; import {RepositoryService} from '../../../api/repository.service'; @@ -26,7 +26,7 @@ export class CreateImageCommandComponent implements OnInit { private readonly user: User; private constants: any; public repositories: Repository[]; - public execution = new Excecution(); + public execution = new Execution(); public commands: Command[] = []; public client: Client; public images = []; diff --git a/admin/WebConsole3/frontend/src/app/pages/command/delete-cache-image-command/delete-cache-image-command.component.ts b/admin/WebConsole3/frontend/src/app/pages/command/delete-cache-image-command/delete-cache-image-command.component.ts index efc14d6d..fb238868 100644 --- a/admin/WebConsole3/frontend/src/app/pages/command/delete-cache-image-command/delete-cache-image-command.component.ts +++ b/admin/WebConsole3/frontend/src/app/pages/command/delete-cache-image-command/delete-cache-image-command.component.ts @@ -10,7 +10,7 @@ import {User} from '../../../model/user'; import {OGCommandsService} from '../../../service/og-commands.service'; import {CommandService} from '../../../api/command.service'; import {Image} from '../../../model/image'; -import {Command, Excecution} from '../../../model/command'; +import {Command, Execution} from '../../../model/command'; import {Client} from '../../../model/client'; import {Repository} from '../../../model/repository'; import {RepositoryService} from '../../../api/repository.service'; @@ -25,7 +25,7 @@ export class DeleteCacheImageCommandComponent implements OnInit { private readonly user: User; private constants: any; public repositories: Repository[]; - public execution = new Excecution(); + public execution = new Execution(); public commands: Command[] = []; public client: Client; public cacheImages = []; @@ -102,9 +102,9 @@ export class DeleteCacheImageCommandComponent implements OnInit { this.execution.script += '\n'; } } - this.execution.script += this.constants.commands.REFRESH_INFO + '\n'; this.execution.script = this.execution.script.replace(/\"/g, '\\"').replace(/\$/g, '\\\$'); this.execution.type = 'RUN_SCRIPT'; + this.execution.sendConfig = true; this.commandService.execute(this.execution).subscribe( (response) => { diff --git a/admin/WebConsole3/frontend/src/app/pages/command/format-command/format-command.component.ts b/admin/WebConsole3/frontend/src/app/pages/command/format-command/format-command.component.ts index 62b733b8..05b3ebfe 100644 --- a/admin/WebConsole3/frontend/src/app/pages/command/format-command/format-command.component.ts +++ b/admin/WebConsole3/frontend/src/app/pages/command/format-command/format-command.component.ts @@ -11,6 +11,7 @@ import {OGCommandsService} from '../../../service/og-commands.service'; import {Client, Partition} from '../../../model/client'; import {CommandService} from '../../../api/command.service'; import {forkJoin} from 'rxjs'; +import {Execution} from '../../../model/command'; @Component({ selector: 'app-format-command', @@ -18,7 +19,7 @@ import {forkJoin} from 'rxjs'; styleUrls: [ './format-command.component.scss' ] }) export class FormatCommandComponent implements OnInit { - execution = {clients: '', script: '', type: ''}; + execution = new Execution(); command = {}; user: User; clientGroups = {}; @@ -85,10 +86,7 @@ export class FormatCommandComponent implements OnInit { const groups = Object.keys(this.clientGroups); for (let g = 0; g < groups.length; g++) { if (!executions[g]) { - executions[g] = { - clients: '', - script: '' - }; + executions[g] = new Execution(); } // Recorrer las particiones del primer cliente de la lista y ver si hay alguna seleccionada const found = false; @@ -101,7 +99,7 @@ export class FormatCommandComponent implements OnInit { while (!found && index < client.partitions.length) { const partition = client.partitions[index]; if (partition.selected === true) { - if(executions[g].script === '') { + if (executions[g].script === '') { executions[g].script = 'ogUnmountAll ' + partition.numDisk + '\n'; } // Si la particion es cache @@ -122,7 +120,8 @@ export class FormatCommandComponent implements OnInit { const execution = { type: 'RUN_SCRIPT', script: executions[index].script, - clients: executions[index].clients.substring(0, executions[index].clients.length - 1) // Quitar la ultima "," + clients: executions[index].clients.substring(0, executions[index].clients.length - 1), // Quitar la ultima "," + sendConfig: true }; promises.push(this.commandService.execute(execution)); } diff --git a/admin/WebConsole3/frontend/src/app/pages/command/partition-format-command/partition-format-command.component.scss b/admin/WebConsole3/frontend/src/app/pages/command/partition-format-command/partition-format-command.component.scss index 97d2231d..ec120f1f 100644 --- a/admin/WebConsole3/frontend/src/app/pages/command/partition-format-command/partition-format-command.component.scss +++ b/admin/WebConsole3/frontend/src/app/pages/command/partition-format-command/partition-format-command.component.scss @@ -12,11 +12,13 @@ right: 0; margin: 0; background-color: black; - width: 2px; + width: 4px; height: 100%; padding: 0 !important; cursor: col-resize; border: 1px solid transparent; } - + table.disk-partitions td:last-child span.resizer:last-child { + display: none; + } } diff --git a/admin/WebConsole3/frontend/src/app/pages/command/partition-format-command/partition-format-command.component.ts b/admin/WebConsole3/frontend/src/app/pages/command/partition-format-command/partition-format-command.component.ts index 8c75fa2e..eb36930a 100644 --- a/admin/WebConsole3/frontend/src/app/pages/command/partition-format-command/partition-format-command.component.ts +++ b/admin/WebConsole3/frontend/src/app/pages/command/partition-format-command/partition-format-command.component.ts @@ -12,6 +12,7 @@ import {CommandService} from '../../../api/command.service'; import {DomSanitizer} from '@angular/platform-browser'; import {ChartOptions} from 'chart.js'; import {Client} from '../../../model/client'; +import {Execution} from '../../../model/command'; @Component({ selector: 'app-partition-format-command', @@ -19,7 +20,7 @@ import {Client} from '../../../model/client'; styleUrls: [ './partition-format-command.component.scss' ] }) export class PartitionFormatCommandComponent implements OnInit { - execution = {clients: '', script: '', type: ''}; + execution = new Execution(); command = {}; user: User; constants: any; diff --git a/admin/WebConsole3/frontend/src/app/pages/software-profile/software-profile.component.html b/admin/WebConsole3/frontend/src/app/pages/software-profile/software-profile.component.html index 4cb0f6e5..0a9abe16 100644 --- a/admin/WebConsole3/frontend/src/app/pages/software-profile/software-profile.component.html +++ b/admin/WebConsole3/frontend/src/app/pages/software-profile/software-profile.component.html @@ -1 +1,83 @@ -
    Html template for class SoftwareProfile
    \ No newline at end of file +
    +

    +

    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    +

    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +

    +
    + + + + +
    +
    +
    + + + + + + + + + + + + + +
    + + + + {{softwareComponent.description}} + + + + {{softwareComponent.type ? softwareComponent.type.name : '-'}} + +
    +
    +
    +
    +
    +
    diff --git a/admin/WebConsole3/frontend/src/app/pages/software-profile/software-profile.component.ts b/admin/WebConsole3/frontend/src/app/pages/software-profile/software-profile.component.ts index bff05a1c..b34cfb77 100644 --- a/admin/WebConsole3/frontend/src/app/pages/software-profile/software-profile.component.ts +++ b/admin/WebConsole3/frontend/src/app/pages/software-profile/software-profile.component.ts @@ -1,17 +1,100 @@ -import { Component } from '@angular/core'; - -import { SoftwareProfileService } from 'src/app/api/software-profile.service'; -import { SoftwareProfile } from 'src/app/model/software-profile'; - -@Component({ - selector: 'software-profile', - templateUrl: './software-profile.component.html', - styleUrls: [ './software-profile.component.scss' ] -}) -export class SoftwareProfileComponent { - // this tells the tabs component which Pages - // should be each tab's root Page - constructor(public softwareProfileService: SoftwareProfileService) { - } - -} +import {Component, OnInit} from '@angular/core'; + +import { SoftwareProfileService } from 'src/app/api/software-profile.service'; +import {ParamMap, ActivatedRoute, Router} from '@angular/router'; +import {SoftwareProfile} from '../../model/software-profile'; +import {ToasterService} from '../../service/toaster.service'; +import {SoftwareComponentService} from '../../api/software-component.service'; +import {SoftwareComponent} from '../../model/software-component'; +import {SoftwareProfileFormType} from '../../form-type/software-profile.form-type'; +import {OgCommonService} from '../../service/og-common.service'; + +@Component({ + selector: 'app-software-profile', + templateUrl: './software-profile.component.html', + styleUrls: [ './software-profile.component.scss' ] +}) +export class SoftwareProfileComponent implements OnInit { + public softwareProfile: SoftwareProfile = new SoftwareProfile(); + public softwareComponents: SoftwareComponent[]; + formType: any; + // this tells the tabs component which Pages + // should be each tab's root Page + constructor(public ogCommonService: OgCommonService, public softwareProfileService: SoftwareProfileService, + public softwareComponentsService: SoftwareComponentService, private routerCtrl: Router, + private router: ActivatedRoute, private toaster: ToasterService) { + this.formType = new SoftwareProfileFormType().getForm(); + } + + ngOnInit(): void { + this.softwareComponentsService.list().subscribe( + components => { + this.softwareComponents = components; + this.router.paramMap.subscribe( + (params: ParamMap) => { + if(params.get('id')) { + this.softwareProfileService.read(Number(params.get('id'))).subscribe( + data => { + this.softwareProfile = data; + const self = this; + // Seleccionar los componentes adecuados + this.softwareComponents.forEach(function(component, index, array) { + if ( self.softwareProfile.softwares.find((value) => value.id === component.id)) { + // @ts-ignore + component.$$selected = true; + } + }); + }, + error => { + this.toaster.pop({type: 'error', body: 'error_loading_software_profile', title: 'error'}); + } + ); + } else { + this.softwareProfile = new SoftwareProfile(); + } + } + ); + }, + error => { + this.toaster.pop({type: 'error', body: 'error_loading_software_components', title: 'error'}); + } + ); + + } + + save() { + this.softwareProfile.softwares = []; + const self = this; + this.softwareComponents.forEach(function(component, index, array) { + // @ts-ignore + if (component.$$selected === true) { + // @ts-ignore + self.softwareProfile.softwares.push(component.id); + } + }); + // Actualizar o guardar + let request; + if(this.softwareProfile.id !== 0){ + request = this.softwareProfileService.update(this.softwareProfile); + } + else{ + request = this.softwareProfileService.create(this.softwareProfile); + } + request.subscribe( + (response) => { + this.toaster.pop({type: 'success', title: 'success', body: 'successfully_saved'}); + this.routerCtrl.navigate(['/app/software']).then( + success => { + console.log(success); + }, + error => { + console.log(error); + } + ); + }, + (error) => { + this.toaster.pop({type: 'error', title: 'error', body: error}); + } + ); + } +} diff --git a/admin/WebConsole3/frontend/src/app/service/og-commands.service.ts b/admin/WebConsole3/frontend/src/app/service/og-commands.service.ts index 1ea33faa..6b54a896 100644 --- a/admin/WebConsole3/frontend/src/app/service/og-commands.service.ts +++ b/admin/WebConsole3/frontend/src/app/service/og-commands.service.ts @@ -39,9 +39,16 @@ export class OGCommandsService { this.commandService.execute(this.execution).subscribe( (response: any[]) => { // Buscar en la respuesta si hay algún statuscode diferente de 200 - const errors = response.filter(function(value) { - return (value.statusCode && value.statusCode !== '!200'); - } ); + const errors = []; + const keys = Object.keys(response); + keys.forEach((index) => { + const elemKeys = Object.keys(response[index]); + elemKeys.forEach((elemKey) => { + if (elemKey === 'statusCode' && response[index][elemKey] !== 200) { + errors.push(response[index]); + } + }); + }); let errorStr = ''; let toasterOpts = {type: 'success', title: 'success', body: this.translate.instant('successfully_executed')}; if (errors.length > 0) { @@ -116,7 +123,7 @@ export class OGCommandsService { // Crear como nombre para mostrar, el disco y partición del sistema const obj = Object.assign({}, client.partitions[index]); const str = 'disco: ' + obj.numDisk + ', part: ' + obj.numPartition + ', SO: ' + client.partitions[index].osName; - clonablePartitions.push(obj.numDisk + ' ' + obj.numPartition) + clonablePartitions.push(obj.numDisk + ' ' + obj.numPartition); options.scope.partitions.push(str); } } diff --git a/admin/WebConsole3/frontend/src/app/service/og-common.service.ts b/admin/WebConsole3/frontend/src/app/service/og-common.service.ts index b529199d..3de25304 100644 --- a/admin/WebConsole3/frontend/src/app/service/og-common.service.ts +++ b/admin/WebConsole3/frontend/src/app/service/og-common.service.ts @@ -198,15 +198,13 @@ export class OgCommonService { } saveSelection() { - if (Object.keys(this.selectedClients).length > 0) { - localStorage.setItem('selectedClients', JSON.stringify(this.selectedClients, function (key, value) { - let result = value; - if (key === 'parent' && typeof value === 'object') { - result = value.id; - } - return result; - })); - } + localStorage.setItem('selectedClients', JSON.stringify(this.selectedClients, function (key, value) { + let result = value; + if (key === 'parent' && typeof value === 'object') { + result = value.id; + } + return result; + })); } getSelectionSize() { -- cgit v1.2.3-18-g5258 From d34b00c51df4dcc5aa88e76361b22ef7c1ff72a8 Mon Sep 17 00:00:00 2001 From: "Ramón M. Gómez" Date: Fri, 17 May 2019 11:51:05 +0200 Subject: #761 Agent optionally sends back the disks configuration after script execution. --- .../src/opengnsys/modules/server/OpenGnSys/__init__.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py b/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py index 6e729046..ab31fb39 100644 --- a/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py +++ b/admin/Sources/Clients/ogagent/src/opengnsys/modules/server/OpenGnSys/__init__.py @@ -136,7 +136,7 @@ class OpenGnSysWorker(ServerWorker): self.browser['url'] = url self.browser['process'] = subprocess.Popen(['browser', '-qws', url]) - def _task_command(self, route, code, op_id): + def _task_command(self, route, code, op_id, send_config=False): """ Task to execute a command and return results to a server URI :param route: server callback REST route to return results @@ -164,6 +164,10 @@ class OpenGnSysWorker(ServerWorker): 'error': err.encode('utf8').encode('base64')}) # Show latest menu, if OGAgent runs on ogLive if os_type == 'oglive': + # Send configuration data, if needed + if send_config: + self.REST.sendMessage('clients/configs', {'mac': self.interface.mac, 'ip': self.interface.ip, + 'config': operations.get_configuration()}) self._launch_browser(menu_url) def onActivation(self): @@ -397,14 +401,15 @@ class OpenGnSysWorker(ServerWorker): try: script = urllib.unquote(post_params.get('script').decode('base64')).decode('utf8') op_id = post_params.get('id') - route = post_params.get('redirect_uri') + route = post_params.get('redirectUri') + send_config = (post_params.get('sendConfig', 'false') == 'true') # Check if the thread id. exists for c in self.commands: if c.getName() == str(op_id): raise Exception('Task id. already exists: {}'.format(op_id)) if post_params.get('client', 'false') == 'false': # Launching a new thread - thr = threading.Thread(name=op_id, target=self._task_command, args=(route, script, op_id)) + thr = threading.Thread(name=op_id, target=self._task_command, args=(route, script, op_id, send_config)) thr.start() self.commands.append(thr) else: -- cgit v1.2.3-18-g5258