for i in range(start_gid, end_gid): if not self.datastore.exists('groups', ('gid', '=', i)): gid = i break if not gid: raise RpcException(errno.ENOSPC, 'No free GIDs available') return gid @description("Create an user in the system") @accepts(h.all_of( h.ref('user'), h.required('username'), h.forbidden('builtin'), h.object(properties={'password': {'type': ['string', 'null']}}), h.any_of( h.required('password'), h.required('unixhash', 'nthash'), h.required('password_disabled') ) )) class UserCreateTask(Task): def __init__(self, dispatcher, datastore): super(UserCreateTask, self).__init__(dispatcher, datastore) self.id = None self.created_group = False @classmethod def early_describe(cls):
return TaskDescription(self.early_describe()) def verify(self, updated_params): return ["system"] 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))) @accepts(h.ref("directory"), h.required("name", "type"), h.forbidden("immutable")) @returns(str) class DirectoryServiceCreateTask(Task): @classmethod def early_describe(cls): return "Creating a directory" def describe(self, directory): return TaskDescription("Creating directory {name}", name=directory["name"]) def verify(self, directory): return ["system"] def run(self, directory): try: params = self.dispatcher.call_sync(
self.datastore.query_stream('crypto.certificates', callback=extend), *(filter or []), stream=True, **(params or {}) ) @accepts() @returns(h.object()) def get_country_codes(self): return COUNTRY_CODES @accepts(h.all_of( h.ref('crypto-certificate'), h.required('type', 'name', 'country', 'state', 'city', 'organization', 'email', 'common'), h.forbidden('certificate_path', 'privatekey_path'), )) @description('Creates a certificate') class CertificateCreateTask(Task): @classmethod def early_describe(cls): return "Creating certificate" def describe(self, certificate): return TaskDescription("Creating certificate {name}", name=certificate['name']) def verify(self, certificate): certificate['selfsigned'] = certificate.get('selfsigned', False) certificate['signing_ca_name'] = certificate.get('signing_ca_name', False) if '"' in certificate['name']:
node['dns.addresses'] = [] node['dns.search'] = [] 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))) @accepts(h.all_of( h.ref('network-interface'), h.required('type'), h.forbidden('id', 'status') )) @returns(str) @description('Creates network interface') class CreateInterfaceTask(Task): @classmethod def early_describe(cls): return "Creating network interface" def describe(self, iface): return TaskDescription("Creating {name} network interface", name=iface['type']) def verify(self, iface): return ['system'] def run(self, iface):
def get_temp_pubkeys(self): for k in temp_pubkeys: yield k @private def remove_temp_pubkey(self, key): try: temp_pubkeys.remove(key) except ValueError: pass @description('Exchanges SSH keys with remote FreeNAS machine') @accepts( h.all_of(h.ref('peer'), h.required('type', 'credentials'), h.forbidden('name'))) class FreeNASPeerCreateTask(Task): @classmethod def early_describe(cls): return 'Exchanging SSH keys with remote host' def describe(self, peer, initial_credentials): return TaskDescription('Exchanging SSH keys with the remote {name}', name=q.get(peer, 'credentials.address', '')) def verify(self, peer, initial_credentials): credentials = peer['credentials'] remote = credentials.get('address') username = initial_credentials.get('username') password = initial_credentials.get('password')
'properties': {} }) backup['properties'] = self.run_subtask_sync('backup.{0}.init'.format(backup['provider']), backup) id = self.datastore.insert('backup', backup) self.dispatcher.emit_event('backup.changed', { 'operation': 'create', 'ids': [id] }) return id @accepts(str, h.all_of( h.ref('backup'), h.forbidden('id', 'provider', 'dataset') )) @description('Updates a backup task') class UpdateBackupTask(Task): @classmethod def early_describe(cls): return 'Updating backup task' def describe(self, id, updated_params): backup = self.datastore.get_by_id('backup', id) return TaskDescription('Updating backup task {name}', name=backup.get('name', id) if backup else id) def verify(self, id, updated_params): return ['system'] def run(self, id, updated_params):
*(filter or []), stream=True, **(params or {})) @accepts() @returns(h.object()) def get_country_codes(self): return COUNTRY_CODES @accepts( h.all_of( h.ref('CryptoCertificate'), h.required('type', 'name', 'country', 'state', 'city', 'organization', 'email', 'common'), h.forbidden('certificate_path', 'privatekey_path'), )) @description('Creates a certificate') class CertificateCreateTask(Task): @classmethod def early_describe(cls): return "Creating certificate" def describe(self, certificate): return TaskDescription("Creating certificate {name}", name=certificate['name']) def verify(self, certificate): certificate['selfsigned'] = certificate.get('selfsigned', False) certificate['signing_ca_name'] = certificate.get( 'signing_ca_name', None)
for i in range(start_gid, end_gid): if not self.datastore.exists('groups', ('gid', '=', i)): gid = i break if not gid: raise RpcException(errno.ENOSPC, 'No free GIDs available') return gid @description("Create an user in the system") @accepts(h.all_of( h.ref('User'), h.required('username'), h.forbidden('builtin'), h.object(properties={'password': {'type': ['password', 'null']}}), h.any_of( h.required('password'), h.required('unixhash', 'nthash'), h.required('password_disabled') ) )) class UserCreateTask(Task): def __init__(self, dispatcher): super(UserCreateTask, self).__init__(dispatcher) self.id = None self.created_group = False @classmethod def early_describe(cls):
def run(self, keytab): if self.datastore.exists('kerberos.keytabs', ('name', '=', keytab['name'])): raise TaskException(errno.EEXIST, 'Keytab {0} already exists'.format(keytab['name'])) id = self.datastore.insert('kerberos.keytabs', keytab) generate_keytab(self.datastore) self.dispatcher.dispatch_event('kerberos.keytab.changed', { 'operation': 'create', 'ids': [id] }) return id @accepts(str, h.all_of( h.ref('KerberosKeytab'), h.forbidden('keytab', 'entries') )) class KerberosKeytabUpdateTask(Task): def verify(self, id, updated_fields): return ['system'] def run(self, id, updated_fields): if not self.datastore.exists('kerberos.keytabs', ('id', '=', id)): raise TaskException(errno.ENOENT, 'Keytab with ID {0} doesn\'t exist'.format(id)) keytab = self.datastore.get_by_id('kerberos.keytabs', id) keytab.update(updated_fields) self.datastore.update('kerberos.keytabs', id, keytab) generate_keytab(self.datastore) self.dispatcher.dispatch_event('kerberos.keytab.changed', { 'operation': 'update',
normalize(backup, {'properties': {}}) backup['properties'], = self.join_subtasks( self.run_subtask('backup.{0}.init'.format(backup['provider']), backup)) id = self.datastore.insert('backup', backup) self.dispatcher.emit_event('backup.changed', { 'operation': 'create', 'ids': [id] }) return id @accepts(str, h.all_of(h.ref('backup'), h.forbidden('id', 'provider', 'dataset'))) @description('Updates a backup task') class UpdateBackupTask(Task): @classmethod def early_describe(cls): return 'Updating backup task' def describe(self, id, updated_params): backup = self.datastore.get_by_id('backup', id) return TaskDescription('Updating backup task {name}', name=backup.get('name', id) if backup else id) def verify(self, id, updated_params): return ['system'] def run(self, id, updated_params):
def join(self, id): self.dispatcher.call_sync('dsd.configuration.join_activedirectory', id) def enable(self, id): self.dispatcher.call_sync('dsd.configuration.enable', id) def disable(self, id): self.dispatcher.call_sync('dsd.configuration.disable', id) @description("Create directory service") @accepts( h.all_of( h.ref('directoryservice'), h.required('name', 'domain'), h.forbidden('id') ) ) class DirectoryServiceCreateTask(Task): def verify(self, directoryservice): dstypes = self.dispatcher.call_sync('dsd.configuration.get_supported_directories') type = directoryservice['type'] if type not in dstypes: raise VerifyException(errno.ENXIO, 'Unknown directory service type {0}'.format(directoryservice[type])) directoryservices = self.dispatcher.call_sync('dsd.configuration.get_directory_services') for ds in directoryservices: if ds['type'] == type: raise VerifyException(errno.EEXIST, 'THERE CAN ONLY BE ONE!') return ['directoryservice']
('name', '=', keytab['name'])): raise TaskException( errno.EEXIST, 'Keytab {0} already exists'.format(keytab['name'])) id = self.datastore.insert('kerberos.keytabs', keytab) generate_keytab(self.datastore) self.dispatcher.dispatch_event('kerberos.keytab.changed', { 'operation': 'create', 'ids': [id] }) return id @accepts(str, h.all_of(h.ref('kerberos-keytab'), h.forbidden('keytab', 'entries'))) class KerberosKeytabUpdateTask(Task): def verify(self, id, updated_fields): return ['system'] def run(self, id, updated_fields): if not self.datastore.exists('kerberos.keytabs', ('id', '=', id)): raise TaskException(errno.ENOENT, 'Keytab with ID {0} doesn\'t exist'.format(id)) keytab = self.datastore.get_by_id('kerberos.keytabs', id) keytab.update(updated_fields) self.datastore.update('kerberos.keytabs', id, keytab) generate_keytab(self.datastore) self.dispatcher.dispatch_event('kerberos.keytab.changed', { 'operation': 'update',
gid = None for i in range(start_gid, end_gid): if not self.datastore.exists('groups', ('gid', '=', i)): gid = i break if not gid: raise RpcException(errno.ENOSPC, 'No free GIDs available') return gid @description("Create an user in the system") @accepts( h.all_of( h.ref('User'), h.required('username'), h.forbidden('builtin'), h.object(properties={'password': { 'type': ['password', 'null'] }}), h.any_of(h.required('password'), h.required('unixhash', 'nthash'), h.required('password_disabled')))) class UserCreateTask(Task): def __init__(self, dispatcher): super(UserCreateTask, self).__init__(dispatcher) self.id = None self.created_group = False @classmethod def early_describe(cls): return "Creating user"
self.dispatcher.call_sync('service.restart', 'nginx') except RpcException as e: raise TaskException( errno.ENXIO, 'Cannot reconfigure system UI: {0}'.format(str(e)) ) self.dispatcher.dispatch_event('system.ui.changed', { 'operation': 'update', 'ids': ['system.ui'], }) @accepts(h.all_of( h.ref('SystemTime'), h.forbidden('boot_time', 'uptime') )) @description("Configures system time") class SystemTimeConfigureTask(Task): @classmethod def early_describe(cls): return 'Configuring system time' def describe(self, props): return TaskDescription('Configuring system time') def verify(self, props): return ['system'] def run(self, props): if 'system_time' in props:
node.update(updated_params) self.dispatcher.emit_event('directoryservice.changed', { 'operation': 'update' }) 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))) @accepts( h.ref('Directory'), h.required('name', 'type'), h.forbidden('immutable') ) @returns(str) class DirectoryServiceCreateTask(Task): @classmethod def early_describe(cls): return "Creating a directory" def describe(self, directory): return TaskDescription("Creating directory {name}", name=directory.get('name', '')) def verify(self, directory): return ['system'] def run(self, directory): try:
'properties': {} }) backup['properties'] = self.run_subtask_sync('backup.{0}.init'.format(backup['provider']), backup) id = self.datastore.insert('backup', backup) self.dispatcher.emit_event('backup.changed', { 'operation': 'create', 'ids': [id] }) return id @accepts(str, h.all_of( h.ref('Backup'), h.forbidden('id', 'provider', 'dataset') )) @description('Updates a backup task') class UpdateBackupTask(Task): @classmethod def early_describe(cls): return 'Updating backup task' def describe(self, id, updated_params): backup = self.datastore.get_by_id('backup', id) return TaskDescription('Updating backup task {name}', name=backup.get('name', id) if backup else id) def verify(self, id, updated_params): return ['system'] def run(self, id, updated_params):
for k in temp_pubkeys: yield k @private def remove_temp_pubkey(self, key): try: temp_pubkeys.remove(key) except ValueError: pass @description('Exchanges SSH keys with remote FreeNAS machine') @accepts(h.all_of( h.ref('peer'), h.required('type', 'credentials'), h.forbidden('name') )) class FreeNASPeerCreateTask(Task): @classmethod def early_describe(cls): return 'Exchanging SSH keys with remote host' def describe(self, peer, initial_credentials): return TaskDescription('Exchanging SSH keys with the remote {name}', name=q.get(peer, 'credentials.address', '')) def verify(self, peer, initial_credentials): credentials = peer['credentials'] remote = credentials.get('address') username = initial_credentials.get('username') password = initial_credentials.get('password')
if p.metadata and p.metadata.get('type') == 'alert_emitter': config = self.dispatcher.call_sync( 'alert.emitter.{0}.get_config'.format( p.metadata['name'])) yield { 'id': p.metadata['id'], 'name': p.metadata['name'], 'config': config } return q.query(collect(), *(filter or []), **(params or {})) @description("Creates an Alert Filter") @accepts( h.all_of(h.ref('AlertFilter'), h.forbidden('id'), h.required('emitter', 'parameters'))) class AlertFilterCreateTask(Task): @classmethod def early_describe(cls): return 'Creating alert filter' def describe(self, alertfilter): return TaskDescription('Creating alert filter') def verify(self, alertfilter): return ['system'] def run(self, alertfilter): normalize(alertfilter, {'clazz': None, 'predicates': []})
self.dispatcher.call_sync('services.reload', 'nginx') except RpcException as e: raise TaskException( errno.ENXIO, 'Cannot reconfigure system UI: {0}'.format(str(e),) ) self.dispatcher.dispatch_event('system.ui.changed', { 'operation': 'update', 'ids': ['system.ui'], }) @accepts(h.all_of( h.ref('system-time'), h.forbidden('boot_time', 'uptime') )) @description("Configures system time") class SystemTimeConfigureTask(Task): def verify(self, props): return ['system'] def run(self, props): if 'system_time' in props: timestamp = time.mktime(parser.parse(props['system_time'])) bsd.clock_settime(bsd.ClockType.REALTIME, timestamp) if 'timezone' in props: self.configstore.set('system.timezone', props['timezone']) try: self.dispatcher.call_sync('etcd.generation.generate_group', 'localtime')
raise VerifyException(errno.ENOENT, 'Interface {0} does not exist'.format(name)) return ['system'] def run(self, name): self.datastore.delete('network.interfaces', name) try: self.dispatcher.call_sync('networkd.configuration.configure_network') except RpcException as e: raise TaskException(errno.ENXIO, 'Cannot reconfigure network: {0}'.format(str(e))) @description("Alters network interface configuration") @accepts(str, h.all_of( h.ref('network-interface'), h.forbidden('id', 'type') )) class ConfigureInterfaceTask(Task): def verify(self, name, updated_fields): if not self.datastore.exists('network.interfaces', ('id', '=', name)): raise VerifyException(errno.ENOENT, 'Interface {0} does not exist'.format(name)) return ['system'] def run(self, name, updated_fields): task = 'networkd.configuration.configure_interface' if updated_fields.get('dhcp'): # Check for DHCP inconsistencies # 1. Check whether DHCP is enabled on other interfaces # 2. Check whether DHCP configures default route and/or DNS server addresses
def run(self, updated_params): node = ConfigNode('directory', self.configstore) node.update(updated_params) self.emit_event('directoryservice.changed', {'operation': 'update'}) 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))) @accepts(h.ref('Directory'), h.required('name', 'type'), h.forbidden('immutable')) @returns(str) class DirectoryServiceCreateTask(Task): @classmethod def early_describe(cls): return "Creating a directory" def describe(self, directory): return TaskDescription("Creating directory {name}", name=directory.get('name', '')) def verify(self, directory): return ['system'] def run(self, directory): try:
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))) @accepts( h.all_of(h.ref('NetworkInterface'), h.required('type'), h.forbidden('id', 'status'))) @returns(str) @description('Creates network interface') class CreateInterfaceTask(Task): @classmethod def early_describe(cls): return "Creating network interface" def describe(self, iface): return TaskDescription("Creating {name} network interface", name=iface['type']) def verify(self, iface): return ['system'] def run(self, iface):
if action in ('stop', 'restart'): self.dispatcher.call_sync('serviced.job.stop', i['Label']) if action in ('start', 'restart'): self.dispatcher.call_sync('serviced.job.start', i['Label']) self.dispatcher.dispatch_event('service.changed', { 'operation': 'update', 'ids': [service['id']] }) @description("Updates configuration for services") @accepts(str, h.all_of( h.ref('service'), h.forbidden('id', 'name', 'builtin', 'pid', 'state') )) class UpdateServiceConfigTask(Task): @classmethod def early_describe(cls): return 'Updating service configuration' def describe(self, id, updated_fields): svc = self.datastore.get_by_id('service_definitions', id) return TaskDescription("Updating configuration of service {name}", name=svc['name']) def verify(self, id, updated_fields): return ['system'] def run(self, id, updated_fields): service_def = self.datastore.get_by_id('service_definitions', id)
try: self.dispatcher.call_sync('etcd.generation.generate_group', 'nginx') self.dispatcher.call_sync('service.restart', 'nginx') except RpcException as e: raise TaskException( errno.ENXIO, 'Cannot reconfigure system UI: {0}'.format(str(e))) self.dispatcher.dispatch_event('system.ui.changed', { 'operation': 'update', 'ids': ['system.ui'], }) @accepts(h.all_of(h.ref('SystemTime'), h.forbidden('boot_time', 'uptime'))) @description("Configures system time") class SystemTimeConfigureTask(Task): @classmethod def early_describe(cls): return 'Configuring system time' def describe(self, props): return TaskDescription('Configuring system time') def verify(self, props): return ['system'] def run(self, props): if 'system_time' in props: timestamp = time.mktime(parser.parse(props['system_time']))
if action in ('stop', 'restart'): self.dispatcher.call_sync('serviced.job.stop', i['Label']) if action in ('start', 'restart'): self.dispatcher.call_sync('serviced.job.start', i['Label']) self.dispatcher.dispatch_event('service.changed', { 'operation': 'update', 'ids': [service['id']] }) @description("Updates configuration for services") @accepts(str, h.all_of(h.ref('Service'), h.forbidden('id', 'name', 'builtin', 'pid', 'state'))) class UpdateServiceConfigTask(ProgressTask): @classmethod def early_describe(cls): return 'Updating service configuration' def describe(self, id, updated_fields): svc = self.datastore.get_by_id('service_definitions', id) return TaskDescription("Updating configuration of service {name}", name=svc['name']) def verify(self, id, updated_fields): return ['system'] def run(self, id, updated_fields): service_def = self.datastore.get_by_id('service_definitions', id)
for p in list(self.dispatcher.plugins.values()): if p.metadata and p.metadata.get('type') == 'alert_emitter': config = self.dispatcher.call_sync('alert.emitter.{0}.get_config'.format(p.metadata['name'])) yield { 'id': p.metadata['id'], 'name': p.metadata['name'], 'config': config } return q.query(collect(), *(filter or []), **(params or {})) @description("Creates an Alert Filter") @accepts(h.all_of( h.ref('AlertFilter'), h.forbidden('id'), h.required('emitter', 'parameters') )) class AlertFilterCreateTask(Task): @classmethod def early_describe(cls): return 'Creating alert filter' def describe(self, alertfilter): return TaskDescription('Creating alert filter') def verify(self, alertfilter): return ['system'] def run(self, alertfilter): normalize(alertfilter, {