def query(self, filter=None, params=None): if not self.is_ipmi_loaded(): raise RpcException(errno.ENXIO, 'The IPMI device could not be found') result = [] for channel in self.channels(): try: out, err = system('/usr/local/bin/ipmitool', 'lan', 'print', str(channel)) except SubprocessException as e: raise RpcException( errno.EFAULT, 'Cannot receive IPMI configuration: {0}'.format( e.err.strip())) raw = {k.strip(): v.strip() for k, v in RE_ATTRS.findall(out)} ret = { IPMI_ATTR_MAP[k]: v for k, v in list(raw.items()) if k in IPMI_ATTR_MAP } ret['id'] = channel ret['vlan_id'] = None if ret.get( 'vlan_id') == 'Disabled' else ret.get('vlan_id') ret['dhcp'] = True if ret.get('dhcp') == 'DHCP Address' else False result.append(ret) return q.query(result, *(filter or []), stream=True, **(params or {}))
def ensure_started(self, service): # XXX launchd! svc = self.datastore.get_one('service_definitions', ('name', '=', service)) if not svc: raise RpcException(errno.ENOENT, 'Service {0} not found'.format(service)) if 'launchd' in svc: launchd = svc['launchd'] plists = [launchd] if isinstance(launchd, dict) else launchd for i in plists: self.dispatcher.call_sync('serviced.job.start', i['Label']) return if 'start_rpc' in svc: try: self.dispatcher.call_sync(svc['start_rpc']) return True except RpcException: raise RpcException( errno.ENOENT, "Whilst starting service {0} rpc '{1}' failed".format( service, svc['start_rpc']))
def provide_dc_url(self): dc_vm = self.get_config() if dc_vm['vm_id'] and dc_vm['enable']: try: guest_info = self.dispatcher.call_sync('vm.get_guest_info', dc_vm['vm_id']) addresses = [] for name, config in guest_info['interfaces'].items(): if name.startswith('lo'): continue addresses += [ 'https://' + i['address'] + ':8443' for i in config['aliases'] if i['af'] != 'LINK' ] return addresses except RpcException: raise RpcException( errno.ENOENT, "Please wait - Domain Controller vm service is not ready or the zentyal_domain_controller " + "virtual machine state was altered manually.") else: raise RpcException( errno.ENOENT, 'Please configure and enable the Domain Controller vm service.' )
def getgrnam(self, name, skip_ad=False): # Try the cache first item = self.context.groups_cache.get(name=name) if item: if skip_ad and item.directory.plugin_type == 'winbind': raise RpcException(errno.ENOENT, 'Group {0} not found'.format(name)) return item.annotated if '@' in name: # Fully qualified group name name, domain_name = name.split('@', 1) dirs = [self.context.get_directory_by_domain(domain_name)] else: dirs = self.context.get_searched_directories() for d in dirs: if skip_ad and d.plugin_type == 'winbind': continue try: group = d.instance.getgrnam(name) except: continue if group: aliases = alias(d, group, 'name') item = CacheItem(group['gid'], group['id'], aliases, copy.copy(group), d, self.context.cache_ttl) self.context.groups_cache.set(item) return item.annotated raise RpcException(errno.ENOENT, 'Group {0} not found'.format(name))
def getpwuuid(self, uuid, skip_ad=False): # Try the cache first item = self.context.users_cache.get(uuid=uuid) if item: if skip_ad and item.directory.plugin_type == 'winbind': raise RpcException(errno.ENOENT, 'UUID {0} not found'.format(uuid)) return fix_passwords(item.annotated) for d in self.context.get_active_directories(): if skip_ad and d.plugin_type == 'winbind': continue try: user = d.instance.getpwuuid(uuid) except: continue if user: resolve_primary_group(self.context, user) aliases = alias(d, user, 'username') aliases.remove(user['username']) item = CacheItem(user['uid'], user['id'], aliases, copy.copy(user), d, self.context.cache_ttl) self.context.users_cache.set(item) return fix_passwords(item.annotated) raise RpcException(errno.ENOENT, 'UUID {0} not found'.format(uuid))
def getgruuid(self, uuid, skip_ad=False): # Try the cache first item = self.context.groups_cache.get(uuid=uuid) if item: if skip_ad and item.directory.plugin_type == 'winbind': raise RpcException(errno.ENOENT, 'UUID {0} not found'.format(uuid)) return item.annotated for d in self.context.get_active_directories(): if skip_ad and d.plugin_type == 'winbind': continue try: group = d.instance.getgruuid(uuid) except: continue if group: aliases = alias(d, group, 'name') item = CacheItem(group['gid'], group['id'], aliases, copy.copy(group), d, self.context.cache_ttl) self.context.groups_cache.set(item) return item.annotated raise RpcException(errno.ENOENT, 'UUID {0} not found'.format(uuid))
def categories_no_auth(self): version = self.dispatcher.call_sync('system.info.version') sw_name = version.split('-')[0].lower() project_name = '-'.join(version.split('-')[:2]).lower() try: r = requests.post( 'https://%s/%s/api/v1.0/categoriesnoauth' % (PROXY_ADDRESS, sw_name), data=json.dumps({'project': project_name}), headers={'Content-Type': 'application/json'}, timeout=10, ) data = r.json() except simplejson.JSONDecodeError as e: logger.debug('Failed to decode ticket attachment response: %s', r.text) raise RpcException(errno.EINVAL, 'Failed to decode ticket response') except requests.ConnectionError as e: raise RpcException(errno.ENOTCONN, 'Connection failed: {0}'.format(str(e))) except requests.Timeout as e: raise RpcException(errno.ETIMEDOUT, 'Connection timed out: {0}'.format(str(e))) if 'error' in data: raise RpcException(errno.EINVAL, data['message']) return data
def cancel(self, id: int) -> int: alert = self.datastore.get_by_id('alerts', id) if not alert: raise RpcException(errno.ENOENT, 'Alert {0} not found'.format(id)) if not alert['active']: raise RpcException(errno.ENOENT, 'Alert {0} is already cancelled'.format(id)) alert.update({'active': False, 'cancelled_at': datetime.utcnow()}) self.datastore.update('alerts', id, alert) self.dispatcher.dispatch_event('alert.changed', { 'operation': 'update', 'ids': [id] }) try: self.dispatcher.call_sync('alertd.alert.cancel', id) except RpcException as err: if err.code == errno.ENOENT: # Alertd didn't start yet. Add alert to the pending queue pending_cancels.append(id) else: raise return id
def getpwnam(self, user_name, skip_ad=False): # Try the cache first item = self.context.users_cache.get(name=user_name) if item: if skip_ad and item.directory.plugin_type == 'winbind': raise RpcException(errno.ENOENT, 'User {0} not found'.format(user_name)) return fix_passwords(item.annotated) if '@' in user_name: # Fully qualified user name user_name, domain_name = user_name.split('@', 1) dirs = [self.context.get_directory_by_domain(domain_name)] else: dirs = self.context.get_searched_directories() for d in dirs: if skip_ad and d.plugin_type == 'winbind': continue try: user = d.instance.getpwnam(user_name) except: continue if user: resolve_primary_group(self.context, user) aliases = alias(d, user, 'username') item = CacheItem(user['uid'], user['id'], aliases, copy.copy(user), d, self.context.cache_ttl) self.context.users_cache.set(item) return fix_passwords(item.annotated) raise RpcException(errno.ENOENT, 'User {0} not found'.format(user_name))
def renew_dhcp(self, interface): if interface not in self.dhcp_clients: raise RpcException(errno.ENXIO, 'Interface {0} is not configured for DHCP'.format(interface)) if not self.dhcp_clients[interface].lease: raise RpcException(errno.ENOENT, 'Cannot renew without a lease') self.dhcp_clients[interface].request(renew=True, timeout=30)
def task_setenv(self, tid, key, value): task = self.__balancer.get_task(tid) if not task: raise RpcException(errno.ENOENT, 'Task {0} not found'.format(tid)) if task.ended.is_set(): raise RpcException(errno.ENOENT, 'Can set environment only for running tasks') task.set_env(key, value)
def abort(self): if not hasattr(self.context.instance, 'abort'): raise RpcException(errno.ENOTSUP, 'Abort not supported') try: self.context.instance.abort() except BaseException as err: raise RpcException(errno.EFAULT, 'Cannot abort: {0}'.format(str(err)))
def unregister_schema(self, name, sender): if name not in list(self.schemas.keys()): raise RpcException(errno.ENOENT, 'Schema not found') conn = self.schemas[name] if conn != sender: raise RpcException(errno.EPERM, 'Permission denied') self.__dispatcher.unregister_schema_definition(name) del self.schemas[name]
def resize(self, token, width, height): conn = self.dispatcher.token_store.lookup_token(token) if not conn: raise RpcException(errno.ENOENT, 'Connection not found') if not isinstance(conn, ShellToken): raise RpcException(errno.EINVAL, 'Wrong ticket type provided') if conn.resize: conn.resize(width, height)
def get_stats(self, data_source, params): start = params.pop('start', None) end = params.pop('end', datetime.utcnow()) timespan = params.pop('timespan', None) frequency = params.pop('frequency', '10S') if start is None and timespan is None: raise RpcException(errno.EINVAL, 'Either "start" or "timespan" is required') if start is not None and timespan is not None: raise RpcException(errno.EINVAL, 'Both "start" and "timespan" specified') if timespan is not None: start = datetime.utcnow() - timedelta(seconds=timespan) if start.tzinfo: start = local_to_utc(start) if end.tzinfo: end = local_to_utc(end) if type(data_source) is str: if data_source not in self.context.data_sources: raise RpcException( errno.ENOENT, 'Data source {0} not found'.format(data_source)) ds = self.context.data_sources[data_source] df = ds.query(start, end, frequency) for i in range(len(df)): yield datetime.utcfromtimestamp(df.index[i].value // 10**9), str(df[i]) return if type(data_source) is list: final = pd.DataFrame() for ds_name in data_source: if ds_name not in self.context.data_sources: raise RpcException( errno.ENOENT, 'Data source {0} not found'.format(ds_name)) ds = self.context.data_sources[ds_name] final[ds_name] = ds.query(start, end, frequency) for i in range(len(final)): yield [ datetime.utcfromtimestamp(final.index[i].value // 10**9) ] + [str(final[col][i]) for col in data_source] return
def release(self, identifier, sender): if identifier not in transactions: raise RpcException(errno.ENOENT, 'Transaction not found') t = transactions[identifier] s = first_or_default(lambda s: s.sid == sender.session_id, t) if not s: raise RpcException(errno.EINVAL, 'Transaction is not held by current session') t.purge(s)
def delete(self, job_id): job = self.context.scheduler.get_job(job_id) if not job: raise RpcException( errno.ENOENT, 'Job with id: {0} does not exist'.format(job_id)) if job.kwargs['protected']: raise RpcException( errno.EPERM, 'Job {0} is protected from being deleted'.format(job_id)) self.context.logger.info('Deleting job with ID {0}'.format(job_id)) self.context.scheduler.remove_job(job_id)
def join_subtasks(self, subtask_ids, sender): executor = self.__balancer.get_executor_by_sender(sender) if not executor: raise RpcException(errno.EPERM, 'Not authorized') subtasks = list(map(self.__balancer.get_task, subtask_ids)) self.__balancer.join_subtasks(*subtasks) for i in subtasks: if i.state != TaskState.FINISHED: raise RpcException(i.error['code'], i.error['message']) return [t.result for t in subtasks]
def resume_service(self, name, sender): if name not in list(self.services.keys()): raise RpcException(errno.ENOENT, 'Service not found') svc = self.services[name] if svc.connection != sender: raise RpcException(errno.EPERM, 'Permission denied') svc.resumed.set() self.__dispatcher.dispatch_event('plugin.service_resume', { 'name': name, })
def get_ssh_keys(self): try: with open('/etc/ssh/ssh_host_rsa_key.pub') as f: return f.read(), self.configstore.get( 'peer.freenas.key.public') except FileNotFoundError: raise RpcException(errno.ENOENT, 'Hostkey file not found')
def apply_state(self, service, restart=False, reload=False): svc = self.datastore.get_one('service_definitions', ('name', '=', service)) if not svc: raise RpcException(errno.ENOENT, 'Service {0} not found'.format(service)) state, _, pid = get_status(self.dispatcher, self.datastore, svc) node = ConfigNode('service.{0}'.format(service), self.configstore) if node['enable'].value and state != 'RUNNING': logger.info('Starting service {0}'.format(service)) self.dispatcher.call_sync('service.ensure_started', service, timeout=120) elif not node['enable'].value and state != 'STOPPED': logger.info('Stopping service {0}'.format(service)) self.dispatcher.call_sync('service.ensure_stopped', service, timeout=120) else: if restart: logger.info('Restarting service {0}'.format(service)) self.dispatcher.call_sync('service.restart', service, timeout=120) elif reload: logger.info('Reloading service {0}'.format(service)) self.dispatcher.call_sync('service.reload', service, timeout=120)
def restart(self, service): svc = self.datastore.get_one('service_definitions', ('name', '=', service)) status, _, _ = get_status(self.dispatcher, self.datastore, svc) if not svc: raise RpcException(errno.ENOENT, 'Service {0} not found'.format(service)) if status != 'RUNNING': return hook_rpc = svc.get('restart_rpc') if hook_rpc: try: self.dispatcher.call_sync(hook_rpc, timeout=300) except RpcException: pass return if 'launchd' in svc: launchd = svc['launchd'] plists = [launchd] if isinstance(launchd, dict) else launchd for i in plists: self.dispatcher.call_sync('serviced.job.restart', i['Label'], timeout=300) return
def get_datastores(self, address, username, password, full=False): ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) ssl_context.verify_mode = ssl.CERT_NONE try: si = connect.SmartConnect(host=address, user=username, pwd=password, sslContext=ssl_context) content = si.RetrieveContent() vm_view = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True) except vmodl.MethodFault as err: raise RpcException(errno.EFAULT, err.msg) try: for datastore in content.viewManager.CreateContainerView(content.rootFolder, [vim.Datastore], True).view: vms = [] if full: for vm in vm_view.view: if datastore not in vm.datastore: continue vms.append({ 'id': vm.config.uuid, 'name': vm.summary.config.name, 'on': vm.summary.runtime.powerState == 'poweredOn', 'snapshottable': can_be_snapshotted(vm) }) yield { 'id': datastore.info.url, 'name': datastore.info.name, 'free_space': datastore.info.freeSpace, 'virtual_machines': vms } finally: connect.Disconnect(si)
def run_subtask(self, name, args, env, sender): executor = self.__balancer.get_executor_by_sender(sender) if not executor: raise RpcException(errno.EPERM, 'Not authorized') ret = self.__balancer.run_subtask(executor.task, name, args, env) return ret.id
def configure_directory(self, id): ds_d = self.context.datastore.get_by_id('directories', id) directory = first_or_default(lambda d: d.id == id, self.context.directories) if not directory: try: directory = Directory(self.context, ds_d) self.context.directories.append(directory) except BaseException as err: raise RpcException(errno.ENXIO, str(err)) if not ds_d: # Directory was removed directory.enabled = False directory.configure() self.context.directories.remove(directory) return if ds_d['enabled'] and not directory.enabled: self.logger.info('Enabling directory {0}'.format(id)) if not ds_d['enabled'] and directory.enabled: self.logger.info('Disabling directory {0}'.format(id)) if ds_d['uid_range']: directory.min_uid, directory.max_uid = ds_d['uid_range'] if ds_d['gid_range']: directory.min_gid, directory.max_gid = ds_d['gid_range'] directory.name = ds_d['name'] directory.enabled = ds_d['enabled'] directory.parameters = ds_d['parameters'] directory.configure()
def normalize_parameters(self, plugin, parameters): cls = self.context.plugins.get(plugin) if not cls: raise RpcException(errno.ENOENT, 'Plugin {0} not found'.format(plugin)) return cls.normalize_parameters(parameters)
def wait(self, id): task = self.__balancer.get_task(id) if task: task.ended.wait() return raise RpcException(errno.ENOENT, 'No such task')
def restart(self, service): svc = self.datastore.get_one('service_definitions', ('name', '=', service)) status = self.query([('name', '=', service)], {'single': True}) if not svc: raise RpcException(errno.ENOENT, 'Service {0} not found'.format(service)) if status['state'] != 'RUNNING': return hook_rpc = svc.get('restart_rpc') if hook_rpc: try: self.dispatcher.call_sync(hook_rpc) except RpcException: pass return if 'launchd' in svc: launchd = svc['launchd'] plists = [launchd] if isinstance(launchd, dict) else launchd for i in plists: self.dispatcher.call_sync('serviced.job.restart', i['Label']) return
def push_status(self, status): sender = get_sender() job = self.context.job_by_pid(sender.credentials['pid']) if not job: raise RpcException(errno.EINVAL, 'Unknown job') job.push_status(status)
def checkin(self): sender = get_sender() job = self.context.job_by_pid(sender.credentials['pid']) if not job: raise RpcException(errno.EINVAL, 'Unknown job') job.checkin()