Пример #1
0
 def complete(self, context):
     return [
         NullComplete('name='),
         EnumComplete('layout=', VOLUME_LAYOUTS.keys()),
         EnumComplete('type=', VOLUME_LAYOUTS.keys()),
         EnumComplete('encryption=', ['yes', 'no']),
         NullComplete('password='******'disks=', 'disk', lambda d: d['name'], ['auto'], list=True),
         EntitySubscriberComplete('cache=', 'disk', lambda d: d['name'], ['auto'], list=True),
         EntitySubscriberComplete('log=', 'disk', lambda d: d['name'], ['auto'], list=True),
     ]
Пример #2
0
    def __init__(self, name, context):
        super(DockerConfigNamespace, self).__init__(name, context)
        self.config_call = "docker.config.get_config"
        self.update_task = 'docker.config.update'

        self.add_property(
            descr='Default Docker host',
            name='default_host',
            get=lambda o: self.get_host({'host': o['default_host']}),
            set=lambda o, v: q.set(o, 'default_host', self.set_host({}, v)),
            complete=EntitySubscriberComplete('default_host=', 'docker.host', lambda d: d['name']),
            usage=_('''\
            Name of a Docker host selected by default for any
            container or container image operations
            when there is no `host` parameter set explicitly in a command.''')
        )

        self.add_property(
            descr='Forward Docker remote API to host',
            name='api_forwarding',
            get=lambda o: self.get_host({'host': o['default_host']}),
            set=lambda o, v: q.set(o, 'default_host', self.set_host({}, v)),
            complete=EntitySubscriberComplete('default_host=', 'docker.host', lambda d: d['name']),
            usage=_('''\
            Defines which (if any) Docker host - Virtual Machine hosting
            a Docker service - should expose their standard remote HTTP API
            at FreeNAS's default network interface.''')
        )

        self.add_property(
            descr='Docker remote API forwarding',
            name='api_forwarding_enable',
            get='api_forwarding_enable',
            set='api_forwarding_enable',
            type=ValueType.BOOLEAN,
            usage=_('''\
            Used for enabling/disabling Docker HTTP API forwarding
            to FreeNAS's default network interface.''')
        )

        self.add_property(
            descr='Default DockerHub collection',
            name='default_collection',
            get='default_collection',
            set='default_collection',
            usage=_('''\
            Used for setting a default DockerHub container images collection,
            which later is being used in tab completion in other 'docker' namespaces.
            Collection equals to DockerHub username''')
        )
Пример #3
0
 def __init__(self, name):
     super(PeerComplete, self).__init__(
         name, (EntitySubscriberComplete(
             name, 'peer', lambda o: o['name']
             if o['type'] == 'freenas' else None),
                RpcComplete(name, 'system.general.get_config',
                            lambda o: o['hostname'])))
Пример #4
0
    def complete(self, context, **kwargs):
        props = []
        name = q.get(kwargs, 'kwargs.image')
        if name:
            image = context.entity_subscribers['docker.image'].query(('names', 'in', name), single=True)
            if not image:
                image = q.query(DockerImageNamespace.default_images, ('name', '=', name), single=True)

            if image and image['presets']:
                presets = image['presets']
                props += [NullComplete('{id}='.format(**i)) for i in presets['settings']]
                props += [NullComplete('volume:{container_path}='.format(**v)) for v in presets['volumes']]
                props += [NullComplete('port:{container_port}/{protocol}='.format(**v)) for v in presets['ports']]

        available_images = q.query(DockerImageNamespace.default_images, select='name')
        available_images += context.entity_subscribers['docker.image'].query(select='names.0')
        available_images = list(set(available_images))

        return props + [
            NullComplete('name='),
            NullComplete('command='),
            NullComplete('hostname='),
            NullComplete('volume:'),
            NullComplete('port:'),
            EnumComplete('image=', available_images),
            EntitySubscriberComplete('host=', 'docker.host', lambda i: q.get(i, 'name')),
            EnumComplete('interactive=', ['yes', 'no']),
            EnumComplete('autostart=', ['yes', 'no']),
            EnumComplete('expose_ports=', ['yes', 'no']),
        ]
Пример #5
0
    def add_properties(self):
        super(VMDeviceNicPropertiesMixin, self).add_properties()

        self.add_property(
            descr='NIC mode',
            name='nic_mode',
            get='properties.mode',
            enum=['NAT', 'BRIDGED', 'MANAGEMENT'],
            list=False,
            usage=_("Mode of NIC device [NAT|BRIDGED|MANAGEMENT]"),
            condition=lambda o: o['type'] == 'NIC',
        )

        self.add_property(
            descr='Emulated device type',
            name='nic_device_type',
            get='properties.device',
            enum=['VIRTIO', 'E1000', 'NE2K'],
            list=False,
            usage=_("The type of virtual NIC emulation [VIRTIO|E1000|NE2K]"),
            condition=lambda o: o['type'] == 'NIC',
        )

        self.add_property(
            descr='Bridge with',
            name='nic_bridge',
            get='properties.bridge',
            list=False,
            complete=MultipleSourceComplete(
                'bridge=', (
                    EntitySubscriberComplete('bridge=', 'network.interface', lambda i: i['id']),
                    EntitySubscriberComplete('bridge=', 'network.interface', lambda i: i['name'])
                ),
                extra=['default']
            ),
            usage=_("The interface to bridge NIC device with (if this NIC device is in BRIDGED mode)"),
            condition=lambda o: o['type'] == 'NIC',
        )

        self.add_property(
            descr='MAC address',
            name='nic_macaddr',
            get='properties.link_address',
            list=False,
            usage=_("Mac address of NIC device"),
            condition=lambda o: o['type'] == 'NIC',
        )
Пример #6
0
    def __init__(self, name, context):
        super(SystemUINamespace, self).__init__(name, context)
        self.context = context
        self.config_call = 'system.ui.get_config'
        self.update_task = 'system.ui.update'

        self.add_property(
            descr='Redirect http to https',
            name='redirect_https',
            get='webui_http_redirect_https',
            type=ValueType.BOOLEAN
        )

        self.add_property(
            descr='Web GUI Protocols in use',
            name='protocols',
            get='webui_protocol',
            type=ValueType.SET,
            enum=['HTTP', 'HTTPS']
        )

        self.add_property(
            descr='Web GUI IP Address (IPv4 and/or IPv6)',
            name='ip_addresses',
            get='webui_listen',
            type=ValueType.SET
        )

        self.add_property(
            descr='HTTP port',
            name='http_port',
            get='webui_http_port',
            type=ValueType.NUMBER
        )

        self.add_property(
            descr='HTTPS port',
            name='https_port',
            get='webui_https_port',
            type=ValueType.NUMBER
        )

        self.add_property(
            descr='HTTPS certificate',
            name='https_certificate',
            get=lambda o: get_related(self.context, 'crypto.certificate', o, 'webui_https_certificate'),
            set=lambda o, v: set_related(self.context, 'crypto.certificate', o, 'webui_https_certificate', v),
            usage=_("""\
            Name of the certificate
            """),
            complete=EntitySubscriberComplete(
                'https_certificate=',
                'crypto.certificate',
                lambda o: o['name'] if o['type'] != 'CERT_CSR' else None
            ),
            type=ValueType.STRING
        )
Пример #7
0
    def __init__(self, name, context):
        super(SmartNamespace, self).__init__(name, context)
        self.extra_query_params = [('task', '=', 'disk.parallel_test')]
        self.required_props.extend(['disks', 'test_type'])
        self.skeleton_entity['task'] = 'disk.parallel_test'
        self.task_args_helper = ['disks', 'test_type']
        self.localdoc['CreateEntityCommand'] = ("""\
            Usage: create <name> disks=<disks> test_type=<test_type> <property>=<value>

            Examples: create mysmart disks=ada0,ada1,ada2 test_type=SHORT
                      create somesmart disks=ada0,ada1,ada2 test_type=LONG schedule={"hour":"*/4"}
                      create somesmart disks=ada0,ada1,ada2 test_type=LONG schedule={"hour":"3,20"}

            Creates a SMART calendar task. For a list of properties, see 'help properties'."""
                                                )
        self.entity_localdoc['SetEntityCommand'] = ("""\
            Usage: set <property>=<value> ...

            Examples: set test_type=LONG
                      set disks=ada1,ada2
                      set enabled=true

            Sets a SMART calendar task property. For a list of properties, see 'help properties'."""
                                                    )

        self.entity_localdoc['GetEntityCommand'] = ("""\
            Usage: get <field>

            Examples:
                get test_type
                get disks

            Display value of specified field.""")

        self.add_property(descr='Disks',
                          name='disks',
                          get=lambda obj: self.get_disks(obj),
                          list=True,
                          type=ValueType.SET,
                          set=lambda obj, val: self.set_disks(obj, val),
                          complete=EntitySubscriberComplete(
                              'disks=', 'disk', lambda i: i['name']))

        self.add_property(
            descr='SMART Test Type',
            name='test_type',
            get=lambda obj: self.get_task_args(obj, 'test_type'),
            list=True,
            set=lambda obj, val: self.set_task_args(obj, val, 'test_type'),
            enum=['SHORT', 'LONG', 'CONVEYANCE', 'OFFLINE'])
Пример #8
0
    def __init__(self, name, context):
        super(ReplicationNamespace, self).__init__(name, context)
        self.extra_query_params = [('task', '=', 'replication.sync')]
        self.required_props.extend(['replication'])
        self.skeleton_entity['task'] = 'replication.sync'
        self.task_args_helper = ['replication']

        self.add_property(
            descr='Replication',
            name='replication',
            get=lambda obj: self.get_task_args(obj, 'replication'),
            set=lambda obj, val: self.set_task_args(obj, val, 'replication'),
            list=True,
            complete=EntitySubscriberComplete('replication=', 'replication',
                                              lambda o: o['name']),
            usage=
            _('Name of the replication object to be used in the replication calendar task.'
              ))
Пример #9
0
    def __init__(self, name, context):
        super(BackupNamespace, self).__init__(name, context)
        self.extra_query_params = [('task', '=', 'backup.sync')]
        self.required_props.extend(['backup'])
        self.skeleton_entity['task'] = 'backup.sync'
        self.task_args_helper = ['backup']
        self.localdoc['CreateEntityCommand'] = ("""\
            Usage: create <name> backup=<backup_name> <property>=<value>

            Examples: create sshbackup_job backup=mysshbackup
                      create s3backup_job backup=mys3backup schedule={"hour":2,"day_of_week":5}
                      create s3backup_job backup=mys3backup schedule={"hour":2,"day_of_week":"1,5"}

            Creates a backup calendar task. For a list of properties, see 'help properties'."""
                                                )

        self.entity_localdoc['SetEntityCommand'] = ("""\
            Usage: set <property>=<value> ...

            Examples: set name=otherbackup
                      set enabled=true

            Sets a backup calendar task property. For a list of properties, see 'help properties'."""
                                                    )

        self.entity_localdoc['GetEntityCommand'] = ("""\
            Usage: get <field>

            Examples:
                get backup
                get name

            Display value of specified field.""")

        self.add_property(
            descr='Backup',
            name='backup',
            get=lambda obj: objid2name(self.context, 'backup',
                                       self.get_task_args(obj, 'backup')),
            list=True,
            set=lambda obj, val: self.set_task_args(
                obj, objname2id(self.context, 'backup', val), 'backup'),
            complete=EntitySubscriberComplete('backup=', 'backup',
                                              lambda i: i['name']))
Пример #10
0
    def __init__(self, name, context):
        super(ScrubNamespace, self).__init__(name, context)
        self.extra_query_params = [('task', '=', 'volume.scrub')]
        self.required_props.extend(['volume'])
        self.skeleton_entity['task'] = 'volume.scrub'
        self.task_args_helper = ['volume']
        self.localdoc['CreateEntityCommand'] = ("""\
            Usage: create <name> disks=<disks> volume=<volume> <property>=<value>

            Examples: create myscrub volume=mypool
                      create somescrub volume=somepool schedule={"hour":2,"day_of_week":5}
                      create somescrub volume=somepool schedule={"hour":"2,12","day_of_week":5}

            Creates a scrub calendar task. For a list of properties, see 'help properties'."""
                                                )

        self.entity_localdoc['SetEntityCommand'] = ("""\
            Usage: set <property>=<value> ...

            Examples: set name=otherscrub
                      set enabled=true

            Sets a scrub calendar task property. For a list of properties, see 'help properties'."""
                                                    )

        self.entity_localdoc['GetEntityCommand'] = ("""\
            Usage: get <field>

            Examples:
                get volume
                get name

            Display value of specified field.""")

        self.add_property(
            descr='Volume',
            name='volume',
            get=lambda obj: self.get_task_args(obj, 'volume'),
            list=True,
            set=lambda obj, val: self.set_task_args(obj, val, 'volume'),
            complete=EntitySubscriberComplete('volume=', 'volume'))
Пример #11
0
    def add_properties(self):
        super(BackupSSHPropertiesMixin, self).add_properties()

        self.add_property(descr='Peer',
                          name='ssh_peer',
                          usage=_("Peer name. Must match a peer of type ssh"),
                          get=lambda o: get_related(self.context, 'peer', o,
                                                    'properties.peer'),
                          set=lambda o, v: set_related(self.context, 'peer', o,
                                                       'properties.peer', v),
                          list=False,
                          condition=lambda o: o['provider'] == 'ssh',
                          complete=EntitySubscriberComplete(
                              'ssh_peer=', 'peer', lambda i: i['name']))

        self.add_property(descr='Directory',
                          name='ssh_directory',
                          usage=_("""\
            Name of existing directory to save the backups to."""),
                          get='properties.directory',
                          list=False,
                          condition=lambda o: o['provider'] == 'ssh')
Пример #12
0
    def __init__(self, name, context):
        super(DockerContainerNamespace, self).__init__(name, context)
        self.entity_subscriber_name = 'docker.container'
        self.create_task = 'docker.container.create'
        self.delete_task = 'docker.container.delete'
        self.allow_edit = False
        self.primary_key_name = 'names.0'
        self.required_props = ['name', 'image']
        self.skeleton_entity = {
            'command': []
        }

        self.entity_localdoc['DeleteEntityCommand'] = ("""\
            Usage: delete

            Deletes the specified Docker container.""")
        self.localdoc['ListCommand'] = ("""\
            Usage: show

            Lists all Docker containers. Optionally, filter or sort by property.
            Use 'help properties' to list available properties.

            Examples:
                show
                show | search name == foo""")

        def get_ports(o):
            return ['{0}/{2}={1}'.format(i['container_port'], i['host_port'], i['protocol']) for i in o['ports']]

        def get_volumes(o):
            return ['{0}={1}'.format(i['container_path'], i['host_path']) for i in o['volumes']]

        self.add_property(
            descr='Name',
            name='name',
            get='names.0',
            usersetable=False,
            list=True,
            usage=_('Name of a container instance.')
        )

        self.add_property(
            descr='Image name',
            name='image',
            get='image',
            usersetable=False,
            list=True,
            complete=EntitySubscriberComplete('image=', 'docker.image', lambda i: q.get(i, 'names.0')),
            strict=False,
            usage=_('Name of container image used to create an instance of a container.')
        )

        self.add_property(
            descr='Command',
            name='command',
            get='command',
            usersetable=False,
            list=True,
            type=ValueType.ARRAY,
            usage=_('''\
            Command being run on a container (like /bin/sh).
            Can be a single string or a list of strings.''')
        )

        self.add_property(
            descr='Environment',
            name='environment',
            get='environment',
            set='environment',
            list=False,
            type=ValueType.ARRAY,
            usage=_('''\
            Array of strings formed as KEY=VALUE.
            These are being converted to environment variables
            visible to a running container instance.''')
        )

        self.add_property(
            descr='Status',
            name='status',
            get='status',
            set=None,
            usersetable=False,
            list=True,
            usage=_('String status of a container returned by a Docker service.')
        )

        self.add_property(
            descr='Web UI URL',
            name='web_ui_url',
            get='web_ui_url',
            set=None,
            usersetable=False,
            list=True,
        )

        self.add_property(
            descr='Container host name',
            name='hostname',
            get='hostname',
            set=None,
            usersetable=False,
            list=False,
            usage=_('''\
            Used to set host name of a container - like my_ubuntu_container.
            If not set explicitly it defaults in most cases
            to generating a random string as a container's host name.''')
        )

        self.add_property(
            descr='Host',
            name='host',
            get=self.get_host,
            set=self.set_host,
            usersetable=False,
            list=True,
            complete=EntitySubscriberComplete('host=', 'docker.host', lambda d: d['name']),
            usage=_('''\
            Name of Docker host instance owning container instance.
            Docker host name equals to name of Virtual Machine
            hosting Docker service.''')
        )

        self.add_property(
            descr='Ports',
            name='ports',
            get=get_ports,
            usersetable=False,
            list=True,
            type=ValueType.SET,
            usage=_('''\
            Array of strings used for defining network ports forwarding.
            Each of values should be formatted like:
            <container_port_number>/<tcp/udp>=<freenas_port_number>
            Ports are always being forwarded to a default FreeNAS box's
            network interface.''')
        )

        self.add_property(
            descr='Expose ports',
            name='expose_ports',
            get='expose_ports',
            usersetable=False,
            list=True,
            type=ValueType.BOOLEAN,
            usage=_('''\
            Property defining whether or not ports which are defined in `ports`
            should be actually forwarded to FreeNAS (host machine).''')
        )

        self.add_property(
            descr='Autostart container',
            name='autostart',
            get='autostart',
            usersetable=False,
            list=True,
            type=ValueType.BOOLEAN,
            usage=_('''\
            Defines if a container should be started automatically
            when a Docker host related to it goes UP''')
        )

        self.add_property(
            descr='Interactive',
            name='interactive',
            get='interactive',
            usersetable=False,
            list=False,
            type=ValueType.BOOLEAN,
            usage=_('''\
            Defines if container's standard input should act
            like it is open even if no console is attached to a container.
            Useful to keep alive a process (command) being run on a container
            which immediately exits when there is no standard input
            opened to it (i.e. /bin/bash or any other shell).''')
        )

        self.add_property(
            descr='Volumes',
            name='volumes',
            get=get_volumes,
            usersetable=False,
            list=True,
            type=ValueType.SET,
            usage=_('''\
            List of strings formatted like:
            <container_path>=<freenas_path>
            Defines which of FreeNAS paths should be exposed to a container.''')
        )

        self.primary_key = self.get_mapping('name')
        self.entity_commands = self.get_entity_commands
Пример #13
0
    def __init__(self, name, context):
        super(VMNamespace, self).__init__(name, context)
        self.entity_subscriber_name = 'vm'
        self.create_task = 'vm.create'
        self.update_task = 'vm.update'
        self.delete_task = 'vm.delete'
        self.required_props = ['name', 'volume']
        self.primary_key_name = 'name'
        self.localdoc['CreateEntityCommand'] = ("""\
            Usage: create <name> volume=<volume> <property>=<value> ...

            Examples: create myvm volume=myvolume
                      create myfreebsd volume=myvolume template=freebsd-11-zfs

            Creates a virtual machine. For a list of properties, see 'help properties'.
            For a list of templates see '/ vm template show'""")
        self.entity_localdoc['SetEntityCommand'] = ("""\
            Usage: set <property>=<value> ...

            Examples: set memsize=2GB
                      set cores=4
                      set guest_type=freebsd64
                      set bootloader=GRUB

            Sets a virtual machine property. For a list of properties, see 'help properties'.""")
        self.entity_localdoc['DeleteEntityCommand'] = ("""\
            Usage: delete

            Deletes the specified virtual machine.""")
        self.localdoc['ListCommand'] = ("""\
            Usage: show

            Lists all virtual machines. Optionally, filter or sort by property.
            Use 'help properties' to list available properties.

            Examples:
                show
                show | search name == foo""")

        def set_memsize(o, v):
            set(o, 'config.memsize', int(v / 1024 / 1024))

        self.skeleton_entity = {
            'devices': [],
            'config': {}
        }

        self.add_property(
            descr='VM Name',
            name='name',
            get='name',
            list=True,
            usage=_("Name of the VM")
        )

        self.add_property(
            descr='Template name',
            name='template',
            get='template.name',
            complete=RpcComplete('template=', 'vm.template.query', lambda i: get(i, 'template.name')),
            usage=_("Name of the template used to create the VM from")
        )

        self.add_property(
            descr='State',
            name='state',
            get='status.state',
            set=None,
            usage=_("The current state of the VM [RUNNING|STOPPED]")
        )

        self.add_property(
            descr='Volume',
            name='volume',
            get='target',
            createsetable=True,
            usersetable=False,
            complete=EntitySubscriberComplete('volume=', 'volume', lambda i: i['id']),
            usage=_("The volume on which the VM is stored")
        )

        self.add_property(
            descr='Description',
            name='description',
            get='description',
            list=False,
            usage=_("Its a description D'OH!")
        )

        self.add_property(
            descr='Memory size (MB)',
            name='memsize',
            get=lambda o: get(o, 'config.memsize') * 1024 * 1024,
            set=set_memsize,
            list=True,
            type=ValueType.SIZE,
            usage=_("Size of the Memory allocated to the VM")
        )

        self.add_property(
            descr='CPU cores',
            name='cores',
            get='config.ncpus',
            list=True,
            type=ValueType.NUMBER,
            usage=_("Number of cpu cores assigned to the VM")
        )

        self.add_property(
            descr='Start on boot',
            name='autostart',
            get='config.autostart',
            type=ValueType.BOOLEAN,
            usage=_("Property that controls whether the VM is autostarted on System Boot up")
        )

        self.add_property(
            descr='Boot device',
            name='boot_device',
            get='config.boot_device',
            list=False,
            usage=_("The device from the devices namespace from which to boot from"),
            complete=RpcComplete(
                'boot_device=',
                'vm.query',
                lambda o: [i['name'] for i in o['devices'] if i['type'] in ('DISK', 'CDROM')]
            )
        )

        self.add_property(
            descr='Boot directory (for GRUB)',
            name='boot_directory',
            get='config.boot_directory',
            list=False,
            usage=_("The directory in VM's dataset under the files directory that contains grub.cfg")
        )

        self.add_property(
            descr='Boot partition (for GRUB)',
            name='boot_partition',
            get='config.boot_partition',
            list=False,
            usage=_("The partition on the os's boot device to boot from (i.e. msdos1 for the first partition of a BIOS partition layout)")
        )

        self.add_property(
            descr='Bootloader type',
            name='bootloader',
            get='config.bootloader',
            list=False,
            enum=['BHYVELOAD', 'GRUB', 'UEFI', 'UEFI_CSM'],
            usage=_("Type of Bootloader"),
        )

        self.add_property(
            descr='Guest type',
            name='guest_type',
            get='guest_type',
            list=False,
            enum=[
                'linux64',
                'freebsd32',
                'freebsd64',
                'netbsd64',
                'openbsd32',
                'openbsd64',
                'windows64',
                'solaris64',
                'other'
            ],
            usage=_("Type of the guest os (i.e. freebsd32, windows64, linux64, etc.)")
        )

        self.add_property(
            descr='Cloud-init data',
            name='cloud_init',
            get='config.cloud_init',
            list=False,
            usage=_("Bread goes in, Toast comes out. You can't explain that (or this!)")
        )

        self.add_property(
            descr='Enabled',
            name='enabled',
            get='enabled',
            list=True,
            type=ValueType.BOOLEAN,
            usage=_("Enables/Disables the VM")
        )

        self.add_property(
            descr='Immutable',
            name='immutable',
            get='immutable',
            list=False,
            usersetable=False,
            type=ValueType.BOOLEAN,
            usage=_("Sets VM as immutable")
        )

        self.add_property(
            descr='Readme',
            name='readme',
            get='config.readme',
            set='config.readme',
            list=False,
            type=ValueType.TEXT_FILE,
            usage=_("Information about this VM including instructions on how to login, username and password, etc.")
        )

        self.add_property(
            descr='NAT IP address',
            name='nat_ip',
            get='status.nat_lease.client_ip',
            set=None,
            list=False,
            condition=lambda o: get(o, 'status.state') != 'STOPPED' and get(o, 'status.nat_lease'),
            usage=_("Displays the natted IP address of the VM (if any)")
        )

        self.add_property(
            descr='VM tools available',
            name='vm_tools_available',
            get='status.vm_tools_available',
            set=None,
            list=False,
            condition=lambda o: get(o, 'status.state') != 'STOPPED',
            usage=_("Shows whether freenas-vm-tools are running on the VM"),
            type=ValueType.BOOLEAN
        )

        self.add_property(
            descr='Guest health',
            name='health',
            get='status.health',
            set=None,
            list=False,
            condition=lambda o: get(o, 'status.state') != 'STOPPED',
            usage=_("Shows guest health status")
        )

        self.primary_key = self.get_mapping('name')
        self.entity_namespaces = self.get_entity_namespaces
        self.entity_commands = self.get_entity_commands

        self.extra_commands = {
            'import': ImportVMCommand(self)
        }
Пример #14
0
    def __init__(self, name, context):
        super(CryptoNamespace, self).__init__(name, context)
        self.context = context
        self.entity_subscriber_name = 'crypto.certificate'
        self.primary_key_name = 'name'
        self.create_task = 'crypto.certificate.create'
        self.update_task = 'crypto.certificate.update'
        self.import_task = 'crypto.certificate.import'
        self.delete_task = 'crypto.certificate.delete'

        self.localdoc['CreateEntityCommand'] = ("""\
            Crates a Certificate or Certificate Authority. For a list of properties, see 'help properties'.

            Usage:
                create type=<cert-type> name=<cert-name> <property>=<value>

            Examples:
            Create root CA Certificate :
                create type=CA_INTERNAL name=myRootCA selfsigned=yes key_length=2048 digest_algorithm=SHA256
                lifetime=3650 country=PL state=Slaskie city=Czerwionka-Leszczyny
                organization=myCAOrg [email protected] common=my_CA_Server
            Create intermediate CA Certificate :
                create type=CA_INTERMEDIATE signing_ca_name=myRootCA name=myInterCA key_length=2048 digest_algorithm=SHA256
                lifetime=365 country=PL state=Slaskie city=Czerwionka-Leszczyny organization=myorg [email protected]
                common=MyCommonName
            Create self-signed server certificate without CA:
                create type=CERT_INTERNAL name=mySelfSignedServerCert selfsigned=yes key_length=2048
                digest_algorithm=SHA256 lifetime=365 country=PL state=Slaskie city=Czerwionka-Leszczyny
                organization=myorg [email protected] common=www.myserver.com
            Create server certificate signed by internal root CA Certificate:
                create type=CERT_INTERNAL name=myCASignedServerCert signing_ca_name=myRootCA key_length=2048
                digest_algorithm=SHA256 lifetime=365 country=PL state=Slaskie city=Czerwionka-Leszczyny
                organization=myorg [email protected] common=www.myserver.com""")

        self.entity_localdoc['DeleteEntityCommand'] = ("""\
            Usage: delete

            Examples: delete

            Deletes the specified certificate.

            !WARNING! Deleting the CA certificate will cause recursive delete
            of all the certificates signed by that CA.""")

        self.localdoc['ListCommand'] = ("""\
            Usage: show

            Examples:
                show
                show | search type == CERT_INTERNAL
                show | search type == CA_EXISTING | sort name

            Lists all certificates, optionally doing filtering and sorting.
            """)

        self.entity_commands = lambda this: {
            'export_certificate': ExportCertificateCommand(this),
            'export_privatekey': ExportPrivatekeyCommand(this)
        }

        self.extra_commands = {'import': ImportCertificateCommand(self)}

        self.skeleton_entity = {
            'type': None,
        }

        self.add_property(
            descr='Name',
            name='name',
            get='name',
            set='name',
            usage=_("""\
            Name of the certificate.
            """),
            list=True,
        )

        self.add_property(
            descr='Type',
            name='type',
            get='type',
            set='type',
            usage=_("""\
            Certificate type
            """),
            enum=[
                'CERT_CSR', 'CERT_INTERMEDIATE', 'CERT_INTERNAL',
                'CA_INTERMEDIATE', 'CA_INTERNAL'
            ],
            list=True,
        )

        self.add_property(
            descr='Serial Number',
            name='serial',
            get='serial',
            set=None,
            usage=_("""\
            Unique serial number of the certificate
            """),
            usersetable=False,
            list=True,
        )

        self.add_property(
            descr='Certificate',
            name='certificate',
            get='certificate',
            set='certificate',
            usage=_("""\
            Certificate contents.
            """),
            type=ValueType.TEXT_FILE,
            createsetable=False,
            usersetable=lambda e: e['type'] in
            ('CA_EXISTING', 'CERT_EXISTING'),
            list=False,
        )

        self.add_property(
            descr='Certificate Path',
            name='certificate_path',
            get='certificate_path',
            set=None,
            usage=_("""\
            Path to the certificate file.
            """),
            type=ValueType.STRING,
            createsetable=False,
            usersetable=False,
            list=False,
        )

        self.add_property(
            descr='Private Key',
            name='privatekey',
            get='privatekey',
            set='privatekey',
            usage=_("""\
            Private key associated with the certificate.
            """),
            type=ValueType.PASSWORD,
            createsetable=False,
            usersetable=lambda e: e['type'] in
            ('CA_EXISTING', 'CERT_EXISTING'),
            list=False,
        )

        self.add_property(
            descr='Private Key Path',
            name='privatekey_path',
            get='privatekey_path',
            set=None,
            usage=_("""\
            Path to the private key associated with the certificate.
            """),
            type=ValueType.STRING,
            createsetable=False,
            usersetable=False,
            list=False,
        )

        self.add_property(
            descr="Self-signed",
            name='selfsigned',
            get='selfsigned',
            set='selfsigned',
            usage=_("""\
            Boolean value. True if the certificate is 'self-signed', meaning that
            the certificate was not signed by any external Certificate Authority.
            """),
            type=ValueType.BOOLEAN,
            createsetable=True,
            usersetable=False,
            list=True,
            condition=lambda e: e['type'] not in
            (None, 'CERT_CSR', 'CERT_INTERMEDIATE', 'CA_INTERMEDIATE'))

        self.add_property(descr="Signing CA",
                          name='signing_ca_name',
                          get='signing_ca_name',
                          set='signing_ca_name',
                          usage=_("""\
            Name of the CA signing this certificate.
            """),
                          complete=EntitySubscriberComplete(
                              'signing_ca_name=', self.entity_subscriber_name,
                              lambda o: o['name'] if o['type'] in
                              ('CA_INTERNAL', 'CA_INTERMEDIATE') else None),
                          createsetable=True,
                          usersetable=False,
                          list=True,
                          condition=lambda e: e['type'] in
                          ('CA_INTERMEDIATE', 'CERT_INTERMEDIATE',
                           'CA_INTERNAL', 'CERT_INTERNAL'))

        self.add_property(
            descr="Signing CA's ID",
            name='signing_ca_id',
            get='signing_ca_id',
            set='signing_ca_id',
            usage=_("""\
            ID of the CA signing this certificate. This field is not user-settable.
            """),
            createsetable=False,
            usersetable=False,
            list=False,
        )

        self.add_property(
            descr='Key length',
            name='key_length',
            get='key_length',
            set='key_length',
            usage=_("""\
            Key length, for security reasons minimun of 2048 is recommanded.
            """),
            type=ValueType.NUMBER,
            usersetable=False,
            list=False,
            condition=lambda e: e['type'] not in (None, ),
        )

        self.add_property(
            descr='Digest algorithm',
            name='digest_algorithm',
            get='digest_algorithm',
            set='digest_algorithm',
            usage=_("""\
            Digest alghoritm for the certificate.
            """),
            enum=['SHA1', 'SHA224', 'SHA256', 'SHA384', 'SHA512'],
            usersetable=False,
            list=False,
            condition=lambda e: e['type'] not in (None, ),
        )

        self.add_property(
            descr='Not Before',
            name='not_before',
            get='not_before',
            set='not_before',
            usage=_("""\
            Certificate's lifetime 'valid from' date.
            """),
            usersetable=False,
            list=True,
            condition=lambda e: e['type'] not in (None, ),
        )

        self.add_property(
            descr='Not After',
            name='not_after',
            get='not_after',
            set='not_after',
            usage=_("""\
            Certificate's lifetime 'valid to' date.
            """),
            usersetable=False,
            list=True,
            condition=lambda e: e['type'] not in (None, ),
        )

        self.add_property(
            descr='Lifetime',
            name='lifetime',
            get='lifetime',
            set='lifetime',
            usage=_("""\
            Certificate lifetime in days, accepts number values"""),
            type=ValueType.NUMBER,
            usersetable=False,
            list=False,
            condition=lambda e: e['type'] not in (None, ),
        )

        self.add_property(
            descr='Country',
            name='country',
            get='country',
            set='country',
            usage=_("""\
            Country of the organization"""),
            usersetable=False,
            list=False,
            condition=lambda e: e['type'] not in (None, ),
        )

        self.add_property(
            descr='State',
            name='state',
            get='state',
            set='state',
            usage=_("""\
            State or province of the organization
            """),
            usersetable=False,
            list=False,
            condition=lambda e: e['type'] not in (None, ),
        )

        self.add_property(
            descr='City',
            name='city',
            get='city',
            set='city',
            usage=_("""\
            Location of the organization
            """),
            usersetable=False,
            list=False,
            condition=lambda e: e['type'] not in (None, ),
        )

        self.add_property(
            descr='Organization',
            name='organization',
            get='organization',
            set='organization',
            usage=_("""\
            Name of the company or organization
            """),
            usersetable=False,
            list=False,
            condition=lambda e: e['type'] not in (None, ),
        )

        self.add_property(
            descr='Common Name',
            name='common',
            get='common',
            set='common',
            usage=_("""\
            Fully qualified domain name of FreeNAS system
            """),
            usersetable=False,
            list=False,
            condition=lambda e: e['type'] not in (None, ),
        )

        self.add_property(
            descr='Email',
            name='email',
            get='email',
            set='email',
            usage=_("""\
            Email address of the person responsible for the certificate
            """),
            usersetable=False,
            list=False,
            condition=lambda e: e['type'] not in (None, ),
        )

        self.primary_key = self.get_mapping('name')
Пример #15
0
    def __init__(self, name, context):
        super(ReplicationNamespace, self).__init__(name, context)

        class PeerComplete(MultipleSourceComplete):
            def __init__(self, name):
                super(PeerComplete, self).__init__(
                    name,
                    (
                        EntitySubscriberComplete(name, 'peer', lambda o: o['name'] if o['type'] == 'freenas' else None),
                        RpcComplete(name, 'system.general.get_config', lambda o: o['hostname'])
                    )
                )

        self.primary_key_name = 'name'
        self.entity_subscriber_name = 'replication'
        self.create_task = 'replication.create'
        self.update_task = 'replication.update'
        self.delete_task = 'replication.delete'
        self.required_props = ['datasets', 'master', 'slave']

        self.localdoc['CreateEntityCommand'] = ("""\
            Usage: create <name> master=<master> slave=<slave> recursive=<recursive>
                    bidirectional=<bidirectional> auto_recover=<auto_recover>
                    replicate_services=<replicate_services> encrypt=<encrypt>
                    compress=<fast/default/best> throttle=<throttle>
                    snapshot_lifetime=<snapshot_lifetime> follow_delete=<follow_delete>

            Example: create my_replication master=10.0.0.2 slave=10.0.0.3
                                           datasets=mypool,mypool/dataset
                     create my_replication master=freenas-1.local slave=freenas-2.local
                                           datasets=source:target,source2/data:target2
                     create my_replication master=10.0.0.2 slave=10.0.0.3
                                           datasets=mypool recursive=yes
                     create my_replication master=10.0.0.2 slave=10.0.0.3 datasets=mypool
                                           bidirectional=yes
                     create my_replication master=10.0.0.2 slave=10.0.0.3
                                           datasets=mypool,mypool2 bidirectional=yes
                                           recursive=yes
                     create my_replication master=10.0.0.2 slave=10.0.0.3
                                           datasets=mypool,mypool2 bidirectional=yes
                                           recursive=yes replicate_services=yes
                     create my_replication master=10.0.0.2 slave=10.0.0.3
                                           datasets=mypool,mypool2 bidirectional=yes
                                           recursive=yes replicate_services=yes
                                           auto_recover=yes
                     create my_replication master=10.0.0.2 slave=10.0.0.3
                                           datasets=mypool encrypt=AES128
                     create my_replication master=10.0.0.2 slave=10.0.0.3
                                           datasets=mypool compress=best
                     create my_replication master=10.0.0.2 slave=10.0.0.3
                                           datasets=mypool throttle=10MiB
                     create my_replication master=10.0.0.2 slave=10.0.0.3
                                           datasets=mypool encrypt=AES128 compress=best
                                           throttle=10MiB
                     create my_replication master=10.0.0.2 slave=10.0.0.3
                                           datasets=mypool snapshot_lifetime=1:10:10
                                           followdelete=yes

            Creates a replication link entry. Link contains configuration data
            used in later replication process.

            All ZFS pools referenced in 'datasets' property must exist on both
            slave and master at creation time. Datasets can be defined as a simple list
            of datasets available on master (source) eg. mypool/mydataset,mypool2/mydataset2,
            or a list of {source}:{target} eg. mypool/ds:targetpool/ds2,otherpool:targetpool2.
            First example could be expanded to:
            mypool/mydataset:mypool/mydataset,mypool2/mydataset2:mypool2mydataset2
            It would have the same meaning.

            Bidirectional replication is accepting only identical master and slave
            (source and target) datasets trees eg mypool:mypool,mypool2:mypool2.

            Created replication is implicitly: unidirectional, non-recursive,
            does not recover automatically and does not replicate services
            along with datasets.

            One of: master, slave parameters must represent one of current machine's
            IP addresses. Both these parameters must be defined,
            because unidirectional replication link can be promoted
            to become bi-directional link.

            Recursive parameter set to 'yes' informs that every child dataset
            of datasets defined in 'datasets' parameter will be replicated
            along with provided parents.

            Only in bi-directional replication service replication
            and automatic recovery are available.

            When automatic recovery is selected it is not possible to switch
            hosts roles manually. It's being done automatically each time
            'master' goes down or up again.
            Creates a replication task. For a list of properties, see 'help properties'.""")
        self.entity_localdoc['SetEntityCommand'] = ("""\
            Usage: set <property>=<value> ...

            Examples: set bidirectional=yes
                      set throttle=1M
                      set encrypt=AES256
                      set datasets=mypool1,mypool2/dataset1

            Sets a replication property. For a list of properties, see 'help properties'.""")

        self.localdoc['ListCommand'] = ("""\
            Usage: show

            Lists all replications. Optionally, filter or sort by property.
            Use 'help properties' to list available properties.

            Examples:
                show
                show | search name == foo""")

        self.entity_localdoc['DeleteEntityCommand'] = ("""\
            Usage: delete scrub=<scrub>

            Examples: delete
                      delete scrub=yes

            Delete current entity. Scrub allows to delete related datasets at slave side.""")

        self.skeleton_entity = {
            'bidirectional': False,
            'recursive': False,
            'replicate_services': False,
            'transport_options': []
        }

        def get_transport_option(obj, name):
            options = obj['transport_options']
            for o in options:
                if name in o['%type'].lower():
                    return o

            return None

        def get_compress(obj):
            compress = get_transport_option(obj, 'compress')
            if compress:
                return compress['level']
            else:
                return None

        def get_throttle(obj):
            throttle = get_transport_option(obj, 'throttle')
            if throttle:
                return throttle['buffer_size']
            else:
                return None

        def get_encrypt(obj):
            encrypt = get_transport_option(obj, 'encrypt')
            if encrypt:
                return encrypt['type']
            else:
                return None

        def set_transport_option(obj, oldval, val):
            if oldval:
                obj['transport_options'].remove(oldval)
            if val:
                obj['transport_options'].append(val)

        def set_compress(obj, val):
            opt = None
            if val != 'no':
                opt = {
                    '%type': 'CompressReplicationTransportOption',
                    'level': val
                }
            set_transport_option(obj, get_transport_option(obj, 'compress'), opt)

        def set_throttle(obj, val):
            opt = {
                '%type': 'ThrottleReplicationTransportOption',
                'buffer_size': val
            }
            set_transport_option(obj, get_transport_option(obj, 'throttle'), opt)

        def set_encrypt(obj, val):
            opt = None
            if val != 'no':
                opt = {
                    '%type': 'EncryptReplicationTransportOption',
                    'type': val
                }
            set_transport_option(obj, get_transport_option(obj, 'encrypt'), opt)

        def get_peer(obj, role):
            if obj[role] == self.context.call_sync('system.info.host_uuid'):
                return self.context.call_sync('system.general.get_config')['hostname']
            else:
                return self.context.entity_subscribers['peer'].query(
                    ('id', '=', obj[role]),
                    single=True,
                    select='name'
                )

        def set_peer(obj, val, role):
            if val == self.context.call_sync('system.general.get_config')['hostname']:
                obj[role] = self.context.call_sync('system.info.host_uuid')
            else:
                peer_id = self.context.entity_subscribers['peer'].query(
                    ('name', '=', val),
                    ('type', '=', 'freenas'),
                    single=True,
                    select='id'
                )
                obj[role] = peer_id

        def get_datasets(obj):
            return ['{0}:{1}'.format(i['master'], i['slave']) for i in obj['datasets']]

        def set_datasets(obj, value):
            datasets = []
            for ds in value:
                sp_dataset = ds.split(':', 1)
                datasets.append({
                    'master': sp_dataset[0],
                    'slave': sp_dataset[int(bool(len(sp_dataset) == 2 and sp_dataset[1]))]
                })

            obj['datasets'] = datasets

        def get_initial_master(obj):
            if obj['initial_master'] == obj['master']:
                return get_peer(obj, 'master')
            elif obj['initial_master'] == obj['slave']:
                return get_peer(obj, 'slave')
            else:
                return

        self.add_property(
            descr='Name',
            name='name',
            get='name',
            usersetable=False,
            list=True,
            usage=_('Name of a replication task')
        )

        self.add_property(
            descr='Master',
            name='master',
            get=lambda o: get_peer(o, 'master'),
            set=lambda o, v: set_peer(o, v, 'master'),
            usersetable=False,
            list=True,
            complete=PeerComplete('master='),
            usage=_('Name of FreeNAS machine (peer) acting as a sending side.')
        )

        self.add_property(
            descr='Slave',
            name='slave',
            get=lambda o: get_peer(o, 'slave'),
            set=lambda o, v: set_peer(o, v, 'slave'),
            usersetable=False,
            list=True,
            complete=PeerComplete('slave='),
            usage=_('Name of FreeNAS machine (peer) acting as a receiving side.')
        )

        self.add_property(
            descr='Datasets',
            name='datasets',
            get=get_datasets,
            set=set_datasets,
            list=False,
            strict=False,
            type=ValueType.SET,
            complete=EntitySubscriberComplete('datasets=', 'volume.dataset', lambda o: o['name'] + ':'),
            usage=_('List of datasets to be replicated.')
        )

        self.add_property(
            descr='Bi-directional',
            name='bidirectional',
            get='bidirectional',
            set='bidirectional',
            list=False,
            type=ValueType.BOOLEAN,
            usage=_('Defines if a replication task does support inverting master/slave roles.')
        )

        self.add_property(
            descr='Automatic recovery',
            name='auto_recover',
            get='auto_recover',
            set='auto_recover',
            condition=lambda o: o.get('bidirectional'),
            list=False,
            type=ValueType.BOOLEAN,
            usage=_('''\
            Enables automatic replication stream invert when initial master
            becomes down/unreachable. Once initial master goes back online
            replication streams are being inverted again
            to match initial direction.''')
        )

        self.add_property(
            descr='Initial master side',
            name='initial_master',
            get=get_initial_master,
            usersetable=False,
            createsetable=False,
            list=False,
            usage=_('Informs which host was initially selected a replication master.')
        )

        self.add_property(
            descr='Recursive',
            name='recursive',
            get='recursive',
            set='recursive',
            list=False,
            type=ValueType.BOOLEAN,
            usage=_('Defines if selected datasets should be replicated recursively.')
        )

        self.add_property(
            descr='Services replication',
            name='replicate_services',
            get='replicate_services',
            set='replicate_services',
            condition=lambda o: o.get('bidirectional'),
            list=False,
            type=ValueType.BOOLEAN,
            usage=_('''\
            When set, in bidirectional replication case,
            enables FreeNAS machines to attempt to recreate services
            (such as shares) on new master after role swap.''')
        )

        self.add_property(
            descr='Transfer encryption',
            name='encryption',
            get=get_encrypt,
            set=set_encrypt,
            enum=['no', 'AES128', 'AES192', 'AES256'],
            list=False,
            usage=_('''\
            Encryption algorithm used during replication stream send operation.
            Can be one of: 'no', 'AES128', 'AES192', 'AES256'.''')
        )

        self.add_property(
            descr='Transfer throttle',
            name='throttle',
            get=get_throttle,
            set=set_throttle,
            list=False,
            type=ValueType.SIZE,
            usage=_('Maximum transfer speed during replication. Value in B/s.')
        )

        self.add_property(
            descr='Transfer compression',
            name='compression',
            get=get_compress,
            set=set_compress,
            enum=['no', 'FAST', 'DEFAULT', 'BEST'],
            list=False,
            usage=_('''\
            Compression algorithm used during replication stream send operation.
            Can be one of: 'no', 'FAST', 'DEFAULT', 'BEST'.''')
        )

        self.add_property(
            descr='Snapshot lifetime',
            name='snapshot_lifetime',
            get='snapshot_lifetime',
            set=lambda o, v: q.set(o, 'snapshot_lifetime', parse_timedelta(str(v)).seconds),
            list=False,
            type=ValueType.NUMBER,
            usage=_('Lifetime of snapshots created for replication purposes.')
        )

        self.add_property(
            descr='Follow delete',
            name='followdelete',
            get='followdelete',
            set='followdelete',
            list=False,
            type=ValueType.BOOLEAN,
            usage=_('''\
            Defines if replication should automatically remove
            stale snapshots at slave side.''')
        )

        self.add_property(
            descr='Current status',
            name='status',
            get='current_state.status',
            usersetable=False,
            createsetable=False,
            list=False,
            type=ValueType.STRING,
            usage=_('Current status of replication.')
        )

        self.add_property(
            descr='Current progress',
            name='progress',
            get=lambda o: '{0:.2f}'.format(round(q.get(o, 'current_state.progress'), 2)) + '%',
            usersetable=False,
            createsetable=False,
            list=False,
            type=ValueType.STRING,
            condition=lambda o: q.get(o, 'current_state.status') == 'RUNNING',
            usage=_('Current progress of replication.')
        )

        self.add_property(
            descr='Last speed',
            name='speed',
            get='current_state.speed',
            usersetable=False,
            createsetable=False,
            list=False,
            type=ValueType.STRING,
            condition=lambda o: q.get(o, 'current_state.status') == 'RUNNING',
            usage=_('Transfer speed of current replication run.')
        )

        self.primary_key = self.get_mapping('name')

        self.entity_commands = self.get_entity_commands
Пример #16
0
 def complete(self, context, **kwargs):
     return [
         EnumComplete('name=', q.query(DockerImageNamespace.default_images, select='name')),
         EntitySubscriberComplete('host=', 'docker.host', lambda d: d['name'])
     ]
Пример #17
0
Файл: backup.py Проект: zoot/cli
 def complete(self, context, **kwargs):
     return [
         EntitySubscriberComplete('dataset=', 'volume.dataset'),
         NullComplete('snapshot=')
     ]