예제 #1
0
파일: namespace.py 프로젝트: erinix/cli
    def do_set(self, obj, value, check_entity=None):
        if not self.can_set(check_entity if check_entity else obj):
            raise ValueError(_("Property '{0}' is not settable for this entity".format(self.name)))

        value = read_value(value, self.type)

        if self.strict and self.enum:
            enum_val = self.enum(obj) if callable(self.enum) else self.enum
            if self.type == ValueType.SET:
                for e in value:
                    if e not in enum_val:
                        raise ValueError("Invalid value for property '{0}'. Should be one of: {1}".format(
                            self.get_name,
                            '; '.join(format_value(i) for i in enum_val))
                        )
            elif value not in enum_val:
                raise ValueError("Invalid value for property '{0}'. Should be one of: {1}".format(
                    self.get_name,
                    ', '.join(format_value(i) for i in enum_val))
                )

        if isinstance(self.set, collections.Callable):
            self.set(obj, value)
            return

        q.set(obj, self.set, value)
예제 #2
0
파일: namespace.py 프로젝트: zoot/cli
    def do_set(self, obj, value, check_entity=None):
        if not self.can_set(check_entity if check_entity else obj):
            raise ValueError(
                _("Property '{0}' is not settable for this entity".format(
                    self.name)))

        value = read_value(value, self.type)

        if self.strict and (self.enum or (self.complete and self.context)):
            enum_val = self.enum() if callable(
                self.enum) else self.enum or self.complete.choices(
                    self.context, None)
            if self.type == ValueType.SET:
                for e in value:
                    if e not in enum_val:
                        raise ValueError(
                            "Invalid value for property '{0}'. Should be one of: {1}"
                            .format(
                                self.get_name,
                                '; '.join(format_value(i) for i in enum_val)))
            elif value not in enum_val:
                raise ValueError(
                    "Invalid value for property '{0}'. Should be one of: {1}".
                    format(self.get_name,
                           ', '.join(format_value(i) for i in enum_val)))

        if isinstance(self.set, collections.Callable):
            self.set(obj, value)
            return

        q.set(obj, self.set, value)
예제 #3
0
파일: commands.py 프로젝트: mactanxin/cli
    def run(self, context, args, kwargs, opargs):
        if len(kwargs) > 0:
            raise CommandException(
                _("Invalid syntax {0}. For help see 'help <command>'".format(
                    kwargs)))

        if len(args) == 0:
            var_dict_list = []
            for k, v in self.variables.get_all_printable():
                var_dict = {
                    'varname': k,
                    'vardescr': self.variables.variable_doc.get(k, ''),
                    'varvalue': v,
                }
                var_dict_list.append(var_dict)
            return Table(var_dict_list, [
                Table.Column('Variable', 'varname', ValueType.STRING),
                Table.Column('Description', 'vardescr', ValueType.STRING),
                Table.Column('Value', 'varvalue')
            ])

        if len(args) == 1:
            try:
                return format_value(self.variables.variables[args[0]])
            except KeyError:
                raise CommandException(
                    _("No such Environment Variable exists"))
        else:
            raise CommandException(
                _("Invalid syntax {0}. For help see 'help <command>'".format(
                    args)))
예제 #4
0
    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)
예제 #5
0
파일: commands.py 프로젝트: erinix/cli
    def run(self, context, args, kwargs, opargs):
        if len(kwargs) > 0:
            raise CommandException(_("Invalid syntax {0}. For help see 'help <command>'".format(kwargs)))

        if len(args) == 0:
            var_dict_list = []
            for k, v in self.variables.get_all_printable():
                var_dict = {
                    'varname': k,
                    'vardescr': self.variables.variable_doc.get(k, ''),
                    'varvalue': v,
                }
                var_dict_list.append(var_dict)
            return Table(var_dict_list, [
                Table.Column('Variable', 'varname', ValueType.STRING),
                Table.Column('Description', 'vardescr', ValueType.STRING),
                Table.Column('Value', 'varvalue')])

        if len(args) == 1:
            try:
                return format_value(self.variables.variables[args[0]])
            except KeyError:
                raise CommandException(_("No such Environment Variable exists"))
        else:
            raise CommandException(_("Invalid syntax {0}. For help see 'help <command>'".format(args)))
예제 #6
0
파일: system.py 프로젝트: erinix/cli
 def run(self, context, args, kwargs, opargs):
     status_dict = context.call_sync('management.status')
     status_dict['up-since'] = format_value(status_dict['started-at'], vt=ValueType.TIME)
     return Object(
         Object.Item("Number of middleware connections", 'middleware-connections', status_dict['connected-clients']),
         Object.Item("Uptime", 'up-since', status_dict['up-since']),
         Object.Item("Started at", 'started-at', status_dict['started-at'])
     )
예제 #7
0
파일: system.py 프로젝트: mactanxin/cli
 def run(self, context, args, kwargs, opargs):
     status_dict = context.call_sync('management.status')
     status_dict['up-since'] = format_value(status_dict['started-at'], vt=ValueType.TIME)
     return Object(
         Object.Item("Number of middleware connections", 'middleware-connections', status_dict['connected-clients']),
         Object.Item("Uptime", 'up-since', status_dict['up-since']),
         Object.Item("Started at", 'started-at', status_dict['started-at'])
     )
예제 #8
0
    def __init__(self, name, context):
        super(CalendarTasksNamespace, self).__init__(name, context)

        self.query_call = 'calendar_tasks.query'
        self.create_task = 'calendar_tasks.create'
        self.update_task = 'calendar_tasks.update'
        self.delete_task = 'calendar_tasks.delete'

        self.add_property(
            descr='Task id',
            name='id',
            get='id',
            set=None,
            list=True)

        self.add_property(
            descr='Task type',
            name='name',
            get=lambda row: TASK_TYPES_REVERSE[row['name']],
            set=self.set_type,
            list=True)

        self.add_property(
            descr='Task arguments',
            name='args',
            get=lambda row: [format_value(i) for i in row['args']],
            set=None,
            list=True
        )

        self.add_property(
            descr='Coalesce',
            name='coalesce',
            get='schedule.coalesce',
            list=True,
            type=ValueType.BOOLEAN)

        self.add_property(
            descr='Schedule',
            name='schedule',
            get=lambda row: ' '.join([v for v in list(row['schedule'].values()) if isinstance(v, str)]),
            set=None,
            list=True,
            type=ValueType.STRING)

        self.primary_key = self.get_mapping('id')
        self.entity_namespaces = lambda this: [
            ScheduleNamespace('schedule', self.context, this)
        ]

        self.entity_commands = lambda this: {
            'run': RunCommand()
        }
예제 #9
0
    def run(self, context, args, kwargs, opargs):
        remote = kwargs.pop('remote')
        remote_dataset = kwargs.pop('remote_dataset')
        bandwidth = kwargs.pop('bandwidth_limit', None)
        dry_run = kwargs.pop('dry_run', False)
        recursive = kwargs.pop('recursive', False)
        follow_delete = kwargs.pop('follow_delete', False)

        args = (
            'replication.replicate_dataset',
            self.parent.parent.parent.entity['id'],
            self.parent.entity['name'],
            {
                'remote': remote,
                'remote_dataset': remote_dataset,
                'bandwidth_limit': bandwidth,
                'recursive': recursive,
                'followdelete': follow_delete
            },
            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(
                    sum(a.get('send_size', 0) for a in result['result']),
                    ValueType.SIZE)
                )
            )

        else:
            context.submit_task(*args)
예제 #10
0
파일: namespace.py 프로젝트: erinix/cli
        def run(self, context, args, kwargs, opargs):
            if len(args) != 1:
                raise CommandException(_('Wrong arguments count'))

            if not self.parent.has_property(args[0]):
                raise CommandException(_('Property {0} not found'.format(args[0])))

            self.parent.load()

            entity = self.parent.entity
            mapping = self.parent.get_mapping(args[0])
            value = mapping.do_get(entity)
            if value is None:
                return PrintableNone()

            return format_value(value, mapping.type)
예제 #11
0
        def run(self, context, args, kwargs, opargs):
            if len(args) != 1:
                raise CommandException(_('Wrong arguments count'))

            if not self.parent.has_property(args[0]):
                raise CommandException(
                    _('Property {0} not found'.format(args[0])))

            self.parent.load()

            entity = self.parent.entity
            mapping = self.parent.get_mapping(args[0])
            value = mapping.do_get(entity)
            if value is None:
                return PrintableNone()

            return format_value(value, mapping.type)
예제 #12
0
파일: backup.py 프로젝트: zoot/cli
    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)
예제 #13
0
파일: backup.py 프로젝트: erinix/cli
    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)
예제 #14
0
파일: backup.py 프로젝트: caymanowl/cli
    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)
예제 #15
0
파일: volumes.py 프로젝트: caymanowl/cli
    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)
예제 #16
0
파일: calendar.py 프로젝트: 650elx/cli
    def __init__(self, name, context):
        super(CalendarTasksNamespace, self).__init__(name, context)

        self.context = context
        self.query_call = 'calendar_task.query'
        self.create_task = 'calendar_task.create'
        self.update_task = 'calendar_task.update'
        self.delete_task = 'calendar_task.delete'
        self.required_props = ['name', 'type']
        self.localdoc["CreateEntityCommand"] = ("""\
            Usage: create <name> type=<type> <property>=<value>

            Examples: create myscrub type=scrub volume=mypool
                      create myscrub2 type=scrub volume=mypool schedule={"second":0, "minute":0, "hour":3} enabled=true
                      create myupdate type=check_updates send_email=false
                      create mysmart type=smart disks=ada0,ada1,ada2 test_type=short
                      create mycommand type=command username=myuser command="some useful unix command"
                      create mysnapshot type=snapshot volume=mypool dataset=mypool/mydataset recursive=true lifetime=1h

            Create a calendar task.  
    
            If a schedule is not set, all time values will be set to * (run all the time).
            The schedule property takes a key/value pair with keys of second, minute, hour,
            day_of_month, month, day_of_week, week, and year with values of *, */integer, or
            integer.

            Valid types for calendar task creation include: scrub, smart, snapshot, replication and check_updates.
            - A 'scrub' task requires a valid volume passed with the 'volume' property.
            - A 'smart' task requires a list of valid disks for the 'disks' property and a test type for the 'test_type' property that is one of short, long, conveyance or offline.
            - A 'check_updates' task requires a boolean for the 'send_email' property which tells the task whether or not to send an alert by email when a new update is available.
            - A 'snapshot' task requires a valid volume and dataset to snapshot, a boolean for the 'recursive' property, a string value of [0-9]+[hdmy] for lifetime and optionally a boolean for 'replicable' and a string for the 'prefix'.  """)
        self.localdoc["DeleteEntityCommand"] = ("""\
            Usage: delete <name>

            Example: delete mytask

            Deletes a calendar task.""")
        self.entity_localdoc["SetEntityCommand"] = ("""\
            Usage: set <property>=<value>

            Examples: set enabled=true
                      set coalesce=false
                      set schedule={"month":"*/2","day":5}

            Sets a calendar task property.""")

        self.skeleton_entity = {
            'enabled': False,
            'schedule': { 'coalesce': True, 'year': None, 'month': None, 'day': None, 'week': None, 'hour': None, 'minute': None, 'second': None, 'day_of_week': None}
        }

        self.add_property(
            descr='Name',
            name='name',
            get='id',
            usage=_("""\
            Alphanumeric name for the task which becomes read-only after the task
            is created."""),
            set='id',
            list=True)

        self.add_property(
            descr='Type',
            name='type',
            get=lambda row: TASK_TYPES_REVERSE[row['name']],
            usage=_("""\
            Indicates the type of task. Allowable values are scrub, smart,
            snapshot, replication, and check_updates."""),
            set=self.set_type,
            list=True)

        self.add_property(
            descr='Arguments',
            name='args',
            get=lambda row: [format_value(i) for i in row['args']],
            set=None,
            list=False
        )

        self.add_property(
            descr='Coalesce',
            name='coalesce',
            get='schedule.coalesce',
            list=True,
            type=ValueType.BOOLEAN)

        self.add_property(
            descr='Schedule',
            name='schedule',
            get=self.get_schedule,
            set='schedule',
            list=True,
            type=ValueType.DICT)

        self.add_property(
            descr='Timezone',
            name='timezone',
            get='schedule.timezone',
            list=True)

        self.add_property(
            descr='Enabled',
            name='enabled',
            usage=_("""\
            Can be set to yes or no. By default, new tasks are disabled
            until set to yes."""),
            get='enabled',
            list=True,
            type=ValueType.BOOLEAN)

        self.add_property(
            descr='Volume',
            name='volume',
            get=lambda e: self.get_args(e, 'volume'),
            list=False,
            set=self.set_volume,
            condition=lambda e: self.meets_condition(e, 'volume')
        )

        self.add_property(
            descr='Send Email',
            name='send_email',
            get=lambda e: self.get_args(e, 'send_email'),
            list=False,
            set=lambda obj, value: self.set_args(obj, value, 'send_email'),
            type=ValueType.BOOLEAN,
            condition=lambda e: self.meets_condition(e, 'send_email')
        )

        self.add_property(
            descr='Disks',
            name='disks',
            get=lambda e: self.get_args(e, 'disks'),
            list=False,
            type=ValueType.SET,
            set=self.set_disks,
            condition=lambda e: self.meets_condition(e, 'disks')
        )

        self.add_property(
            descr='SMART Test Type',
            name='test_type',
            get=lambda e: self.get_args(e, 'test_type'),
            list=False,
            enum=['short','long','conveyance','offline'],
            set=lambda obj, value: self.set_args(obj, value, 'test_type'),
            condition=lambda e: self.meets_condition(e, 'test_type')
        )

        self.add_property(
            descr='Username',
            name='username',
            get=lambda e: self.get_args(e, 'username'),
            list=False,
            set=self.set_username,
            condition=lambda e: self.meets_condition(e, 'username')
        )

        self.add_property(
            descr='Command',
            name='command',
            get=lambda e: self.get_args(e, 'command'),
            list=False,
            set=lambda obj, value: self.set_args(obj, value, 'command'),
            condition=lambda e: self.meets_condition(e, 'command')
        )

        self.add_property(
            descr='Dataset',
            name='dataset',
            get=lambda e: self.get_args(e, 'dataset'),
            list=False,
            set=lambda obj, value: self.set_args(obj, value, 'dataset'),
            condition=lambda e: self.meets_condition(e, 'dataset')
        )
        
        self.add_property(
            descr='Lifetime',
            name='lifetime',
            get=lambda e: self.get_args(e, 'lifetime'),
            list=False,
            set=lambda obj, value: self.set_args(obj, value, 'lifetime'),
            condition=lambda e: self.meets_condition(e, 'lifetime'),
            type=ValueType.NUMBER
        )

        self.add_property(
            descr='Recursive',
            name='recursive',
            get=lambda e: self.get_args(e, 'recursive'),
            list=False,
            set=lambda obj, value: self.set_args(obj, value, 'recursive'),
            condition=lambda e: self.meets_condition(e, 'recursive'),
            type=ValueType.BOOLEAN
        )

        self.add_property(
            descr='Prefix',
            name='prefix',
            get=lambda e: self.get_args(e, 'prefix'),
            list=False,
            set=lambda obj, value: self.set_args(obj, value, 'prefix'),
            condition=lambda e: self.meets_condition(e, 'prefix')
        )

        self.add_property(
            descr='Replicable',
            name='replicable',
            get=lambda e: self.get_args(e, 'replicable'),
            list=False,
            set=lambda obj, value: self.set_args(obj, value, 'replicable'),
            condition=lambda e: self.meets_condition(e, 'replicable'),
            type=ValueType.BOOLEAN
        )

        self.primary_key = self.get_mapping('name')
        self.entity_namespaces = lambda this: [
            StatusNamespace('status', self.context, this),
            ScheduleNamespace('schedule', self.context, this)
        ]

        self.entity_commands = lambda this: {
            'run': RunCommand(this)
        }
예제 #17
0
    def __init__(self, name, context):
        super(CalendarTasksNamespace, self).__init__(name, context)

        self.context = context
        self.query_call = 'calendar_task.query'
        self.create_task = 'calendar_task.create'
        self.update_task = 'calendar_task.update'
        self.delete_task = 'calendar_task.delete'
        self.required_props = ['name', 'type']
        self.localdoc["CreateEntityCommand"] = ("""\
            Usage: create <name> type=<type> <property>=<value>

            Examples: create myscrub type=scrub volume=mypool
                      create myscrub2 type=scrub volume=mypool schedule={"second":0, "minute":0, "hour":3} enabled=true
                      create myupdate type=check_updates send_email=false
                      create mysmart type=smart disks=ada0,ada1,ada2 test_type=short
                      create mycommand type=command username=myuser command="some useful unix command"
                      create mysnapshot type=snapshot volume=mypool dataset=mypool/mydataset recursive=true lifetime=1h

            Create a calendar task.  
    
            If a schedule is not set, all time values will be set to * (run all the time).
            The schedule property takes a key/value pair with keys of second, minute, hour,
            day_of_month, month, day_of_week, week, and year with values of *, */integer, or
            integer.

            Valid types for calendar task creation include: scrub, smart, snapshot, replication and check_updates.
            - A 'scrub' task requires a valid volume passed with the 'volume' property.
            - A 'smart' task requires a list of valid disks for the 'disks' property and a test type for the 'test_type' property that is one of short, long, conveyance or offline.
            - A 'check_updates' task requires a boolean for the 'send_email' property which tells the task whether or not to send an alert by email when a new update is available.
            - A 'snapshot' task requires a valid volume and dataset to snapshot, a boolean for the 'recursive' property, a string value of [0-9]+[hdmy] for lifetime and optionally a boolean for 'replicable' and a string for the 'prefix'.  """
                                                )
        self.localdoc["DeleteEntityCommand"] = ("""\
            Usage: delete <name>

            Example: delete mytask

            Deletes a calendar task.""")
        self.entity_localdoc["SetEntityCommand"] = ("""\
            Usage: set <property>=<value>

            Examples: set enabled=true
                      set coalesce=false
                      set schedule={"month":"*/2","day":5}

            Sets a calendar task property.""")

        self.skeleton_entity = {
            'enabled': False,
            'schedule': {
                'coalesce': True,
                'year': None,
                'month': None,
                'day': None,
                'week': None,
                'hour': None,
                'minute': None,
                'second': None,
                'day_of_week': None
            }
        }

        self.add_property(descr='Name',
                          name='name',
                          get='id',
                          usage=_("""\
            Alphanumeric name for the task which becomes read-only after the task
            is created."""),
                          set='id',
                          list=True)

        self.add_property(descr='Type',
                          name='type',
                          get=lambda row: TASK_TYPES_REVERSE[row['name']],
                          usage=_("""\
            Indicates the type of task. Allowable values are scrub, smart,
            snapshot, replication, and check_updates."""),
                          set=self.set_type,
                          list=True)

        self.add_property(
            descr='Arguments',
            name='args',
            get=lambda row: [format_value(i) for i in row['args']],
            set=None,
            list=False)

        self.add_property(descr='Coalesce',
                          name='coalesce',
                          get='schedule.coalesce',
                          list=True,
                          type=ValueType.BOOLEAN)

        self.add_property(descr='Schedule',
                          name='schedule',
                          get=self.get_schedule,
                          set='schedule',
                          list=True,
                          type=ValueType.DICT)

        self.add_property(descr='Timezone',
                          name='timezone',
                          get='schedule.timezone',
                          list=True)

        self.add_property(descr='Enabled',
                          name='enabled',
                          usage=_("""\
            Can be set to yes or no. By default, new tasks are disabled
            until set to yes."""),
                          get='enabled',
                          list=True,
                          type=ValueType.BOOLEAN)

        self.add_property(
            descr='Volume',
            name='volume',
            get=lambda e: self.get_args(e, 'volume'),
            list=False,
            set=self.set_volume,
            condition=lambda e: self.meets_condition(e, 'volume'))

        self.add_property(
            descr='Send Email',
            name='send_email',
            get=lambda e: self.get_args(e, 'send_email'),
            list=False,
            set=lambda obj, value: self.set_args(obj, value, 'send_email'),
            type=ValueType.BOOLEAN,
            condition=lambda e: self.meets_condition(e, 'send_email'))

        self.add_property(descr='Disks',
                          name='disks',
                          get=lambda e: self.get_args(e, 'disks'),
                          list=False,
                          type=ValueType.SET,
                          set=self.set_disks,
                          condition=lambda e: self.meets_condition(e, 'disks'))

        self.add_property(
            descr='SMART Test Type',
            name='test_type',
            get=lambda e: self.get_args(e, 'test_type'),
            list=False,
            enum=['short', 'long', 'conveyance', 'offline'],
            set=lambda obj, value: self.set_args(obj, value, 'test_type'),
            condition=lambda e: self.meets_condition(e, 'test_type'))

        self.add_property(
            descr='Username',
            name='username',
            get=lambda e: self.get_args(e, 'username'),
            list=False,
            set=self.set_username,
            condition=lambda e: self.meets_condition(e, 'username'))

        self.add_property(
            descr='Command',
            name='command',
            get=lambda e: self.get_args(e, 'command'),
            list=False,
            set=lambda obj, value: self.set_args(obj, value, 'command'),
            condition=lambda e: self.meets_condition(e, 'command'))

        self.add_property(
            descr='Dataset',
            name='dataset',
            get=lambda e: self.get_args(e, 'dataset'),
            list=False,
            set=lambda obj, value: self.set_args(obj, value, 'dataset'),
            condition=lambda e: self.meets_condition(e, 'dataset'))

        self.add_property(
            descr='Lifetime',
            name='lifetime',
            get=lambda e: self.get_args(e, 'lifetime'),
            list=False,
            set=lambda obj, value: self.set_args(obj, value, 'lifetime'),
            condition=lambda e: self.meets_condition(e, 'lifetime'),
            type=ValueType.NUMBER)

        self.add_property(
            descr='Recursive',
            name='recursive',
            get=lambda e: self.get_args(e, 'recursive'),
            list=False,
            set=lambda obj, value: self.set_args(obj, value, 'recursive'),
            condition=lambda e: self.meets_condition(e, 'recursive'),
            type=ValueType.BOOLEAN)

        self.add_property(
            descr='Prefix',
            name='prefix',
            get=lambda e: self.get_args(e, 'prefix'),
            list=False,
            set=lambda obj, value: self.set_args(obj, value, 'prefix'),
            condition=lambda e: self.meets_condition(e, 'prefix'))

        self.add_property(
            descr='Replicable',
            name='replicable',
            get=lambda e: self.get_args(e, 'replicable'),
            list=False,
            set=lambda obj, value: self.set_args(obj, value, 'replicable'),
            condition=lambda e: self.meets_condition(e, 'replicable'),
            type=ValueType.BOOLEAN)

        self.primary_key = self.get_mapping('name')
        self.entity_namespaces = lambda this: [
            StatusNamespace('status', self.context, this),
            ScheduleNamespace('schedule', self.context, this)
        ]

        self.entity_commands = lambda this: {'run': RunCommand(this)}
예제 #18
0
파일: complete.py 프로젝트: erinix/cli
 def choices(self, context, token):
     return [format_value(i) for i in self.data]
예제 #19
0
파일: complete.py 프로젝트: zoot/cli
 def choices(self, context, token):
     return [format_value(i) for i in self.data]
예제 #20
0
    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)