import acrort
import acrobind
import shlex
class GtobOptions:
def __init__(self, *, request_url=False):
self.stop_on_error = False
self.request_url = request_url
def to_unit(self):
result = acrort.plain.Unit()
if self.stop_on_error:
result = result.consolidate({'StopOnError': True})
if self.request_url:
result = result.consolidate({'ResolveHumanUrl': True})
return result
class GtobCommandProcessor(acrobind.CommandShell):
def __init__(self, connection, printer, config):
acrobind.CommandShell.__init__(self, connection=connection, printer=printer, config=config)
self._projection = None
self._tree = connection.gtob.open_global_tree()
self._current_item = self._tree.root
def do_reset(self, arg):
"""Reset global tree to its default state."""
tree = self.connection.gtob.open_global_tree()
self._projection = None
self._tree = tree
self._current_item = self._tree.root
self.print_browsing_details()
def _open_logon_profile(self):
return self.connection.access.open_logon_profile()
def _open_logon_proxy_profile(self):
host_id = self._current_item.attributes.HostID.ref
return self.connection.access.open_logon_profile(target_machine=host_id)
def _open_current_profile(self):
return self.connection.access.open_user_profile()
def _open_delegated_profile(self):
host_id = self._current_item.attributes.HostID.ref
return self.connection.access.open_user_profile(target_machine=host_id)
def preloop(self):
self.print_browsing_details()
def print_browsing_details(self):
self.printer.write("Hierarchy root: {}".format(self._tree.root.key))
def item_to_display_name(self, item):
return item.display_name
def item_to_name(self, item):
return item.name
def item_to_key(self, item):
return item.key
def print_items(self, items, transform_handler):
i = 0
for item in items:
i = i + 1
msg = transform_handler(item)
self.printer.write("{:<4} ...... {}".format(i, msg))
def do_jump(self, arg):
"""Jump to the global tree inside managed machine assuming that
current item has property 'HostID' property in attributes.
"""
host_id = self._current_item.attributes.HostID.ref
tree = self.connection.gtob.open_global_tree(projection=self._projection, target_machine=host_id)
self._tree = tree
self._current_item = tree.root
self.print_browsing_details()
def do_stat(self, arg):
"""List details about current item."""
self.printer.write(self._current_item)
def do_top(self, arg):
"""Change current item to hierarchy root."""
self._current_item = self._tree.root
def do_cd(self, arg):
"""Change current item. Default credentials is used if possible.
| Synopsis:
| cd ..
| cd index
|
| Description:
| .. - change current item on parent.
| index - change current item on child by its index
"""
options = GtobOptions()
if arg == '..':
parents = self._current_item.parents
if not parents:
acrort.common.make_logic_error("Current item {} doesn't have any parent.".format(self._current_item.key)).throw()
subject = self._tree.resolve_item(key=parents[0], options=options)
else:
items = self._tree.select_children(key=self._current_item.key, options=options)
idx = int(arg) - 1
subject = items[idx]
subject.throw_if_error_item()
self._current_item = subject
def do_ls(self, arg):
"""List child or parent items in specified mode. Default credentials is used if possible.
| Synopsis:
| ls [d|k|n] [e]
|
| Description:
| d - print display names, used by default
| k - print keys
| n - print names
| e - turn on 'StopOnError' mode
"""
options = GtobOptions()
list_method = self.item_to_display_name
args = shlex.split(arg)
if 'd' in args:
list_method = self.item_to_display_name
if 'k' in args:
list_method = self.item_to_key
if 'n' in args:
list_method = self.item_to_name
if 'e' in args:
options.stop_on_error = True
items = self._tree.select_children(key=self._current_item.key, options=options)
if items:
items[0].throw_if_error_item()
self.print_items(items, list_method)
else:
self.printer.write("No items.")
def do_resolve_key(self, arg):
"""Resolve specified item key. Default credentials is used if possible.
| Synopsis:
| resolve-key <key>
"""
options = GtobOptions()
subject = self._tree.resolve_item(key=arg, options=options)
subject.throw_if_error_item()
self._current_item = subject
def do_resolve(self, arg):
"""Resolve item by protocol and human path. Default credentials is used if possible.
| Synopsis:
| resolve <protocol> <human path>
"""
protocol, path = shlex.split(arg)
options = GtobOptions()
subject = self._tree.resolve_item(url=acrort.gtob.ItemUrl(protocol=protocol, path=path), options=options)
subject.throw_if_error_item()
self._current_item = subject
def do_resolve_url(self, arg):
"""Resolve specified item by its URL. Default credentials is used if possible.
| Synopsis:
| resolve-url <url>
"""
url = shlex.split(arg)[0]
key = acrort.gtob.ItemKey(url, 'url')
self.do_resolve_key(key)
def do_url(self, arg):
"""List URL for current item."""
options = GtobOptions(request_url=True)
subject = self._tree.resolve_item(key=self._current_item.key, options=options)
subject.throw_if_error_item()
self.printer.write(subject.attributes.HumanUrl.ref)
def do_human(self, arg):
"""List all human paths supported by current item."""
options = GtobOptions()
url_list = self._tree.describe_item(key=self._current_item.key, options=options)
if not url_list:
self.printer.write("No human paths are supported by current item.")
return
for url in url_list:
self.printer.write("protocol='{}', path='{}'".format(url.protocol, url.path))
def do_credtmp(self, arg):
"""List temp credentials in the current logon session."""
profile = self._open_logon_profile()
accounts = profile.select()
if not accounts:
self.printer.write("There are no temp accounts in the logon profile.")
return
for account in accounts:
self.printer.write(account)
def do_credtmp_set(self, arg):
"""Set temp credentials for specified resource in the current logon session.
| Synopsis:
| credtmp-set <resource-type> <resource-address> <username> <password>
"""
resource_type, resource_address, user_name, password = shlex.split(arg)
profile = self._open_logon_profile()
profile.add_account(resource_type=resource_type, resource_address=resource_address, user_name=user_name, password=password)
def do_credtmp_reset(self, arg):
"""Reset temp credentials for specified resource in the current logon session.
| Synopsis:
| credtmp-reset <resource-type> <resource-address>
"""
resource_type, resource_address = shlex.split(arg)
profile = self._open_logon_profile()
profile.delete_account(resource_type=resource_type, resource_address=resource_address)
def do_credtmp_reset_all(self, arg):
"""Reset credentials for all resources in the current logon session."""
profile = self._open_logon_profile()
profile.clear()
def do_credtmp_injected(self, arg):
"""List credentials injected to specified machine to the proxy-logon session."""
profile = self._open_logon_proxy_profile()
accounts = profile.select()
if not accounts:
self.printer.write("There are no temp accounts in the proxy-logon profile.")
return
for account in accounts:
self.printer.write(account)
def do_credtmp_inject(self, arg):
"""Inject credentials to specified machine in the proxy-logon session.
| Synopsis:
| cred-inject <resource-type> <resource-address> <username> <password>
"""
resource_type, resource_address, user_name, password = shlex.split(arg)
profile = self._open_logon_proxy_profile()
profile.add_account(resource_type=resource_type, resource_address=resource_address, user_name=user_name, password=password)
def do_credtmp_revoke(self, arg):
"""Revoke credentials in specified machine from the proxy-logon session.
| Synopsis:
| cred-revoke <resource-type> <resource-address>
"""
resource_type, resource_address = shlex.split(arg)
profile = self._open_logon_proxy_profile()
profile.delete_account(resource_type=resource_type, resource_address=resource_address)
def do_credtmp_revoke_all(self, arg):
"""Revoke credentials for all resources in specified machine from the proxy-logon session."""
profile = self._open_logon_proxy_profile()
profile.clear()
def do_cred(self, arg):
"""List credentials for current user profile."""
profile = self._open_current_profile()
accounts = profile.select()
if not accounts:
self.printer.write("There are no accounts in the current user profile.")
return
for account in accounts:
self.printer.write(account)
def do_cred_set(self, arg):
"""Set credentials for specified resource in the current user profile.
| Synopsis:
| cred-set <resource-type> <resource-address> <username> <password>
"""
resource_type, resource_address, user_name, password = shlex.split(arg)
profile = self._open_current_profile()
profile.add_account(resource_type=resource_type, resource_address=resource_address, user_name=user_name, password=password)
def do_cred_reset(self, arg):
"""Reset credentials for specified resource in the current user profile.
| Synopsis:
| cred-reset <resource-type> <resource-address>
"""
resource_type, resource_address = shlex.split(arg)
profile = self._open_current_profile()
profile.delete_account(resource_type=resource_type, resource_address=resource_address)
def do_cred_reset_all(self, arg):
"""Reset credentials for all resources in the current user profile."""
profile = self._open_current_profile()
profile.clear()
def do_cred_injected(self, arg):
"""List credentials for the current user profile injected to specified machine."""
profile = self._open_delegated_profile()
accounts = profile.select()
if not accounts:
self.printer.write("There is no injected accounts.")
return
for account in accounts:
self.printer.write(account)
def do_cred_inject(self, arg):
"""Inject credentials to specified machine in the current user proxy-profile.
| Synopsis:
| cred-inject <resource-type> <resource-address> <username> <password>
"""
resource_type, resource_address, user_name, password = shlex.split(arg)
profile = self._open_delegated_profile()
profile.add_account(resource_type=resource_type, resource_address=resource_address, user_name=user_name, password=password)
def do_cred_revoke(self, arg):
"""Revoke credentials in specified machine from the current user proxy-profile.
| Synopsis:
| cred-revoke <resource-type> <resource-address>
"""
resource_type, resource_address = shlex.split(arg)
profile = self._open_delegated_profile()
profile.delete_account(resource_type=resource_type, resource_address=resource_address)
def do_cred_revoke_all(self, arg):
"""Revoke credentials for all resources in specified machine from the current user proxy-profile."""
profile = self._open_delegated_profile()
profile.clear()
def do_types_list(self, arg):
"""List names for known item types."""
for type_object in self._tree.types:
self.printer.write(" {}".format(type_object.type_id))
def do_ext(self, arg):
"""List extensions of specified item type. Type extensions of current item is listed by default.
| Synopsis:
| ext
| ext <type-name>
"""
subject = arg if arg else self._current_item.key.type_id
for item_type in filter(lambda t: t.type_id == subject, self._tree.types):
self.printer.write(item_type.extensions)
return
acrort.common.make_logic_error("Unknown type name '{}' is given.".format(subject)).throw()
def do_types_like(self, arg):
"""List details about all types matching up the specified pattern(s).
| Synopsis:
| types-like <pattern1> [<pattern2> ...]
"""
matched_types = {}
patterns = shlex.split(arg)
if not patterns:
acrort.common.make_logic_error("At least one argument must be specified for this command.").throw()
for item_type in self._tree.types:
for pattern in patterns:
if item_type.type_id.startswith(pattern):
matched_types[item_type.type_id] = item_type
if not matched_types:
self.printer.write("No item types matching up the specified pattern(s) are found.")
return
for item_type in matched_types.values():
self.printer.write(item_type)
def do_projection_set(self, arg):
"""Set or reset current projection.
| Synopsis:
| projection-set <name>
|
| Description:
| <name> - name of projection to be applied.
| Reset current projection if name is empty.
"""
projection = None
if arg:
projection = arg
tree = self.connection.gtob.open_global_tree(projection=projection)
self._projection = projection
self._tree = tree
self._current_item = tree.root
self.print_browsing_details()
def do_projection(self, arg):
"""List current projection."""
if self._projection is None:
self.printer.write("No projection is currently set.")
else:
self.printer.write("Current projection: {}".format(self._projection))
def main():
parser = acrobind.CommandLineParser()
parser.append_processor(acrobind.ConnectionArgumentsProcessor())
parser.append_processor(acrobind.CommandShellArgumentsProcessor())
parser.append_processor(acrobind.OutputArgumentsProcessor())
parser.append_processor(acrobind.DebugTraceArgumentsProcessor())
try:
config = parser.parse_arguments()
except acrort.Exception as exception:
error = exception.to_error()
return error.to_exit_code()
printer = acrobind.Output(config, end='\n')
conn, error = acrobind.connect_to_service(config, printer=printer)
if conn is None:
return error.to_exit_code()
processor = GtobCommandProcessor(connection=conn, printer=printer, config=config)
return processor.cmdloop()
if __name__ == '__main__':
exit(acrobind.interruptable_safe_execute(main))
|