def run(self, context, args, kwargs, opargs): obj = self.get_relative_namespace(context) nss = obj.namespaces() cmds = obj.commands() # Only display builtin items if in the RootNamespace outseq = None if obj.__class__.__name__ == 'RootNamespace': outseq = Sequence( _("Global commands:"), sorted(['/', '..', '-'] + list(context.ml.base_builtin_commands.keys()))) outseq += Sequence(_("Filtering commands:"), sorted(list(context.ml.pipe_commands.keys()))) ns_seq = Sequence( _("Current namespace items:"), sorted(list(cmds)) + [ add_tty_formatting(context, quote(ns.get_name())) for ns in sorted(nss, key=lambda i: str(i.get_name())) ]) if outseq is not None: outseq += ns_seq else: outseq = ns_seq return outseq
def run(self, context, args, kwargs, opargs): if len(args) != 1 and 'name' not in kwargs: raise CommandException("Please specify the image name") name = kwargs.get('name') or args[0] readme = context.call_sync('docker.image.readme', name) if readme: return Sequence(readme) else: return Sequence("Image {0} readme does not exist".format(args[0]))
def run(self, context, args, kwargs, opargs): # Enclose ipv6 urls in '[]' according to ipv6 url spec my_ips = [ wrap_address(ip) for ip in context.call_sync('network.config.get_my_ips', timeout=60) ] my_protocols = context.call_sync('system.ui.get_config', timeout=60) urls = [] for proto in my_protocols['webui_protocol']: proto_port = my_protocols['webui_{0}_port'.format(proto.lower())] if proto_port is not None: if proto_port in [80, 443]: for x in my_ips: urls.append( {'url': '{0}://{1}'.format(proto.lower(), x)}) else: for x in my_ips: urls.append({ 'url': '{0}://{1}:{2}'.format(proto.lower(), x, proto_port) }) return Sequence( _("You may try the following URLs to access the web user interface:" ), Table(urls, [Table.Column(_('URLs (url)'), 'url')]))
def run(self, context, args, kwargs, opargs): if not args and not kwargs: raise CommandException( _("Command invalidate_token requires more arguments.")) if len(args) > 1: raise CommandException(_("Wrong syntax for invalidate_token.")) if len(args) == 1 and not kwargs.get('token'): kwargs['token'] = args.pop(0) if 'token' not in kwargs: raise CommandException(_('Please specify a valid token')) else: token = str(kwargs.pop('token')) try: if token.index('*') < 2: raise CommandException( _('You have to enter at least first two digits of a valid token.' )) except ValueError: pass match = first_or_default( lambda c: c['code'][:2] == token[:2], context.call_sync('peer.freenas.get_auth_codes')) if not match: return Sequence( 'No matching code found. You might have entered wrong token, or it has already expired.' ) else: if match['code'] == token: token = match context.call_sync('peer.freenas.invalidate_code', token)
def run(self, context, args, kwargs, opargs): if len(kwargs) > 0: raise CommandException(_("Invalid syntax {0}. type builtin or 'builtin <command>'".format(kwargs))) if len(args) > 1: raise CommandException(_("Invalid syntax {0}. type builtin or 'builtin <command>'".format(kwargs))) if len(args) == 0: builtin_cmd_dict_list = [ {"cmd": "/", "description": "Go to the root namespace"}, {"cmd": "..", "description": "Go up one namespace"}, {"cmd": "-", "description": "Go back to previous namespace"} ] filtering_cmd_dict_list = [] for key, value in context.ml.builtin_commands.items(): if hasattr(value, 'description') and value.description is not None: description = value.description else: description = key builtin_cmd_dict = { 'cmd': key, 'description': description, } if key in context.ml.pipe_commands: filtering_cmd_dict_list.append(builtin_cmd_dict) else: builtin_cmd_dict_list.append(builtin_cmd_dict) builtin_cmd_dict_list = sorted(builtin_cmd_dict_list, key=lambda k: k['cmd']) filtering_cmd_dict_list = sorted(filtering_cmd_dict_list, key=lambda k: k['cmd']) output_seq = Sequence() output_seq.append( Table(builtin_cmd_dict_list, [ Table.Column('Global Command', 'cmd', ValueType.STRING), Table.Column('Description', 'description', ValueType.STRING) ])) output_seq.append( Table(filtering_cmd_dict_list, [ Table.Column('Filter Command', 'cmd', ValueType.STRING), Table.Column('Description', 'description', ValueType.STRING) ])) return output_seq if len(args) == 1: command_name = args[0] default_cmd_help = { "/": "Go to the root namespace", "..": "Go up one namespace", "-": "Go back to previous namespace" } if command_name in default_cmd_help.keys(): print(default_cmd_help[command_name]) elif command_name in context.ml.builtin_commands.keys(): return inspect.getdoc(context.ml.builtin_commands[command_name]) + '\n' else: raise CommandException(_("Invalid syntax: '{0}' is not a valid CLI builtin.".format(command_name)))
def eval_(ast): if isinstance(ast, str): ast = parse(ast, '<eval>') if isinstance(ast, Quote): ast = ast.body return Sequence(*config.instance.eval(ast))
def run(self, context, args, kwargs, opargs): return Sequence( _("These are the active ips from all the configured network interfaces" ), Table([{ 'ip': x } for x in context.call_sync('network.config.get_my_ips')], [Table.Column(_("IP Addresses (ip)"), 'ip')]))
def run(self, context, args, kwargs, opargs): if len(args) < 1 or not isinstance(args[0], Quote): raise CommandException("Provide code fragment to evaluate") start = datetime.now() result = context.eval(args[0].body) end = datetime.now() msg = "Execution time: {0} seconds".format((end - start).total_seconds()) return Sequence(*(result + [msg]))
def run(self, context, args, kwargs, opargs): if self.parent.entity.get('providers_presence', 'NONE') != 'ALL': raise CommandException('You must unlock your volume first') path = kwargs.get('path', None) if path is None: raise CommandException('You must provide an output path for a backup file') name = self.parent.entity['id'] result = context.call_task_sync('volume.keys.backup', name, path) return Sequence("Backup password:", str(result['result']))
def run(self, context, args, kwargs, opargs): result = context.call_task_sync('backup.query', self.parent.entity['id']) manifest = result['result'] return Sequence( Object( Object.Item('Hostname', 'hostname', manifest['hostname']), Object.Item('Dataset', 'dataset', manifest['dataset']), ), Table(manifest['snapshots'], [ Table.Column('Snapshot name', 'name', ValueType.STRING), Table.Column('Incremental', 'incremental', ValueType.BOOLEAN), Table.Column('Created at', 'created_at', ValueType.TIME) ]))
def run(sef, context, args, kwargs, opargs): if len(args) == 0: return "" else: echo_seq = [] for i, item in enumerate(args): if not ( isinstance(item, (Table, output_obj, dict, Sequence, list)) or i == 0 or isinstance(args[i - 1], (Table, output_obj, dict, Sequence, list)) ): echo_seq[-1] = ' '.join([echo_seq[-1], str(item)]) elif isinstance(item, list): echo_seq.append(', '.join(item)) else: echo_seq.append(item) return Sequence(*echo_seq)
def run(self, context, args, kwargs, opargs): result = context.call_task_sync('backup.query', self.parent.entity['id']) if result['state'] != 'FINISHED': raise CommandException('Failed to query backup: {0}'.format( q.get(result, 'error.message'))) manifest = result['result'] return Sequence( Object( Object.Item('Hostname', 'hostname', manifest['hostname']), Object.Item('Dataset', 'dataset', manifest['dataset']), ), Table(manifest['snapshots'], [ Table.Column('Snapshot name', 'name', ValueType.STRING), Table.Column('Incremental', 'incremental', ValueType.BOOLEAN), Table.Column('Created at', 'created_at', ValueType.TIME) ]))
def run(self, context, args, kwargs, opargs): if not kwargs.get('username') or not kwargs.get('password'): raise CommandException( 'You have to provide a bug tracking system password and username in order to submit a ticket' ) if not kwargs.get('subject'): raise CommandException( _('You have to provide a subject for a ticket')) if not kwargs.get('description'): raise CommandException( _('You have to provide a description for a ticket')) if not kwargs.get('type'): raise CommandException( _('You have to provide a type of the ticket: bug/feature')) if not kwargs.get('category'): raise CommandException( _('You have to provide a category for the ticket')) if not kwargs.get('attach_debug_data'): kwargs['debug'] = True else: kwargs['debug'] = True if kwargs.pop( 'attach_debug_data') == 'yes' else False if kwargs.get('attachments') and isinstance(kwargs['attachments'], str): kwargs['attachments'] = [kwargs['attachments']] if not self.ticket_categories: self.ticket_categories.update( context.call_sync('support.categories', kwargs['username'], kwargs['password'])) kwargs['category'] = self.ticket_categories[kwargs['category']] ticket_result = context.call_task_sync('support.submit', kwargs) if ticket_result.get( 'result') and ticket_result['result'][0] is not None: return Sequence('Submitted ticket number:{0}. {1}'.format( ticket_result['result'][0], ticket_result['result'][1]))
def run(self, context, args, kwargs, opargs, filtering=None): if len(args) != 0: raise CommandException('Wrong arguments count') self.parent.load() values = Object() entity = self.parent.entity for mapping in self.parent.property_mappings: if not mapping.get: continue if mapping.ns: continue if mapping.condition is not None: if not mapping.condition(entity): continue if mapping.set and mapping.is_usersetable( entity) and self.parent.allow_edit: editable = True else: editable = False value = Object.Item( mapping.descr, mapping.name, mapping.do_get(entity), mapping.type, editable, ) values.append(value) if self.parent.leaf_entity: leaf_res = ListCommand(self.parent).run( context, args, kwargs, opargs, filtering) return Sequence( values, "-- {0} --".format(self.parent.leaf_ns.description), leaf_res) return values
def run(self, context, args, kwargs, opargs): incremental = read_value(kwargs.pop('incrementasl', 'yes'), ValueType.BOOLEAN) snapshot = read_value(kwargs.pop('snapshot', 'yes'), ValueType.BOOLEAN) dry_run = read_value(kwargs.pop('dry_run', 'no'), ValueType.BOOLEAN) if dry_run: def describe(row): if row['type'] == 'SEND_STREAM': return '{localfs}@{snapshot} -> {remotefs}@{snapshot} ({incr})'.format( incr='incremental' if row.get('incremental') else 'full', **row) if row['type'] == 'DELETE_SNAPSHOTS': return 'reinitialize remote dataset {remotefs}'.format( **row) if row['type'] == 'DELETE_DATASET': return 'delete remote dataset {remotefs} (because it has been deleted locally)'.format( **row) result = context.call_task_sync('backup.sync', self.parent.entity['id'], snapshot, True) if result['state'] != 'FINISHED': raise CommandException('Failed to query backup: {0}'.format( q.get(result, 'error.message'))) return Sequence( Table(result['result'], [ Table.Column('Action type', 'type', ValueType.STRING), Table.Column('Description', describe, ValueType.STRING) ]), "Estimated backup stream size: {0}".format( format_value( sum(a.get('send_size', 0) for a in result['result']), ValueType.SIZE))) else: tid = context.submit_task('backup.sync', self.parent.entity['id'], snapshot) return TaskPromise(context, tid)
def run(self, context, args, kwargs, opargs): namespaces = self.parent.namespaces() output_dict = {} output = Sequence() hw_info_dict = context.call_sync('system.info.hardware') parent_commands = self.parent.commands() def get_show(obj): if isinstance(obj, ConfigNamespace): obj.load() commands = obj.commands() if 'show' in commands: instance = commands['show'] return instance.run(context, '', '', '') else: raise CommandException( _("Namespace {0} does not have 'show' command".format( obj.name))) def append_out(key): if key == 'ipmi' or len(output_dict[key]) > 0: output.append("\nData about {0}:".format(key)) output.append(output_dict[key]) for namespace in namespaces: output_dict[namespace.name] = get_show(namespace) append_out(namespace.name) output_dict['memory'] = Object( Object.Item("Memory size", 'memory_size', hw_info_dict['memory_size'], vt=ValueType.SIZE)) output_dict['cpu'] = parent_commands['cpu'].run(context, '', '', '') append_out('memory') append_out('cpu') return output
def run(self, context, args, kwargs, opargs): incremental = kwargs.pop('incremental', False) snapshot = kwargs.pop('snapshot', False) dry_run = kwargs.pop('dry_run', False) if dry_run: def describe(row): if row['type'] == 'SEND_STREAM': return '{localfs}@{snapshot} -> {remotefs}@{snapshot} ({incr})'.format( incr='incremental' if row.get('incremental') else 'full', **row) if row['type'] == 'DELETE_SNAPSHOTS': return 'reinitialize remote dataset {remotefs}'.format( **row) if row['type'] == 'DELETE_DATASET': return 'delete remote dataset {remotefs} (because it has been deleted locally)'.format( **row) result = context.call_task_sync('backup.sync', self.parent.entity['id'], snapshot, incremental, True) return Sequence( Table(result['result'], [ Table.Column('Action type', 'type', ValueType.STRING), Table.Column('Description', describe, ValueType.STRING) ]), "Estimated backup stream size: {0}".format( format_value( sum(a.get('send_size', 0) for a in result['result']), ValueType.SIZE))) else: context.submit_task('backup.sync', self.parent.entity['id'], incremental, snapshot)
def run(self, context, args, kwargs, opargs): return Sequence(*context.call_sync('shell.get_shells'))
def run(self, context, args, kwargs, opargs): remote = kwargs.pop('remote') remote_dataset = kwargs.pop('remote_dataset') dry_run = kwargs.pop('dry_run', False) recursive = kwargs.pop('recursive', False) follow_delete = kwargs.pop('follow_delete', False) compress = kwargs.pop('compress', None) encrypt = kwargs.pop('encrypt', None) throttle = kwargs.pop('throttle', None) transport_plugins = [] if compress: if compress not in ['fast', 'default', 'best']: raise CommandException('Compression level must be selected as one of: fast, default, best') transport_plugins.append({ 'name': 'compress', 'level': compress.upper() }) if throttle: if not isinstance(throttle, int): raise CommandException('Throttle must be a number representing maximum transfer per second') transport_plugins.append({ 'name': 'throttle', 'buffer_size': throttle }) if encrypt: if encrypt not in ['AES128', 'AES192', 'AES256']: raise CommandException('Encryption type must be selected as one of: AES128, AES192, AES256') transport_plugins.append({ 'name': 'encrypt', 'type': encrypt }) args = ( 'replication.replicate_dataset', self.parent.entity['name'], { 'remote': remote, 'remote_dataset': remote_dataset, 'recursive': recursive, 'followdelete': follow_delete }, transport_plugins, dry_run ) if dry_run: def describe(row): if row['type'] == 'SEND_STREAM': return '{localfs}@{snapshot} -> {remotefs}@{snapshot} ({incr})'.format( incr='incremental' if row.get('incremental') else 'full', **row ) if row['type'] == 'DELETE_SNAPSHOTS': return 'reinitialize remote dataset {remotefs}'.format(**row) if row['type'] == 'DELETE_DATASET': return 'delete remote dataset {remotefs} (because it has been deleted locally)'.format(**row) result = context.call_task_sync(*args) return Sequence( Table( result['result'], [ Table.Column('Action type', 'type', ValueType.STRING), Table.Column('Description', describe, ValueType.STRING) ] ), "Estimated replication stream size: {0}".format(format_value( result[1], ValueType.SIZE) ) ) else: context.submit_task(*args)
def run(self, context, args, kwargs, opargs): return Sequence('One time authentication code:', context.call_sync('peer.freenas.create_auth_code'))
def run(self, context, args, kwargs, opargs, filtering=None): if self.parent.entity['template'].get('readme'): return Sequence(self.parent.entity['template']['readme']) else: return Sequence("Selected template does not have readme entry")
def run(self, context, args, kwargs, opargs): ns = self.get_relative_namespace(context) arg = args[:] obj = context.ml.get_relative_object(ns, args) if len(arg) > 0: if "/" in arg: return textwrap.dedent("""\ Usage: / / <namespace> / <namespace> <command> Allows you to navigate or execute commands starting from the root namespace""" ) elif ".." in arg: return textwrap.dedent("""\ Usage: .. Goes up one level of namespace""") elif "-" in arg: return textwrap.dedent("""\ Usage: - Goes back to the previous namespace""") elif "properties" in arg: # If the namespace has properties, display a list of the available properties if hasattr(obj, 'property_mappings'): prop_dict_list = [] for prop in obj.property_mappings: if prop.condition and hasattr( obj, 'entity') and not prop.condition(obj.entity): continue if prop.usage: prop_usage = prop.usage else: if prop.enum: enum_values = prop.enum(obj) if callable( prop.enum) else prop.enum prop_type = "enum " + str(enum_values) else: prop_type = str( prop.type).split('ValueType.')[-1].lower() if not prop.set: prop_usage = "{0}, read_only {1} value".format( prop.descr, prop_type) else: prop_usage = "{0}, accepts {1} values".format( prop.descr, prop_type) prop_dict = { 'propname': prop.name, 'propusage': ' '.join(prop_usage.split()) } prop_dict_list.append(prop_dict) if len(prop_dict_list) > 0: return Table(prop_dict_list, [ Table.Column('Property', 'propname', ValueType.STRING), Table.Column('Usage', 'propusage', ValueType.STRING), ]) if isinstance( obj, Command) or isinstance(obj, FilteringCommand) and obj.__doc__: command_name = obj.__class__.__name__ if (hasattr(obj, 'parent') and hasattr(obj.parent, 'localdoc') and command_name in obj.parent.localdoc.keys()): return textwrap.dedent( obj.parent.localdoc[command_name]) + "\n" else: if inspect.getdoc(obj) is not None: return inspect.getdoc(obj) + "\n" else: return _("No help exists for '{0}'.\n".format(arg[0])) if isinstance(obj, Namespace): # First listing the Current Namespace's commands cmd_dict_list = [] ns_cmds = obj.commands() for key, value in ns_cmds.items(): if hasattr(value, 'description') and value.description is not None: description = value.description else: description = obj.get_name() value_description = re.sub('<entity>', str(obj.get_name()), description) cmd_dict = { 'cmd': key, 'description': value_description, } cmd_dict_list.append(cmd_dict) # Then listing the namespaces available from this namespace for nss in obj.namespaces(): if not isinstance(nss, SingleItemNamespace): if hasattr(nss, 'description') and nss.description is not None: description = nss.description else: description = nss.name namespace_dict = { 'cmd': nss.name, 'description': description, } cmd_dict_list.append(namespace_dict) cmd_dict_list = sorted(cmd_dict_list, key=lambda k: k['cmd']) # Finally listing the builtin cmds builtin_cmd_dict_list = [{ "cmd": "/", "description": "Go to the root namespace" }, { "cmd": "..", "description": "Go up one namespace" }, { "cmd": "-", "description": "Go back to previous namespace" }] filtering_cmd_dict_list = [] for key, value in context.ml.builtin_commands.items(): if hasattr(value, 'description') and value.description is not None: description = value.description else: description = key builtin_cmd_dict = { 'cmd': key, 'description': description, } if key in context.ml.pipe_commands: filtering_cmd_dict_list.append(builtin_cmd_dict) else: builtin_cmd_dict_list.append(builtin_cmd_dict) builtin_cmd_dict_list = sorted(builtin_cmd_dict_list, key=lambda k: k['cmd']) filtering_cmd_dict_list = sorted(filtering_cmd_dict_list, key=lambda k: k['cmd']) # Finally printing all this out in unix `LESS(1)` pager style output_seq = Sequence() if cmd_dict_list: output_seq.append( Table(cmd_dict_list, [ Table.Column('Command', 'cmd', ValueType.STRING), Table.Column('Description', 'description', ValueType.STRING) ])) # Only display the help on builtin commands if in the RootNamespace if obj.__class__.__name__ == 'RootNamespace': output_seq.append( Table(builtin_cmd_dict_list, [ Table.Column('Global Command', 'cmd', ValueType.STRING), Table.Column('Description', 'description', ValueType.STRING) ])) output_seq.append( Table(filtering_cmd_dict_list, [ Table.Column('Filter Command', 'cmd', ValueType.STRING), Table.Column('Description', 'description', ValueType.STRING) ])) help_message = "" if obj.__doc__: help_message = inspect.getdoc(obj) elif isinstance(obj, SingleItemNamespace): help_message = obj.entity_doc() if help_message != "": output_seq.append("") output_seq.append(help_message) output_seq.append("") return output_seq
def rpc(name, *args): return Sequence(*config.instance.call_sync(name, *args))
def run(self, context, args, kwargs, opargs, filtering=None): return Sequence(self.parent.entity[self.key].get('readme', 'Selected template does not have readme entry'))
def run(self, context, args, kwargs, opargs): root_namespaces = context.root_ns.namespaces() output_dict = {} output = Sequence() def get_show(obj): if isinstance(obj, ConfigNamespace): obj.load() commands = obj.commands() if 'show' in commands: instance = commands['show'] return instance.run(context, '', '', '') else: raise CommandException(_("Namespace {0} does not have 'show' command".format(obj.name))) def append_out(key): if len(output_dict[key]) > 0: output.append("\nData about {0}:".format(key)) output.append(output_dict[key]) for namespace in root_namespaces: if namespace.name in ('system', 'service', 'vm', 'disk', 'share', 'volume'): output_dict[namespace.name] = get_show(namespace) elif namespace.name == 'account': for account_nested_namespace in namespace.namespaces(): if account_nested_namespace.name == 'directoryservice': for nested_namespace in account_nested_namespace.namespaces(): if nested_namespace.name == 'directories': output_dict[nested_namespace.name] = get_show(nested_namespace) if nested_namespace.name == 'kerberos': for kerberos_namespace in nested_namespace.namespaces(): if kerberos_namespace.name == 'keytab' or \ kerberos_namespace.name == 'realm': output_dict[kerberos_namespace.name] = get_show(kerberos_namespace) elif namespace.name == 'network': for nested_namespace in namespace.namespaces(): if nested_namespace.name == 'config' or \ nested_namespace.name == 'host' or \ nested_namespace.name == 'interface' or \ nested_namespace.name == 'route': output_dict[nested_namespace.name] = get_show(nested_namespace) elif namespace.name == 'boot': for nested_namespace in namespace.namespaces(): if nested_namespace.name == 'environment': output_dict[nested_namespace.name] = get_show(nested_namespace) hw_info_dict = context.call_sync('system.info.hardware') output_dict['hardware'] = Object( Object.Item("CPU Clockrate", 'cpu_clockrate', hw_info_dict['cpu_clockrate']), Object.Item("CPU Model", 'cpu_model', hw_info_dict['cpu_model']), Object.Item("CPU Cores", 'cpu_cores', hw_info_dict['cpu_cores']), Object.Item("Memory size", 'memory_size', hw_info_dict['memory_size'], vt=ValueType.SIZE), Object.Item("VM Guest", 'vm_guest', hw_info_dict['vm_guest']) ) ver_info = context.call_sync('system.info.version') output.append("System version: {0}".format(ver_info)) output.append("\n\nStatus of machine:") append_out('system') append_out('hardware') output.append("\n\nStatus of boot environment:") append_out('environment') output.append("\n\nStatus of networking:") append_out('config') append_out('host') append_out('interface') append_out('route') output.append("\n\nStatus of storage:") append_out('volume') append_out('disk') append_out('share') if len(output_dict['vm']) > 0: output.append("\n\nStatus of VMs:") append_out('vm') output.append("\n\nStatus of services:") append_out('service') if len(output_dict['directories']) > 0: output.append("\n\nStatus of Active Directory:") append_out('directories') if len(output_dict['keytab']) > 0 or len(output_dict['realm']) > 0: output.append("\n\nStatus of Kerberos:") append_out('keytab') append_out('realm') return output
def run(self, context, args, kwargs, opargs): return Sequence(*context.call_sync('system.general.timezones'))
def run(self, context, args, kwargs, opargs): result = context.call_task_sync('volume.export', self.parent.name) if result.get('result', None) is not None: return Sequence("Detached volume {0} was encrypted!".format(args[0]), "You must save user key listed below to be able to import volume in the future", str(result['result']))