示例#1
0
    def run(self, config_path, name, type):
        try:
            share = load_config(config_path, f'{type}-{name}', version=CONFIG_VERSION)
        except FileNotFoundError:
            raise VerifyException(
                errno.ENOENT,
                f'There is no share {name} of type {type} at {config_path} to be imported.'
            )
        except ValueError as err:
            raise VerifyException(errno.EINVAL, f'Cannot read configuration file: {err}')

        if share['type'] != type:
            raise VerifyException(
                errno.EINVAL,
                f'Share type {type} does not match configuration file entry type {share["type"]}'
            )

        if not self.dispatcher.call_sync('share.supported_types').get(share['type']):
            raise TaskException(errno.ENXIO, f'Unknown sharing type {share["type"]}')

        if self.datastore.exists(
            'shares',
            ('type', '=', share['type']),
            ('name', '=', share['name'])
        ):
            raise TaskException(errno.EEXIST, 'Share {share["name"]} of type {share["type"]} already exists')

        id = self.run_subtask_sync(f'share.{share["type"]}.import', share)
        self.dispatcher.dispatch_event('share.changed', {
            'operation': 'create',
            'ids': [id]
        })

        return id
示例#2
0
    def verify(self, certificate):
        certificate['selfsigned'] = certificate.get('selfsigned', False)
        certificate['signing_ca_name'] = certificate.get(
            'signing_ca_name', None)

        if '"' in certificate['name']:
            raise VerifyException(errno.EINVAL,
                                  'Provide certificate name without : `"`')

        if certificate['type'] in ('CERT_INTERNAL', 'CA_INTERNAL',
                                   'CA_INTERMEDIATE'):
            if not certificate['selfsigned'] and not certificate[
                    'signing_ca_name']:
                raise VerifyException(
                    errno.ENOENT,
                    'Either "selfsigned" or "signing_ca_name" field value must be specified'
                )
            if certificate['selfsigned'] and certificate['signing_ca_name']:
                raise VerifyException(
                    errno.ENOENT,
                    'Only one of "selfsigned","signing_ca_name" fields should be specified'
                )

        if certificate['type'] == 'CA_INTERMEDIATE':
            if not certificate['signing_ca_name']:
                raise VerifyException(
                    errno.ENOENT,
                    '"signing_ca_name" field value not specified')

        return ['system']
示例#3
0
    def verify(self, user):

        errors = []

        for code, message in check_unixname(user['username']):
            errors.append(('name', code, message))

        if self.datastore.exists('users', ('username', '=', user['username'])):
            raise VerifyException(errno.EEXIST,
                                  'User with given name already exists')

        if 'id' in user and self.datastore.exists('users',
                                                  ('id', '=', user['id'])):
            raise VerifyException(errno.EEXIST,
                                  'User with given UID already exists')

        if 'groups' in user and len(user['groups']) > 64:
            errors.append(
                ('groups', errno.EINVAL,
                 'User cannot belong to more than 64 auxiliary groups'))

        if 'full_name' in user and ':' in user['full_name']:
            errors.append(('full_name', errno.EINVAL,
                           'The character ":" is not allowed'))

        if errors:
            raise ValidationException(errors)

        return ['system']
示例#4
0
    def verify(self, config_path, name, type):
        try:
            share = load_config(config_path, '{0}-{1}'.format(type, name))
        except FileNotFoundError:
            raise VerifyException(
                errno.ENOENT,
                'There is no share {0} of type {1} at {2} to be imported.'.
                format(name, type, config_path))
        except ValueError:
            raise VerifyException(
                errno.EINVAL,
                'Cannot read configuration file. File is not a valid JSON file'
            )

        if share['type'] != type:
            raise VerifyException(
                errno.EINVAL,
                'Share type {0} does not match configuration file entry type {1}'
                .format(type, share['type']))

        if not self.dispatcher.call_sync('share.supported_types').get(
                share['type']):
            raise VerifyException(
                errno.ENXIO, 'Unknown sharing type {0}'.format(share['type']))

        return ['system']
示例#5
0
    def verify(self, peer, initial_credentials):
        credentials = peer['credentials']
        remote = credentials.get('address')
        if not initial_credentials:
            raise VerifyException(
                errno.EINVAL,
                'No credentials provided. Provide either username and password or token'
            )

        username = initial_credentials.get('username')
        password = initial_credentials.get('password')

        if not remote:
            raise VerifyException(
                errno.EINVAL, 'Address of remote host has to be specified')

        if not initial_credentials.get(
                'auth_code') and not initial_credentials.get('key_auth'):
            if not username:
                raise VerifyException(errno.EINVAL,
                                      'Username has to be specified')

            if not password:
                raise VerifyException(errno.EINVAL,
                                      'Password has to be specified')

        return ['system']
示例#6
0
    def verify(self, path, reboot_post_install=False):

        if not os.path.exists(path):
            raise VerifyException(errno.EEXIST, 'File does not exist')

        if not tarfile.is_tarfile(path):
            raise VerifyException(errno.EEXIST, 'File does not exist')

        return ['root']
示例#7
0
    def verify(self, disk, fstype, params=None):
        if not get_disk_by_path(disk):
            raise VerifyException(errno.ENOENT,
                                  "Disk {0} not found".format(disk))

        if fstype not in ['freebsd-zfs']:
            raise VerifyException(errno.EINVAL,
                                  "Unsupported fstype {0}".format(fstype))

        return ['disk:{0}'.format(disk)]
示例#8
0
    def verify(self, id):
        disk = self.datastore.get_by_id('disks', id)

        if not disk:
            raise VerifyException(errno.ENOENT,
                                  'Disk {0} not found'.format(id))

        if self.dispatcher.call_sync('disks.is_online', disk['path']):
            raise VerifyException(errno.EINVAL, 'Cannot delete online disk')

        return ['disk:{0}'.format(os.path.basename(disk['path']))]
示例#9
0
    def verify(self, id, new_name, params=None):
        if self.datastore.exists('volumes', ('id', '=', id)):
            raise VerifyException(
                errno.ENOENT, 'Volume with id {0} already exists'.format(id))

        if self.datastore.exists('volumes', ('name', '=', new_name)):
            raise VerifyException(
                errno.ENOENT,
                'Volume with name {0} already exists'.format(new_name))

        return self.verify_subtask('zfs.pool.import', id)
示例#10
0
    def verify(self, openvpn_updated):
        node = ConfigNode('service.openvpn', self.configstore).__getstate__()
        node.update(openvpn_updated)

        if node['dev'] not in ['tap', 'tun']:
            raise VerifyException(errno.EINVAL,
                                  '{0} Bad interface name. Allowed values tap/tun.'.format(node['dev']))
        if ((node['mode'] == 'pki' and node['dev'].startswith('tun'))
                or (node['mode'] == 'psk' and node['dev'].startswith('tap'))):
            raise VerifyException(errno.EINVAL,
                                  'tap interfaces can be used with pki scenario and tun with psk mode')

        if node['mode'] == 'pki' and (not node['ca'] or not node['cert']):
            raise VerifyException(errno.EINVAL,
                                  'For pki VPN mode ca and certyficate values are required')

        if node['mode'] == 'psk':
            try:
                ipaddress.ip_address(node['psk_server_ip'])
                ipaddress.ip_address(node['psk_remote_ip'])
            except ValueError as e:
                raise VerifyException(errno.EINVAL, str(e))

        if (node['server_bridge_extended']
            and not (node['server_bridge_ip'] or node['server_bridge_netmask']
                     or node['server_bridge_range_begin'] or node['server_bridge_range_end'])):

            raise VerifyException(errno.EINVAL,
                                  'For pki server_bridge_extended mode all server_bridge values are required')




        if node['mode'] == 'pki' and node['server_bridge_extended']:
            try:
                bridge_ip = ipaddress.ip_address(node['server_bridge_ip'])
                netmask = node['server_bridge_netmask']
                ip_range_begin = ipaddress.ip_address(node['server_bridge_range_begin'])
                ip_range_end = ipaddress.ip_address(node['server_bridge_range_end'])
                subnet = ipaddress.ip_network('{0}/{1}'.format(bridge_ip, netmask), strict=False)

            except ValueError as e:
                raise VerifyException(errno.EINVAL, str(e))

            if (ip_range_begin not in subnet) or (ip_range_end not in subnet):
                raise VerifyException(errno.EINVAL,
                                      'Provided range of remote client IP adresses is invalid.')

            if (bridge_ip >= ip_range_begin) and (bridge_ip <= ip_range_end):
                raise VerifyException(errno.EINVAL,
                                      'Provided bridge IP address is in the client ip range.')
        if node['mode'] == 'pki':
            if (node['keepalive_ping_interval'] * 2) >= node['keepalive_peer_down']:
                raise VerifyException(errno.EINVAL, 'The second parameter to keepalive must be'
                                      'at least twice the value of the first parameter.'
                                      'Recommended setting is keepalive 10 60.')

        return ['system']
示例#11
0
    def verify(self, id, updated_fields):
        disk = self.datastore.get_by_id('disks', id)

        if not disk:
            raise VerifyException(errno.ENOENT,
                                  'Disk {0} not found'.format(id))

        if not self.dispatcher.call_sync('disks.is_online', disk['path']):
            raise VerifyException(errno.EINVAL,
                                  'Cannot configure offline disk')

        return ['disk:{0}'.format(disk['path'])]
示例#12
0
    def verify(self, share):
        if share['target_type'] == 'FILE':
            # File extent
            if not os.path.exists(share['target_path']):
                raise VerifyException(errno.ENOENT, "Extent file does not exist")
        elif share['target_type'] == 'ZVOL':
            if not os.path.exists(os.path.join('/dev/zvol', share['target_path'])):
                raise VerifyException(errno.ENOENT, "Extent ZVol does not exist")
        else:
            raise VerifyException(errno.EINVAL, 'Unsupported target type {0}'.format(share['target_type']))

        return ['system']
示例#13
0
    def verify(self, certificate):

        if self.datastore.exists('crypto.certificates',
                                 ('name', '=', certificate['name'])):
            raise VerifyException(
                errno.EEXIST, 'Certificate with given name already exists')

        if not self.datastore.exists('crypto.certificates',
                                     ('id', '=', certificate['signedby'])):
            raise VerifyException(errno.EEXIST,
                                  'Signing Certificate does not exist')

        return ['system']
示例#14
0
    def verify(self, id, updated_fields):

        if not self.datastore.exists('crypto.certificates', ('id', '=', id)):
            raise VerifyException(
                errno.EEXIST, 'Certificate ID {0} does not exist'.format(id))

        try:
            load_certificate(updated_fields['certificate'])
        except crypto.Error as e:
            raise VerifyException(errno.EINVAL,
                                  'Invalid certificate: {0}'.format(str(e)))

        return ['system']
示例#15
0
    def verify(self, share):
        properties = share['properties']
        if (properties.get('maproot_user') or properties.get('maproot_group')) and \
           (properties.get('mapall_user') or properties.get('mapall_group')):
            raise VerifyException(
                errno.EINVAL,
                'Cannot set maproot and mapall properties simultaneously')

        if share['target_type'] != 'DATASET' and properties.get('alldirs'):
            raise VerifyException(
                errno.EINVAL, 'alldirs can be only used with dataset shares')

        return ['service:nfs']
示例#16
0
    def verify(self, uid):
        user = self.datastore.get_by_id('users', uid)

        if user is None:
            raise VerifyException(
                errno.ENOENT, 'User with UID {0} does not exists'.format(uid))

        if user['builtin']:
            raise VerifyException(
                errno.EPERM,
                'Cannot delete builtin user {0}'.format(user['username']))

        return ['system']
示例#17
0
    def verify(self, id):
        # Check if group exists
        group = self.datastore.get_one('groups', ('id', '=', id))
        if group is None:
            raise VerifyException(errno.ENOENT,
                                  'Group with given ID does not exists')

        if group['builtin'] is True:
            raise VerifyException(
                errno.EINVAL,
                'Group {0} is built-in and can not be deleted'.format(
                    group['name']))

        return ['system']
示例#18
0
    def verify(self, id, updated_fields):

        certificate = self.datastore.get_by_id('crypto.certificates', id)
        if certificate is None:
            raise VerifyException(
                errno.ENOENT, 'Certificate ID {0} does not exists'.format(id))

        if 'name' in updated_fields and self.datastore.exists(
                'crypto.certificates', ('name', '=', updated_fields['name']),
            ('id', '!=', id)):
            raise VerifyException(
                errno.EEXIST, 'Certificate with given name already exists')

        return ['system']
示例#19
0
    def verify(self, certificate):

        if self.datastore.exists('crypto.certificates',
                                 ('name', '=', certificate['name'])):
            raise VerifyException(
                errno.EEXIST, 'Certificate with given name already exists')

        try:
            load_privatekey(certificate['privatekey'],
                            certificate.get('passphrase'))
        except Exception:
            raise VerifyException(errno.EINVAL, 'Invalid passphrase')

        return ['system']
示例#20
0
 def verify(self, service, updated_fields):
     if not self.datastore.exists('service_definitions',
                                  ('name', '=', service)):
         raise VerifyException(
             errno.ENOENT,
             'Service {0} not found'.format(service))
     for x in updated_fields:
         if not self.dispatcher.configstore.exists(
                 'service.{0}.{1}'.format(service, x)):
             raise VerifyException(
                 errno.ENOENT,
                 'Service {0} does not have the following key: {1}'.format(
                     service, x))
     return ['system']
示例#21
0
    def verify(self, key_type, key_length):
        if key_type not in ['dh-parameters', 'tls-auth-key']:
            raise VerifyException(errno.EINVAL, 'Type dh-parameters or tls-auth-key')

        if key_length and key_type == 'dh-parameters':
            if key_length not in [1024, 2048]:
                raise VerifyException(errno.EINVAL,
                                      'You have to chose between 1024 and 2048 bits.')

        if not key_length and key_type == 'dh-parameters':
                raise VerifyException(errno.EINVAL,
                                      'You have to chose between 1024 and 2048 bits.')

        return['system']
示例#22
0
    def verify(self):
        if not update_cache.get('available', timeout=1):
            raise VerifyException(errno.ENOENT, (
                'No updates currently available for download - check for new updates'
            ))

        block = self.dispatcher.resource_graph.get_resource(
            update_resource_string)
        if block is not None and block.busy:
            raise VerifyException(
                errno.EBUSY,
                ('An Update Operation (Configuration/ Download/ Applying'
                 'the Updates) is already in the queue, please retry later'))

        return [update_resource_string]
示例#23
0
    def verify(self, peer, initial_credentials=None):
        if peer.get('type') not in self.dispatcher.call_sync(
                'peer.peer_types'):
            raise VerifyException(
                errno.EINVAL, 'Unknown peer type {0}'.format(peer.get('type')))

        return ['system']
示例#24
0
    def verify(self, share):
        if share['properties'].get(
                'guest_only') and not share['properties'].get('guest_ok'):
            raise VerifyException(
                errno.EINVAL, 'guest_only works only with guest_ok enabled')

        return ['service:smb']
示例#25
0
    def verify(self, id, updated_fields, force=False):

        ntp = self.datastore.get_by_id('ntpservers', id)
        if ntp is None:
            raise VerifyException(errno.ENOENT, 'NTP Server with given ID does not exists')

        errors = []

        try:
            if 'address' in updated_fields:
                system('ntpdate', '-q', updated_fields['address'])
        except SubprocessException:
            if not force:
                errors.append((
                    'address',
                    errno.EINVAL,
                    'Server could not be reached. Check "Force" to continue regardless.'))

        minpoll = updated_fields.get('minpoll', ntp.get('minpoll'))
        maxpoll = updated_fields.get('maxpoll', ntp.get('maxpoll'))

        if minpoll is not None and maxpoll is not None and not maxpoll > minpoll:
            errors.append(('maxpoll', errno.EINVAL, 'Max Poll should be higher than Min Poll'))

        if errors:
            raise ValidationException(errors)

        return ['system']
示例#26
0
    def verify(self, share, dataset_properties=None, enable_service=False):
        if not self.dispatcher.call_sync('share.supported_types').get(
                share['type']):
            raise VerifyException(
                errno.ENXIO, 'Unknown sharing type {0}'.format(share['type']))

        return ['system']
示例#27
0
    def verify(self, name):
        share = self.datastore.get_by_id('shares', name)
        if not share:
            raise VerifyException(errno.ENOENT, 'Share not found')

        self.share_type = share['type']
        return ['system']
示例#28
0
    def verify(self, id):
        certificate = self.datastore.get_by_id('crypto.certificates', id)
        if certificate is None:
            raise VerifyException(
                errno.ENOENT, 'Certificate ID {0} does not exists'.format(id))

        return ['system']
示例#29
0
    def verify(self, oldname, newname):
        be = FindClone(oldname)
        if not be:
            raise VerifyException(
                errno.ENOENT, 'Boot environment {0} not found'.format(oldname))

        return ['system']
示例#30
0
    def verify(self, disk):
        boot_pool_name = self.configstore.get('system.boot_pool_name')
        disk_id = self.dispatcher.call_sync('disk.path_to_id', disk)
        if not disk_id:
            raise VerifyException(f'Disk {disk} not found')

        return [f'zpool:{boot_pool_name}', f'disk:{disk_id}']