示例#1
0
    def run(self, ups):
        node = ConfigNode('service.ups', self.configstore).__getstate__()
        if 'monitor_password' in ups:
            ups['monitor_password'] = ups['monitor_password'].secret

        node.update(ups)

        if node['mode'] == 'MASTER' and (not node['driver_port'] or not node['driver']):
            raise TaskException(errno.EINVAL, 'Please provide a valid port and driver for monitored UPS device')

        if node['mode'] == 'SLAVE' and not node['remote_host']:
            raise TaskException(errno.EINVAL, 'remote_host field is required in SLAVE mode')

        if not re.search(r'^[a-z0-9\.\-_]+$', node['identifier'], re.I):
            raise TaskException(errno.EINVAL, 'Use alphanumeric characters, ".", "-" and "_"')

        for i in ('monitor_user', 'monitor_password'):
            if re.search(r'[ #]', node[i], re.I):
                raise TaskException(errno.EINVAL, 'Spaces or number signs are not allowed')

        try:
            node = ConfigNode('service.ups', self.configstore)
            node.update(ups)
            self.dispatcher.call_sync('etcd.generation.generate_group', 'services')
            self.dispatcher.call_sync('etcd.generation.generate_group', 'ups')
            self.dispatcher.dispatch_event('service.ups.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(
                errno.ENXIO, 'Cannot reconfigure UPS: {0}'.format(str(e))
            )

        return 'RESTART'
示例#2
0
    def run(self, settings):
        node = ConfigNode('network', self.configstore)
        node.update(settings)

        if node['dhcp.assign_gateway']:
            # Clear out gateway settings
            node['gateway.ipv4'] = None

        if node['dhcp.assign_dns']:
            # Clear out DNS settings
            node['dns.addresses'] = []
            node['dns.search'] = []

        configure_proxy(self.dispatcher, node['http_proxy'].value)

        try:
            for code, message in self.dispatcher.call_sync(
                    'networkd.configuration.configure_network', timeout=60):
                self.add_warning(TaskWarning(code, message))

            self.dispatcher.call_sync('etcd.generation.generate_group',
                                      'network')
        except RpcException as e:
            raise TaskException(
                errno.ENXIO,
                'Cannot reconfigure interface: {0}'.format(str(e)))
示例#3
0
    def run(self, rsyncd):
        config = ConfigNode('service.rsyncd', self.configstore).__getstate__()

        if rsyncd.get('port') and is_port_open(rsyncd['port']):
            service_state = self.dispatcher.call_sync(
                'service.query', [('name', '=', 'rsyncd')], {
                    'single': True,
                    'select': 'state'
                })

            if not (service_state == "RUNNING"
                    and rsyncd['port'] == config['port']):
                raise TaskException(errno.EINVAL,
                                    'Provided port is already in use')

        try:
            node = ConfigNode('service.rsyncd', self.configstore)
            node.update(rsyncd)
            self.dispatcher.call_sync('etcd.generation.generate_group',
                                      'rsyncd')
            self.dispatcher.dispatch_event('service.rsyncd.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(
                errno.ENXIO, 'Cannot reconfigure Rsyncd: {0}'.format(str(e)))
示例#4
0
    def run(self, ftp):
        if ftp.get('filemask'):
            ftp['filemask'] = get_integer(ftp['filemask'])

        if ftp.get('dirmask'):
            ftp['dirmask'] = get_integer(ftp['dirmask'])

        if ftp.get('anonymous_path'):
            if not os.path.exists(ftp['anonymous_path']):
                raise TaskException(
                    errno.ENOENT, 'Directory {0} does not exists'.format(
                        ftp['anonymous_path']))

        try:
            node = ConfigNode('service.ftp', self.configstore)
            node.update(ftp)
            self.dispatcher.call_sync('etcd.generation.generate_group', 'ftp')
            self.dispatcher.dispatch_event('service.ftp.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(errno.ENXIO,
                                'Cannot reconfigure FTP: {0}'.format(str(e)))

        return 'RESTART'
示例#5
0
    def run(self, ipfs):
        try:
            node = ConfigNode('service.ipfs', self.configstore)
            old_path = node['path'].value
            if 'path' in ipfs and ipfs['path'] != old_path:
                if not os.path.exists(ipfs['path']):
                    os.makedirs(ipfs['path'])
                    # jkh says that the ipfs path should be owned by root
                    os.chown(ipfs['path'], 0, 0)
                # Only move the contents and not the entire folder
                # there could be other stuff in that folder
                # (a careless user might have merged this with his other files)
                # also this folder could be a dataset in which case a simple move will fail
                # so lets just move the internal contents of this folder over
                if old_path is not None and os.path.exists(old_path):
                    try:
                        for item in os.listdir(old_path):
                            shutil.move(old_path + '/' + item, ipfs['path'])
                    except shutil.Error as serr:
                        raise TaskException(
                            errno.EIO,
                            "Migrating ipfs path resulted in error: {0}".format(serr))
            node.update(ipfs)
            self.dispatcher.call_sync('etcd.generation.generate_group', 'services')
            self.dispatcher.dispatch_event('service.ipfs.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(
                errno.ENXIO, 'Cannot reconfigure IPFS: {0}'.format(str(e))
            )

        return 'RELOAD'
示例#6
0
    def run(self, ups):
        node = ConfigNode('service.ups', self.configstore).__getstate__()
        node.update(ups)

        if node['mode'] == 'MASTER' and (not node['driver_port'] or not node['driver']):
            raise TaskException(errno.EINVAL, 'Please provide a valid port and driver for monitored UPS device')

        if node['mode'] == 'SLAVE' and not node['remote_host']:
            raise TaskException(errno.EINVAL, 'This field is required')

        if not re.search(r'^[a-z0-9\.\-_]+$', node['identifier'], re.I):
            raise TaskException(errno.EINVAL, 'Use alphanumeric characters, ".", "-" and "_"')

        for i in ('monitor_user', 'monitor_password'):
            if re.search(r'[ #]', node[i], re.I):
                raise TaskException(errno.EINVAL, 'Spaces or number signs are not allowed')

        try:
            node = ConfigNode('service.ups', self.configstore)
            node.update(ups)
            self.dispatcher.call_sync('etcd.generation.generate_group', 'services')
            self.dispatcher.call_sync('etcd.generation.generate_group', 'ups')
            self.dispatcher.dispatch_event('service.ups.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(
                errno.ENXIO, 'Cannot reconfigure UPS: {0}'.format(str(e))
            )

        return 'RESTART'
示例#7
0
    def run(self, ipfs):
        try:
            node = ConfigNode('service.ipfs', self.configstore)
            old_path = node['path'].value
            if 'path' in ipfs and ipfs['path'] != old_path:
                if not os.path.exists(ipfs['path']):
                    os.makedirs(ipfs['path'])
                    # jkh says that the ipfs path should be owned by root
                    os.chown(ipfs['path'], 0, 0)
                # Only move the contents and not the entire folder
                # there could be other stuff in that folder
                # (a careless user might have merged this with his other files)
                # also this folder could be a dataset in which case a simple move will fail
                # so lets just move the internal contents of this folder over
                if old_path is not None and os.path.exists(old_path):
                    try:
                        for item in os.listdir(old_path):
                            shutil.move(old_path + '/' + item, ipfs['path'])
                    except shutil.Error as serr:
                        raise TaskException(
                            errno.EIO,
                            "Migrating ipfs path resulted in error: {0}".format(serr))
            node.update(ipfs)
            self.dispatcher.call_sync('etcd.generation.generate_group', 'ipfs')
            self.dispatcher.dispatch_event('service.ipfs.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(
                errno.ENXIO, 'Cannot reconfigure IPFS: {0}'.format(str(e))
            )

        return 'RESTART'
    def run(self, dc):
        self.set_progress(0, 'Checking Domain Controller service state')
        node = ConfigNode('service.dc', self.configstore).__getstate__()
        node.update(dc)
        if not node.get('volume'):
            raise TaskException(
                errno.ENXIO,
                'Domain controller service is hosted by the virtual machine.'
                'Please provide the valid zfs pool name for the virtual machine volume creation.'
            )

        else:
            try:
                self.dispatcher.call_sync(
                    'service.dc.check_dc_vm_availability')
            except RpcException:
                dc['vm_id'] = self.run_subtask_sync(
                    'vm.create', {
                        'name': 'zentyal_domain_controller',
                        'template': {
                            'name': 'zentyal-4.2'
                        },
                        'target': node['volume'],
                        'config': {
                            'autostart': True
                        }
                    },
                    progress_callback=lambda p, m, e=None: self.chunk_progress(
                        5, 100, 'Creating Domain Controller virtual machine: ',
                        p, m, e))
            finally:
                vm_config = self.dispatcher.call_sync(
                    'vm.query', [('id', '=', dc.get('vm_id', node['vm_id']))],
                    {
                        'select': 'config',
                        'single': True
                    })
                if not node['enable'] and vm_config['autostart']:
                    vm_config['autostart'] = False
                elif node['enable'] and not vm_config['autostart']:
                    vm_config['autostart'] = True

                self.run_subtask_sync(
                    'vm.update',
                    dc['vm_id'] if dc.get('vm_id') else node['vm_id'],
                    {'config': vm_config})

        try:
            node = ConfigNode('service.dc', self.configstore)
            node.update(dc)

            self.dispatcher.dispatch_event('service.dc.changed', {
                'operation': 'update',
                'ids': None,
            })

        except RpcException as e:
            raise TaskException(
                errno.ENXIO,
                'Cannot reconfigure DC vm service: {0}'.format(str(e)))
示例#9
0
    def run(self, snmp):
        node = ConfigNode("service.snmp", self.configstore).__getstate__()
        node.update(snmp)

        if node["contact"]:
            if "@" in node["contact"]:
                if not jsonschema._format.is_email(node["contact"]):
                    raise TaskException(errno.EINVAL, "Invalid e-mail address")
            elif not re.match(r"^[-_a-zA-Z0-9\s]+$", node["contact"]):
                raise TaskException(
                    errno.EINVAL, "Must contain only alphanumeric characters, _, - or a valid e-mail address"
                )

        if not node["community"]:
            if not node["v3"]:
                raise TaskException(errno.ENOENT, "This field is required")
        elif not re.match(r"^[-_a-zA-Z0-9\s]+$", node["community"]):
            raise TaskException(errno.EINVAL, "The community must contain only alphanumeric characters, _ or -")

        if node["v3_password"] and len(node["v3_password"]) < 8:
            raise TaskException(errno.EINVAL, "Password must contain at least 8 characters")

        if node["v3_privacy_passphrase"] and len(node["v3_privacy_passphrase"]) < 8:
            raise TaskException(errno.EINVAL, "Passphrase must contain at least 8 characters")

        try:
            node = ConfigNode("service.snmp", self.configstore)
            node.update(snmp)
            self.dispatcher.call_sync("etcd.generation.generate_group", "snmpd")
            self.dispatcher.dispatch_event("service.snmp.changed", {"operation": "updated", "ids": None})
        except RpcException as e:
            raise TaskException(errno.ENXIO, "Cannot reconfigure SNMP: {0}".format(str(e)))

        return "RESTART"
示例#10
0
    def verify(self, openvpn):
        interface_pattern = '(tap|tun)[0-9]'
        node = ConfigNode('service.openvpn', self.configstore).__getstate__()
        node.update(openvpn)
        
        if not re.search(interface_pattern, node['dev']):
            raise VerifyException(errno.EINVAL,
                                  '{0} Bad interface name. Allowed values tap/tun[0-9].'.format(node['dev']))
	
        if 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['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 run(self, ssh):
        config = self.dispatcher.call_sync('service.query',
                                           [('name', '=', 'sshd')], {
                                               'single': True,
                                               'select': 'config'
                                           })
        port = ssh.get('port')
        if port and port != config['port'] and is_port_open(port):
            raise TaskException(
                errno.EBUSY,
                'Port number : {0} is already in use'.format(port))

        try:
            node = ConfigNode('service.sshd', self.configstore)
            node.update(ssh)
            self.dispatcher.call_sync('etcd.generation.generate_group', 'sshd')
            self.dispatcher.dispatch_event('service.sshd.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(errno.ENXIO,
                                'Cannot reconfigure SSH: {0}'.format(str(e)))

        return 'RELOAD'
示例#12
0
    def verify(self, snmp):
        errors = []

        node = ConfigNode('service.snmp', self.configstore).__getstate__()
        node.update(snmp)

        if node['contact']:
            if '@' in node['contact']:
                if not jsonschema._format.is_email(node['contact']):
                    errors.append(('contact', errno.EINVAL, 'Invalid e-mail address'))
            elif not re.match(r'^[-_a-zA-Z0-9\s]+$', node['contact']):
                errors.append(('contact', errno.EINVAL, (
                    'Must contain only alphanumeric characters, _, - or a valid e-mail address')
                ))

        if not node['community']:
            if not node['v3']:
                errors.append(('community', errno.ENOENT, 'This field is required'))
        elif not re.match(r'^[-_a-zA-Z0-9\s]+$', node['community']):
            errors.append(('community', errno.EINVAL, (
                'The community must contain only alphanumeric characters, _ or -')
            ))

        if node['v3_password'] and len(node['v3_password']) < 8:
            errors.append(('v3_password', errno.EINVAL, 'Password must contain at least 8 characters'))

        if node['v3_privacy_passphrase'] and len(node['v3_privacy_passphrase']) < 8:
            errors.append(('v3_password', errno.EINVAL, 'Passphrase must contain at least 8 characters'))

        if errors:
            raise ValidationException(errors)

        return ['system']
示例#13
0
    def run(self, smb):
        try:
            action = 'NONE'
            node = ConfigNode('service.smb', self.configstore)
            if smb.get('filemask'):
                smb['filemask'] = get_integer(smb['filemask'])
            if smb.get('dirmask'):
                smb['dirmask'] = get_integer(smb['dirmask'])
            node.update(smb)
            configure_params(node.__getstate__(), self.dispatcher.call_sync('service.smb.ad_enabled'))

            try:
                rpc = smbconf.SambaMessagingContext()
                rpc.reload_config()
            except OSError:
                action = 'RESTART'

            # XXX: Is restart to change netbios name/workgroup *really* needed?
            if 'netbiosname' in smb or 'workgroup' in smb:
                action = 'RESTART'

            self.dispatcher.dispatch_event('service.smb.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(
                errno.ENXIO, 'Cannot reconfigure SMB: {0}'.format(str(e))
            )

        return action
    def verify(self, ftp):
        errors = ValidationException()
        node = ConfigNode('service.ftp', self.configstore).__getstate__()
        node.update(ftp)

        pmin = node['passive_ports_min']
        if 'passive_ports_min' in ftp:
            if pmin and (pmin < 1024 or pmin > 65535):
                errors.add((0, 'passive_ports_min'), 'This value must be between 1024 and 65535, inclusive.')

        pmax = node['passive_ports_max']
        if 'passive_ports_max' in ftp:
            if pmax and (pmax < 1024 or pmax > 65535):
                errors.add((0, 'passive_ports_max'), 'This value must be between 1024 and 65535, inclusive.')
            elif pmax and pmin and pmin >= pmax:
                errors.add((0, 'passive_ports_max'),  'This value must be higher than minimum passive port.')

        if node['only_anonymous'] and not node['anonymous_path']:
            errors.add(
                ((0, 'anonymous_path'), errno.EINVAL, 'This field is required for anonymous login.')
            )

        if node['tls'] is True and not node['tls_ssl_certificate']:
            errors.add((0, 'tls_ssl_certificate'), 'TLS specified without certificate.')

        if node['tls_ssl_certificate']:
            cert = self.dispatcher.call_sync('crypto.certificate.query', [('id', '=', node['tls_ssl_certificate'])])
            if not cert:
                errors.add((0, 'tls_ssl_certificate'), 'SSL Certificate not found.')

        if errors:
            raise errors

        return ['system']
示例#15
0
    def run(self, nfs):
        config = self.dispatcher.call_sync('service.query',
                                           [('name', '=', 'nfs')],
                                           {'single': True})['config']
        for n in ('mountd_port', 'rpcstatd_port', 'rpclockd_port'):
            port = nfs.get(n)
            if port and port != config[n] and is_port_open(port, 'inet'):
                raise TaskException(
                    errno.EBUSY,
                    'Port number : {0} is already in use'.format(port))

        try:
            node = ConfigNode('service.nfs', self.configstore)
            node.update(nfs)
            self.dispatcher.call_sync('etcd.generation.generate_group',
                                      'services')
            self.dispatcher.call_sync('etcd.generation.generate_group', 'nfs')
            self.dispatcher.dispatch_event('service.nfs.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(errno.ENXIO,
                                'Cannot reconfigure NFS: {0}'.format(str(e)))

        return 'RESTART'
示例#16
0
    def run(self, ftp):
        if ftp.get('filemask'):
            ftp['filemask'] = get_integer(ftp['filemask'])

        if ftp.get('dirmask'):
            ftp['dirmask'] = get_integer(ftp['dirmask'])

        if ftp.get('anonymous_path'):
            if not os.path.exists(ftp['anonymous_path']):
                raise TaskException(errno.ENOENT,
                    'Directory {0} does not exists'.format(ftp['anonymous_path']))

        try:
            node = ConfigNode('service.ftp', self.configstore)
            node.update(ftp)
            self.dispatcher.call_sync('etcd.generation.generate_group', 'ftp')
            self.dispatcher.dispatch_event('service.ftp.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(
                errno.ENXIO, 'Cannot reconfigure FTP: {0}'.format(str(e))
            )

        return 'RESTART'
示例#17
0
    def run(self, afp):
        paths = [PosixPath(afp.get(y)) if afp.get(y) else None for y in ('dbpath', 'homedir_path')]
        for p in paths:
            if p and not p.exists():
                raise TaskException(errno.ENOENT, 'Path : {0} does not exist'.format(p.as_posix()))
            if p and not p.is_dir():
                raise TaskException(errno.ENOTDIR, 'Path : {0} is not a directory'.format(p.as_posix()))

        if afp.get('guest_user'):
            if not self.dispatcher.call_sync('user.query', [('username', '=', afp['guest_user'])], {'single': True}):
                raise TaskException(errno.EINVAL, 'User: {0} does not exist'.format(afp['guest_user']))

        try:
            node = ConfigNode('service.afp', self.configstore)
            node.update(afp)
            self.dispatcher.call_sync('etcd.generation.generate_group', 'services')
            self.dispatcher.call_sync('etcd.generation.generate_group', 'afp')
            self.dispatcher.dispatch_event('service.afp.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(
                errno.ENXIO, 'Cannot reconfigure AFP: {0}'.format(str(e))
            )

        return 'RELOAD'
示例#18
0
    def run(self, webdav):
        node = ConfigNode('service.webdav', self.configstore).__getstate__()
        node.update(webdav)

        if node['http_port'] == node['https_port']:
            raise TaskException(errno.EINVAL, 'HTTP and HTTPS ports cannot be the same')

        if 'HTTPS' in node['protocol'] and not node['certificate']:
            raise TaskException(errno.EINVAL, 'SSL protocol specified without choosing a certificate')

        if node['certificate']:
            cert = self.dispatcher.call_sync(
                'crypto.certificate.query',
                [('name', '=', node['certificate'])],
                {'single': True}
            )

            if not cert:
                raise TaskException(errno.ENOENT, 'SSL Certificate not found.')

        try:
            node = ConfigNode('service.webdav', self.configstore)
            node.update(webdav)
            self.dispatcher.call_sync('etcd.generation.generate_group', 'services')
            self.dispatcher.call_sync('etcd.generation.generate_group', 'webdav')
            self.dispatcher.dispatch_event('service.webdav.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(
                errno.ENXIO, 'Cannot reconfigure WebDAV: {0}'.format(str(e))
            )

        return 'RESTART'
    def run(self, id, updated_fields):
        service_def = self.datastore.get_by_id('service_definitions', id)
        node = ConfigNode('service.{0}'.format(service_def['name']), self.configstore)
        restart = False
        reload = False
        updated_config = updated_fields.get('config')

        if updated_config is None:
            return

        del updated_config['type']

        if service_def.get('task'):
            enable = updated_config.pop('enable', None)

            try:
                self.verify_subtask(service_def['task'], updated_config)
            except RpcException as err:
                new_err = ValidationException()
                new_err.propagate(err, [0], [1, 'config'])
                raise new_err

            result = self.join_subtasks(self.run_subtask(service_def['task'], updated_config))
            restart = result[0] == 'RESTART'
            reload = result[0] == 'RELOAD'

            if enable is not None:
                node['enable'] = enable
        else:
            node.update(updated_config)

            if service_def.get('etcd-group'):
                self.dispatcher.call_sync('etcd.generation.generate_group', service_def.get('etcd-group'))

            if 'enable' in updated_config:
                # Propagate to dependent services
                for i in service_def.get('dependencies', []):
                    svc_dep = self.datastore.get_by_id('service_definitions', i)
                    self.join_subtasks(self.run_subtask('service.update', i, {
                        'config': {
                            'type': 'service-{0}'.format(svc_dep['name']),
                            'enable': updated_config['enable']
                        }
                    }))

                if service_def.get('auto_enable'):
                    # Consult state of services dependent on us
                    for i in self.datastore.query('service_definitions', ('dependencies', 'in', service_def['name'])):
                        enb = self.configstore.get('service.{0}.enable', i['name'])
                        if enb != updated_config['enable']:
                            del updated_config['enable']
                            break

        self.dispatcher.call_sync('etcd.generation.generate_group', 'services')
        self.dispatcher.call_sync('service.apply_state', service_def['name'], restart, reload, timeout=30)
        self.dispatcher.dispatch_event('service.changed', {
            'operation': 'update',
            'ids': [service_def['id']]
        })
示例#20
0
    def get_config(self):
        node = ConfigNode('network', self.configstore).__getstate__()
        node.update({
            'gateway': self.dispatcher.call_sync('networkd.configuration.get_default_routes'),
            'dns': self.dispatcher.call_sync('networkd.configuration.get_dns_config')
        })

        return node
示例#21
0
    def run(self, updated_params):
        node = ConfigNode('directory', self.configstore)
        node.update(updated_params)

        try:
            self.dispatcher.call_sync('dscached.management.reload_config')
        except RpcException as e:
            raise TaskException(errno.ENXIO, 'Cannot reconfigure directory services: {0}'.format(str(e)))
    def run(self, updated_params):
        node = ConfigNode('directory', self.configstore)
        node.update(updated_params)

        try:
            self.dispatcher.call_sync('dscached.management.reload_config')
        except RpcException as e:
            raise TaskException(errno.ENXIO, 'Cannot reconfigure directory services: {0}'.format(str(e)))
示例#23
0
    def get_config(self):
        node = ConfigNode('network', self.configstore).__getstate__()
        node.update({
            'gateway': self.dispatcher.call_sync('networkd.configuration.get_default_routes'),
            'dns': self.dispatcher.call_sync('networkd.configuration.get_dns_config')
        })

        return node
示例#24
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']
示例#25
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']
示例#26
0
    def run(self, iscsi):
        try:
            node = ConfigNode('service.iscsi', self.configstore)
            node.update(iscsi)
            self.dispatcher.call_sync('etcd.generation.generate_group', 'ctl')
        except RpcException as e:
            raise TaskException(errno.ENXIO, 'Cannot reconfigure iSCSI: {0}'.format(str(e)))

        return 'RELOAD'
示例#27
0
 def run(self, iscsi):
     try:
         node = ConfigNode('service.iscsi', self.configstore)
         node.update(iscsi)
         self.dispatcher.call_sync('etcd.generation.generate_group', 'ctl')
     except RpcException as e:
         raise TaskException(errno.ENXIO, 'Cannot reconfigure iSCSI: {0}'.format(str(e)))
         
     return 'RELOAD'
示例#28
0
    def run(self, mail):
        node = ConfigNode('mail', self.dispatcher.configstore)
        node.update(mail)

        try:
            self.dispatcher.call_sync('etcd.generation.generate_group', 'mail')
        except RpcException, e:
            raise TaskException(errno.ENXIO,
                                'Cannot reconfigure mail: {0}'.format(str(e)))
示例#29
0
    def run(self, service, updated_fields):
        service_def = self.datastore.get_one('service_definitions', ('name', '=', service))
        node = ConfigNode('service.{0}'.format(service), self.dispatcher.configstore)
        node.update(updated_fields)

        self.dispatcher.dispatch_event('service.changed', {
            'operation': 'update',
            'ids': [service_def['id']]
        })
示例#30
0
    def run(self, settings):
        node = ConfigNode('network', self.configstore)
        node.update(settings)

        try:
            self.dispatcher.call_sync('networkd.configuration.configure_network')
            self.dispatcher.call_sync('etcd.generation.generate_group', 'network')
        except RpcException as e:
            raise TaskException(errno.ENXIO, 'Cannot reconfigure interface: {0}'.format(str(e)))
示例#31
0
    def run(self, smb):
        node = ConfigNode('service.smb', self.configstore).__getstate__()
        netbiosname = smb.get('netbiosname')
        if netbiosname is not None:
            for n in netbiosname:
                if not validate_netbios_name(n):
                    raise TaskException(errno.EINVAL, 'Invalid name {0}'.format(n))
        else:
            netbiosname = node['netbiosname']

        workgroup = smb.get('workgroup')
        if workgroup is not None:
            if not validate_netbios_name(workgroup):
                raise TaskException(errno.EINVAL, 'Invalid name')
        else:
            workgroup = node['workgroup']

        if workgroup.lower() in [i.lower() for i in netbiosname]:
            raise TaskException(errno.EINVAL, 'NetBIOS and Workgroup must be unique')

        if smb.get('guest_user'):
            if not self.dispatcher.call_sync('user.query', [('username', '=', smb['guest_user'])], {'single': True}):
                raise TaskException(errno.EINVAL, 'User: {0} does not exist'.format(smb['guest_user']))

        try:
            action = 'NONE'
            node = ConfigNode('service.smb', self.configstore)
            if smb.get('filemask'):
                smb['filemask'] = get_integer(smb['filemask'])

            if smb.get('dirmask'):
                smb['dirmask'] = get_integer(smb['dirmask'])

            node.update(smb)
            configure_params(node.__getstate__(), self.dispatcher.call_sync('service.smb.ad_enabled'))

            try:
                rpc = smbconf.SambaMessagingContext()
                rpc.reload_config()
            except OSError:
                action = 'RESTART'

            # XXX: Is restart to change netbios name/workgroup *really* needed?
            if 'netbiosname' in smb or 'workgroup' in smb:
                action = 'RESTART'

            self.dispatcher.dispatch_event('service.smb.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(
                errno.ENXIO, 'Cannot reconfigure SMB: {0}'.format(str(e))
            )

        return action
示例#32
0
    def run(self, dyndns):
        try:
            node = ConfigNode("service.dyndns", self.configstore)
            node.update(dyndns)
            self.dispatcher.call_sync("etcd.generation.generate_group", "dyndns")
            self.dispatcher.dispatch_event("service.dyndns.changed", {"operation": "updated", "ids": None})
        except RpcException as e:
            raise TaskException(errno.ENXIO, "Cannot reconfigure DynamicDNS: {0}".format(str(e)))

        return "RELOAD"
示例#33
0
    def verify(self, haproxy):
        errors = []

        node = ConfigNode('service.haproxy', self.configstore).__getstate__()
        node.update(haproxy)

        if errors:
            raise ValidationException(errors)

        return ['system']
示例#34
0
    def verify(self, riakcs):
        errors = []

        node = ConfigNode('service.riak_cs', self.configstore).__getstate__()
        node.update(riakcs)

        if errors:
            raise ValidationException(errors)

        return ['system']
示例#35
0
    def verify(self, stanchion):
        errors = []

        node = ConfigNode("service.stanchion", self.configstore).__getstate__()
        node.update(stanchion)

        if errors:
            raise ValidationException(errors)

        return ["system"]
示例#36
0
    def verify(self, glusterd):
        errors = []

        node = ConfigNode('service.glusterd', self.configstore).__getstate__()
        node.update(glusterd)

        if errors:
            raise ValidationException(errors)

        return ['system']
示例#37
0
    def run(self, mail):
        node = ConfigNode('mail', self.dispatcher.configstore)
        node.update(mail)

        try:
            self.dispatcher.call_sync('etcd.generation.generate_group', 'mail')
        except RpcException, e:
            raise TaskException(
                errno.ENXIO, 'Cannot reconfigure mail: {0}'.format(str(e))
            )
示例#38
0
    def run(self, ftp):
        try:
            node = ConfigNode("service.ftp", self.configstore)
            node.update(ftp)
            self.dispatcher.call_sync("etcd.generation.generate_group", "ftp")
            self.dispatcher.dispatch_event("service.ftp.changed", {"operation": "updated", "ids": None})
        except RpcException as e:
            raise TaskException(errno.ENXIO, "Cannot reconfigure FTP: {0}".format(str(e)))

        return "RESTART"
示例#39
0
    def verify(self, ftp):
        errors = ValidationException()
        node = ConfigNode('service.ftp', self.configstore).__getstate__()
        node.update(ftp)

        pmin = node['passive_ports_min']
        if 'passive_ports_min' in ftp:
            if pmin and (pmin < 1024 or pmin > 65535):
                errors.add(
                    (0, 'passive_ports_min'),
                    'This value must be between 1024 and 65535, inclusive.')

        pmax = node['passive_ports_max']
        if 'passive_ports_max' in ftp:
            if pmax and (pmax < 1024 or pmax > 65535):
                errors.add(
                    (0, 'passive_ports_max'),
                    'This value must be between 1024 and 65535, inclusive.')
            elif pmax and pmin and pmin >= pmax:
                errors.add(
                    (0, 'passive_ports_max'),
                    'This value must be higher than minimum passive port.')

        if not all((pmax, pmin)) and any((pmax, pmin)):
            errors.add(
                (0, 'passive_ports_max' if pmin else 'passive_ports_min'),
                'You cannot just supply only one of "passive_ports_max" or "passive_ports_min"'
                + 'Either both stay none or both have valid values in them')

        if node['only_anonymous'] and not node['anonymous_path']:
            errors.add((0, 'anonymous_path'),
                       'This field is required for anonymous login.')

        if node['tls'] is True and not node['tls_ssl_certificate']:
            errors.add((0, 'tls_ssl_certificate'),
                       'TLS specified without certificate.')

        if node['tls_ssl_certificate']:
            cert = self.dispatcher.call_sync(
                'crypto.certificate.query',
                [('id', '=', node['tls_ssl_certificate'])])
            if not cert:
                errors.add((0, 'tls_ssl_certificate'),
                           'SSL Certificate not found.')

        if node['only_anonymous'] and node['only_local']:
            errors.add((
                0, 'only_anonymous'
            ), 'Anonymous only and local only types of authentication cannot be enabled together.'
                       )

        if errors:
            raise errors

        return ['system']
示例#40
0
    def run(self, openvpn_updated):
        node = ConfigNode('service.openvpn', self.configstore).__getstate__()
        node.update(openvpn_updated)

        if node['mode'] == 'pki':

                ca_cert_id = self.datastore.query('crypto.certificates',
                                                  ('name', '=', node['ca']), select=('id'))
                ca_cert_name = self.datastore.query('crypto.certificates',
                                                    ('id', '=', node['ca']), select=('name'))

                if not ca_cert_id:
                    if not ca_cert_name:
                        raise TaskException(errno.EINVAL,
                                            'Provided CA certificate does not exist in config database.')

                else:
                        openvpn_updated['ca'] = ca_cert_id[0]

                cert_id = self.datastore.query('crypto.certificates',
                                               ('name', '=', node['cert']), select=('id'))
                cert_name = self.datastore.query('crypto.certificates',
                                                 ('id', '=', node['cert']), select=('name'))

                if not cert_id:
                    if not cert_name:
                        raise TaskException(errno.EINVAL,
                                            'Provided certificate does not exist in config database.')
                else:
                    openvpn_updated['cert'] = cert_id[0]
                    openvpn_updated['key'] = cert_id[0]

                openvpn_user = self.datastore.exists('users', ('username', '=', node['user']))
                if not openvpn_user:
                    raise TaskException(errno.EINVAL, 'Provided user does not exist.')

                openvpn_group = self.datastore.exists('groups', ('name', '=', node['group']))
                if not openvpn_group:
                    raise TaskException(errno.EINVAL, 'Provided user does not exist.')

        try:
            node = ConfigNode('service.openvpn', self.configstore)
            node.update(openvpn_updated)

            self.dispatcher.call_sync('etcd.generation.generate_group', 'openvpn')
            self.dispatcher.dispatch_event('service.openvpn.changed', {
                'operation': 'update',
                'ids': None,
            })

        except RpcException as e:
            raise TaskException(errno.ENXIO,
                                'Cannot reconfigure OpenVPN: {0}'.format(str(e)))

        return 'RESTART'
示例#41
0
    def run(self, openvpn_updated):
        node = ConfigNode('service.openvpn', self.configstore).__getstate__()
        node.update(openvpn_updated)

        if node['mode'] == 'pki':

                ca_cert_id = self.datastore.query('crypto.certificates',
                                                  ('name', '=', node['ca']), select=('id'))
                ca_cert_name = self.datastore.query('crypto.certificates',
                                                    ('id', '=', node['ca']), select=('name'))

                if not ca_cert_id:
                    if not ca_cert_name:
                        raise TaskException(errno.EINVAL,
                                            'Provided CA certificate does not exist in config database.')

                else:
                        openvpn_updated['ca'] = ca_cert_id[0]

                cert_id = self.datastore.query('crypto.certificates',
                                               ('name', '=', node['cert']), select=('id'))
                cert_name = self.datastore.query('crypto.certificates',
                                                 ('id', '=', node['cert']), select=('name'))

                if not cert_id:
                    if not cert_name:
                        raise TaskException(errno.EINVAL,
                                            'Provided certificate does not exist in config database.')
                else:
                    openvpn_updated['cert'] = cert_id[0]
                    openvpn_updated['key'] = cert_id[0]

                openvpn_user = self.datastore.exists('users', ('username', '=', node['user']))
                if not openvpn_user:
                    raise TaskException(errno.EINVAL, 'Provided user does not exist.')

                openvpn_group = self.datastore.exists('groups', ('name', '=', node['group']))
                if not openvpn_group:
                    raise TaskException(errno.EINVAL, 'Provided user does not exist.')

        try:
            node = ConfigNode('service.openvpn', self.configstore)
            node.update(openvpn_updated)

            self.dispatcher.call_sync('etcd.generation.generate_group', 'openvpn')
            self.dispatcher.dispatch_event('service.openvpn.changed', {
                'operation': 'update',
                'ids': None,
            })

        except RpcException as e:
            raise TaskException(errno.ENXIO,
                                'Cannot reconfigure OpenVPN: {0}'.format(str(e)))

        return 'RESTART'
示例#42
0
    def run(self, dc):
        self.set_progress(0, 'Checking Domain Controller service state')
        node = ConfigNode('service.dc', self.configstore).__getstate__()
        node.update(dc)
        if not node.get('volume'):
            raise TaskException(
                errno.ENXIO,
                'Domain controller service is hosted by the virtual machine.'
                'Please provide the valid zfs pool name for the virtual machine volume creation.'
            )

        else:
            try:
                self.dispatcher.call_sync('service.dc.check_dc_vm_availability')
            except RpcException:
                dc['vm_id'] = self.run_subtask_sync('vm.create', {
                    'name': 'zentyal_domain_controller',
                    'template': {'name': 'zentyal-4.2'},
                    'target': node['volume'],
                    'config': {'autostart': True}},
                    progress_callback=lambda p, m, e=None: self.chunk_progress(
                        5, 100, 'Creating Domain Controller virtual machine: ', p, m, e
                    )
                )
            finally:
                vm_config = self.dispatcher.call_sync(
                    'vm.query',
                    [('id', '=', dc.get('vm_id', node['vm_id']))],
                    {'select': 'config', 'single': True}
                )
                if not node['enable'] and vm_config['autostart']:
                    vm_config['autostart'] = False
                elif node['enable'] and not vm_config['autostart']:
                    vm_config['autostart'] = True

                self.run_subtask_sync(
                    'vm.update',
                    dc['vm_id'] if dc.get('vm_id') else node['vm_id'],
                    {'config': vm_config}
                )

        try:
            node = ConfigNode('service.dc', self.configstore)
            node.update(dc)

            self.dispatcher.dispatch_event('service.dc.changed', {
                'operation': 'update',
                'ids': None,
            })

        except RpcException as e:
            raise TaskException(errno.ENXIO,
                                'Cannot reconfigure DC vm service: {0}'.format(str(e)))
示例#43
0
    def run(self, smb):
        node = ConfigNode('service.smb', self.configstore).__getstate__()
        netbiosname = smb.get('netbiosname')
        if netbiosname is not None:
            for n in netbiosname:
                if not validate_netbios_name(n):
                    raise TaskException(errno.EINVAL, 'Invalid name {0}'.format(n))
        else:
            netbiosname = node['netbiosname']

        workgroup = smb.get('workgroup')
        if workgroup is not None:
            if not validate_netbios_name(workgroup):
                raise TaskException(errno.EINVAL, 'Invalid name')
        else:
            workgroup = node['workgroup']

        if workgroup.lower() in [i.lower() for i in netbiosname]:
            raise TaskException(errno.EINVAL, 'NetBIOS and Workgroup must be unique')

        try:
            action = 'NONE'
            node = ConfigNode('service.smb', self.configstore)
            if smb.get('filemask'):
                smb['filemask'] = get_integer(smb['filemask'])

            if smb.get('dirmask'):
                smb['dirmask'] = get_integer(smb['dirmask'])

            node.update(smb)
            configure_params(node.__getstate__(), self.dispatcher.call_sync('service.smb.ad_enabled'))

            try:
                rpc = smbconf.SambaMessagingContext()
                rpc.reload_config()
            except OSError:
                action = 'RESTART'

            # XXX: Is restart to change netbios name/workgroup *really* needed?
            if 'netbiosname' in smb or 'workgroup' in smb:
                action = 'RESTART'

            self.dispatcher.dispatch_event('service.smb.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(
                errno.ENXIO, 'Cannot reconfigure SMB: {0}'.format(str(e))
            )

        return action
示例#44
0
    def run(self, settings):
        node = ConfigNode('network', self.dispatcher.configstore)
        node.update(settings)

        try:
            self.dispatcher.call_sync(
                'networkd.configuration.configure_network')
            self.dispatcher.call_sync('etcd.generation.generate_group',
                                      'network')
        except RpcException, e:
            raise TaskException(
                errno.ENXIO,
                'Cannot reconfigure interface: {0}'.format(str(e)))
示例#45
0
 def run(self, rsyncd):
     try:
         node = ConfigNode('service.rsyncd', self.configstore)
         node.update(rsyncd)
         self.dispatcher.call_sync('etcd.generation.generate_group',
                                   'rsyncd')
         self.dispatcher.dispatch_event('service.rsyncd.changed', {
             'operation': 'updated',
             'ids': None,
         })
     except RpcException as e:
         raise TaskException(
             errno.ENXIO, 'Cannot reconfigure Rsyncd: {0}'.format(str(e)))
示例#46
0
 def run(self, rsyncd):
     try:
         node = ConfigNode('service.rsyncd', self.configstore)
         node.update(rsyncd)
         self.dispatcher.call_sync('etcd.generation.generate_group', 'rsyncd')
         self.dispatcher.dispatch_event('service.rsyncd.changed', {
             'operation': 'updated',
             'ids': None,
         })
     except RpcException as e:
         raise TaskException(
             errno.ENXIO, 'Cannot reconfigure Rsyncd: {0}'.format(str(e))
         )
    def run(self, lldp):
        try:
            node = ConfigNode('service.lldp', self.configstore)
            node.update(lldp)
            self.dispatcher.dispatch_event('service.lldp.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(
                errno.ENXIO, 'Cannot reconfigure LLDP: {0}'.format(str(e))
            )

        return 'RELOAD'
    def verify(self, lldp):
        errors = ValidationException()
        node = ConfigNode('service.lldp', self.configstore).__getstate__()
        node.update(lldp)

        # Lazy load pycountry due to extra verbose DEBUG logging
        import pycountry
        if node['country_code'] and node['country_code'] not in pycountry.countries.indices['alpha2']:
            errors.add((0, 'country_code'), 'Invalid ISO-3166 alpha 2 code')

        if errors:
            raise errors

        return ['system']
示例#49
0
    def run(self, glusterd):
        try:
            node = ConfigNode('service.glusterd', self.configstore)
            node.update(glusterd)
            self.dispatcher.dispatch_event('service.glusterd.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(
                errno.ENXIO, 'Cannot reconfigure Glusterd: {0}'.format(str(e))
            )

        return 'RESTART'
示例#50
0
    def run(self, snmp):
        node = ConfigNode('service.snmp', self.configstore).__getstate__()
        if 'v3_password' in snmp:
            snmp['v3_password'] = unpassword(snmp['v3_password'])

        node.update(snmp)

        if node['contact']:
            if '@' in node['contact']:
                if not jsonschema._format.is_email(node['contact']):
                    raise TaskException(errno.EINVAL, 'Invalid e-mail address')
            elif not re.match(r'^[-_a-zA-Z0-9\s]+$', node['contact']):
                raise TaskException(
                    errno.EINVAL,
                    'Must contain only alphanumeric characters, _, - or a valid e-mail address'
                )

        if not node['community']:
            if not node['v3']:
                raise TaskException(errno.ENOENT, 'This field is required')
        elif not re.match(r'^[-_a-zA-Z0-9\s]+$', node['community']):
            raise TaskException(
                errno.EINVAL,
                'The community must contain only alphanumeric characters, _ or -'
            )

        if node['v3_password'] and len(node['v3_password']) < 8:
            raise TaskException(errno.EINVAL,
                                'Password must contain at least 8 characters')

        if node['v3_privacy_passphrase'] and len(
                node['v3_privacy_passphrase']) < 8:
            raise TaskException(
                errno.EINVAL, 'Passphrase must contain at least 8 characters')

        try:
            node = ConfigNode('service.snmp', self.configstore)
            node.update(snmp)
            self.dispatcher.call_sync('etcd.generation.generate_group',
                                      'snmpd')
            self.dispatcher.dispatch_event('service.snmp.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(errno.ENXIO,
                                'Cannot reconfigure SNMP: {0}'.format(str(e)))

        return 'RESTART'
示例#51
0
    def run(self, dyndns):
        try:
            node = ConfigNode('service.dyndns', self.configstore)
            node.update(dyndns)
            self.dispatcher.call_sync('etcd.generation.generate_group', 'dyndns')
            self.dispatcher.dispatch_event('service.dyndns.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(
                errno.ENXIO, 'Cannot reconfigure DynamicDNS: {0}'.format(str(e))
            )

        return 'RELOAD'
示例#52
0
    def run(self, tftp):
        try:
            node = ConfigNode('service.tftpd', self.configstore)
            tftp['umask'] = get_integer(tftp['umask'])
            node.update(tftp)
            self.dispatcher.call_sync('etcd.generation.generate_group',
                                      'services')
            self.dispatcher.dispatch_event('service.tftpd.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(errno.ENXIO,
                                'Cannot reconfigure TFTP: {0}'.format(str(e)))

        return 'RESTART'
示例#53
0
    def run(self, lldp):
        node = ConfigNode('service.lldp', self.configstore).__getstate__()
        node.update(lldp)
        import pycountry
        if node['country_code'] and node[
                'country_code'] not in pycountry.countries.indices['alpha2']:
            raise TaskException(errno.EINVAL, 'Invalid ISO-3166 alpha 2 code')

        try:
            self.dispatcher.dispatch_event('service.lldp.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(errno.ENXIO,
                                'Cannot reconfigure LLDP: {0}'.format(str(e)))

        return 'RELOAD'
示例#54
0
    def run(self, rsyncd):

        if rsyncd.get('port') and is_port_open(rsyncd['port']):
            raise TaskException(errno.EINVAL,
                                'Provided port is already in use')

        try:
            node = ConfigNode('service.rsyncd', self.configstore)
            node.update(rsyncd)
            self.dispatcher.call_sync('etcd.generation.generate_group',
                                      'rsyncd')
            self.dispatcher.dispatch_event('service.rsyncd.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(
                errno.ENXIO, 'Cannot reconfigure Rsyncd: {0}'.format(str(e)))
示例#55
0
    def run(self, webdav):
        node = ConfigNode('service.webdav', self.configstore).__getstate__()
        if 'password' in webdav:
            webdav['password'] = unpassword(webdav['password'])

        for p in ('http_port', 'https_port'):
            port = webdav.get(p)
            if port and port != node[p] and is_port_open(port):
                raise TaskException(
                    errno.EBUSY,
                    'Port number : {0} is already in use'.format(port))

        node.update(webdav)

        if node['http_port'] == node['https_port']:
            raise TaskException(errno.EINVAL,
                                'HTTP and HTTPS ports cannot be the same')

        if 'HTTPS' in node['protocol'] and not node['certificate']:
            raise TaskException(
                errno.EINVAL,
                'SSL protocol specified without choosing a certificate')

        if node['certificate'] and not self.dispatcher.call_sync(
                'crypto.certificate.query', [('id', '=', node['certificate'])],
            {'single': True}):
            raise TaskException(errno.ENOENT, 'SSL Certificate not found.')

        try:
            node = ConfigNode('service.webdav', self.configstore)
            node.update(webdav)
            self.dispatcher.call_sync('etcd.generation.generate_group',
                                      'services')
            self.dispatcher.call_sync('etcd.generation.generate_group',
                                      'webdav')
            self.dispatcher.dispatch_event('service.webdav.changed', {
                'operation': 'updated',
                'ids': None,
            })
        except RpcException as e:
            raise TaskException(
                errno.ENXIO, 'Cannot reconfigure WebDAV: {0}'.format(str(e)))

        return 'RESTART'
示例#56
0
    def verify(self, ftp):
        errors = ValidationException()
        node = ConfigNode('service.ftp', self.configstore).__getstate__()
        node.update(ftp)

        pmin = node['passive_ports_min']
        if 'passive_ports_min' in ftp:
            if pmin and (pmin < 1024 or pmin > 65535):
                errors.add(
                    (0, 'passive_ports_min'),
                    'This value must be between 1024 and 65535, inclusive.')

        pmax = node['passive_ports_max']
        if 'passive_ports_max' in ftp:
            if pmax and (pmax < 1024 or pmax > 65535):
                errors.add(
                    (0, 'passive_ports_max'),
                    'This value must be between 1024 and 65535, inclusive.')
            elif pmax and pmin and pmin >= pmax:
                errors.add(
                    (0, 'passive_ports_max'),
                    'This value must be higher than minimum passive port.')

        if node['only_anonymous'] and not node['anonymous_path']:
            errors.add((0, 'anonymous_path'), errno.EINVAL,
                       'This field is required for anonymous login.')

        if node['tls'] is True and not node['tls_ssl_certificate']:
            errors.add((0, 'tls_ssl_certificate'),
                       'TLS specified without certificate.')

        if node['tls_ssl_certificate']:
            cert = self.dispatcher.call_sync(
                'crypto.certificate.query',
                [('id', '=', node['tls_ssl_certificate'])])
            if not cert:
                errors.add((0, 'tls_ssl_certificate'),
                           'SSL Certificate not found.')

        if errors:
            raise errors

        return ['system']
示例#57
0
    def run(self, id, updated_fields):
        service_def = self.datastore.get_by_id('service_definitions', id)
        if not service_def:
            raise TaskException(errno.ENOENT,
                                'Service {0} not found'.format(id))

        if 'config' in updated_fields:
            for x in updated_fields['config']:
                if x == 'type':
                    continue

                if not self.configstore.exists('service.{0}.{1}'.format(
                        service_def['name'], x)):
                    raise TaskException(
                        errno.ENOENT,
                        'Service {0} does not have the following key: {1}'.
                        format(service_def['name'], x))

        node = ConfigNode('service.{0}'.format(service_def['name']),
                          self.configstore)
        restart = False
        reload = False
        updated_config = updated_fields.get('config')
        if updated_config is None:
            return

        enable = not node['enable'].value and updated_config['enable']
        disable = node['enable'].value and not updated_config['enable']
        updated_config.pop('type', None)

        if service_def.get('task'):
            try:
                self.verify_subtask(service_def['task'], updated_config)
            except RpcException as err:
                new_err = ValidationException()
                new_err.propagate(err, [0], [1, 'config'])
                raise new_err

            result = self.run_subtask_sync(service_def['task'],
                                           updated_config,
                                           progress_callback=self.set_progress)

            restart = result == 'RESTART'
            reload = result == 'RELOAD'

            if updated_config.get('enable') is not None:
                node['enable'] = updated_config['enable']
        else:
            node.update(updated_config)

            if service_def.get('etcd-group'):
                self.dispatcher.call_sync('etcd.generation.generate_group',
                                          service_def.get('etcd-group'))

        if 'enable' in updated_config:
            # Propagate to dependent services
            for i in service_def.get('dependencies', []):
                svc_dep = self.datastore.get_by_id('service_definitions', i)
                self.run_subtask_sync(
                    'service.update', i, {
                        'config': {
                            'type': 'service-{0}'.format(svc_dep['name']),
                            'enable': updated_config['enable']
                        }
                    })

            if service_def.get('auto_enable'):
                # Consult state of services dependent on us
                for i in self.datastore.query(
                        'service_definitions',
                    ('dependencies', 'in', service_def['name'])):
                    enb = self.configstore.get('service.{0}.enable', i['name'])
                    if enb != updated_config['enable']:
                        del updated_config['enable']
                        break

        if 'launchd' in service_def:
            if enable:
                load_job(self.dispatcher, service_def)

            if disable:
                unload_job(self.dispatcher, service_def)

        self.dispatcher.call_sync('etcd.generation.generate_group', 'services')
        self.dispatcher.call_sync('service.apply_state',
                                  service_def['name'],
                                  restart,
                                  reload,
                                  timeout=120)
        self.dispatcher.dispatch_event('service.changed', {
            'operation': 'update',
            'ids': [service_def['id']]
        })
示例#58
0
 def run(self, updated_fields):
     node = ConfigNode('service.consul', self.configstore).__getstate__()
     node.update(updated_fields)
     return 'RELOAD'