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
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']
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']
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']
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']
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']
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)]
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']))]
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)
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']
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'])]
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']
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']
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']
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']
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']
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']
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']
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']
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']
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']
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]
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']
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']
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']
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']
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']
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']
def verify(self, oldname, newname): be = FindClone(oldname) if not be: raise VerifyException( errno.ENOENT, 'Boot environment {0} not found'.format(oldname)) return ['system']
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}']