import acrort
import acrobind
import argparse
import re
import sys
LOGGING_CONTROL_COMMAND_ID = 'C94C9C84-9B24-4830-AB9F-A5E342607057'
RE_UUID = re.compile("[0-F]{8}-[0-F]{4}-[0-F]{4}-[0-F]{4}-[0-F]{12}", re.I)
MMS_CHANNELS = [
'alerts',
'archive-manager',
'archive3',
'astorage-client',
'backup-api',
'disk-manager',
'dms',
'enforcement',
'http',
'mms',
'mms-live-upgrade',
'panic',
'recovery-assistant',
'tol-activity',
'tol-inspector',
'zmq_client_connections',
'zmq_client_sessions'
]
AMS_CHANNELS = [
'alerts',
'ams',
'backup-assistant',
'backup_notifications',
'centralized-live-upgrade',
'client-activity',
'dml_core',
'dml_dispatcher_perf',
'dms',
'email_service',
'enforcement',
'gxt_engine_requests',
'http',
'panic',
'protection_engine',
'recovery-assistant',
'registry-access',
'server_dispatcher_perf',
'session-manager',
'settings',
'sync_replication',
'sync_replication_performance',
'tol-inspector',
'zmq_server_sessions'
]
LEVELS = {
'UNKNOWN_TRACE': 'debug',
'DEBUG_TRACE': 'debug',
'INFORMATION': 'info',
'WARNING': 'warning',
'ERROR_TRACE': 'error',
'CRITICAL_ERROR': 'error'
}
def is_guid(key):
return bool(RE_UUID.match(key))
def select_machine_by_ip(connection, machine_ip):
pattern = [
('^Is', 'string', 'MachineManagement::Machine'),
('.Info.Role', 'dword', 0), #ROLE_MMS
('.Info.Name^Like', 'string', '%{0}%'.format(machine_ip)),
]
spec = acrort.dml.ViewSpec(pattern=acrort.plain.Unit(flat=pattern))
return connection.dml.select(spec)
def select_machine_by_id(connection, machine_id):
pattern = [
('^Is', 'string', 'MachineManagement::Machine'),
('.ID', 'guid', machine_id)
]
spec = acrort.dml.ViewSpec(pattern=acrort.plain.Unit(flat=pattern))
return connection.dml.select(spec)
def run_get_logging_params(connection, machine_name, machine_id, channels):
for ch in channels:
print("Get parameters for channel '{}':".format(ch), end=" ")
arg = 'level {}'.format(ch)
try:
activity_id = connection.tol.launch_command(
command=LOGGING_CONTROL_COMMAND_ID, target_machine=machine_id, argument=arg)
result = connection.tol.get_result(activity_id, target_machine=machine_id)
print("'{}'".format(LEVELS[result.ref]))
#print("Done with activity {}".format(activity_id))
except acrort.Exception as e:
print("failed: {}".format(e.to_error()))
except Exception as e:
print("failed: {}".format(str(e)))
def run_set_logging_params(connection, machine_name, machine_id, level, channels):
for ch in channels:
arg = 'level {} {}'.format(ch, level)
print("Set parameters: '{}'".format(arg), end=" ")
try:
activity_id = connection.tol.launch_command(
command=LOGGING_CONTROL_COMMAND_ID, target_machine=machine_id, argument=arg)
wait_result = connection.tol.get_result(activity_id, target_machine=machine_id)
print("Done.")
#print("Done with activity {}".format(activity_id))
except acrort.Exception as e:
print("failed: {}".format(e.to_error()))
except Exception as e:
print("failed: {}".format(str(e)))
def run_set_logging_params_on_service(connection, machine_name, level, channels, get):
if get:
run_get_logging_params(connection, machine_name, None, channels)
else:
run_set_logging_params(connection, machine_name, None, level, channels)
def run_set_logging_params_on_agents_using_ams(connection, machines, level, channels, get):
for machine_id in machines:
print('Find machine: {}'.format(machine_id))
if is_guid(machine_id):
machine = select_machine_by_id(connection, machine_id)
else:
machine = select_machine_by_ip(connection, machine_id)
if not machine or len(machine) == 0:
print("There is no machine with ID {}, update logging parameters skipped.".format(machine_id))
elif machine[0].Status.ref == 1:
print("Machine with ID {} is offline, update logging parameters skipped.".format(machine_id))
else:
if get:
print("Get logging for {} {} {}".format(machine_id, machine[0].Info.Name.ref, machine[0].ID.ref))
run_get_logging_params(connection, machine_id, machine[0].ID.ref, channels)
else:
print("Set logging for {} {} {}".format(machine_id, machine[0].Info.Name.ref, machine[0].ID.ref))
run_set_logging_params(connection, machine_id, machine[0].ID.ref, level, channels)
def main():
parser = argparse.ArgumentParser(description='Setup logging parameters remotely for Acronis services')
parser.add_argument(
'-c', '--connection',
required=True,
nargs=3,
help='Host to connect to, in form <host> <username> <password>')
parser.add_argument(
'-s', '--service',
required=True,
nargs=1,
help='Services: ams, mms')
parser.add_argument(
'-m', '--machine',
required=False,
nargs=1,
help='Machine to setup logging parameters on, in form <ip address> or <machine guid>')
parser.add_argument(
'-ch', '--channel',
required=False,
nargs='*',
help='Supported AMS channels: \n' + '\n'.join(AMS_CHANNELS) + \
'Supported MMS channels: \n' + '\n'.join(MMS_CHANNELS))
parser.add_argument(
'-l', '--level',
required=False,
nargs=1,
help='Set logging level. Supported levels: debug, info, warning')
args = parser.parse_args()
service = args.service[0]
if service not in ['ams', 'mms']:
print("Service not supported: {}".format(service))
return
host = args.connection[0]
creds = (args.connection[1], args.connection[2])
print("Connecting to {} {} ...".format(service, host), end=" ")
connection = acrort.connectivity.Connection(service, host, creds)
print("Done.")
level = args.level[0] if args.level else ''
channels = args.channel if args.channel else MMS_CHANNELS
get = False if args.level else True
if service == 'mms' or (service == 'ams' and not args.machine):
if service == 'ams':
channels = args.channel if args.channel else AMS_CHANNELS
run_set_logging_params_on_service(connection, host, level, channels, get)
else:
run_set_logging_params_on_agents_using_ams(connection, args.machine, level, channels, get)
if __name__ == '__main__':
exit(acrobind.interruptable_safe_execute(main))
|