def apply(self, args, options): output = '' try: p = subprocess.Popen([self.update_cmd], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) ret = p.wait() output += p.stdout.read() logger.debug("commonconf apply: %d" % ret) if ret != 0: raise HttpReqError(500, output) except OSError: traceback.print_exc() raise HttpReqError(500, "can't apply commonconf changes") try: p = subprocess.Popen([self.monit], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) ret = p.wait() output += '\n' + p.stdout.read() logger.debug("monit apply: %d" % ret) if ret != 0: raise HttpReqError(500, output) except OSError: traceback.print_exc() raise HttpReqError(500, "can't apply monit changes") return output
def Hosts(args, options): """ POST /hosts >>> hosts({'hostname': 'xivo', 'domain': 'localdomain'}) """ _validate_hosts(args) if not os.access(Rcc['hostname_path'], (os.X_OK | os.W_OK)): raise HttpReqError( 415, "path not found or not writable or not executable: %r" % Rcc['hostname_path'], ) if not os.access(Rcc['hosts_path'], (os.X_OK | os.W_OK)): raise HttpReqError( 415, "path not found or not writable or not executable: %r" % Rcc['hosts_path'], ) if not RESOLVCONFLOCK.acquire_read(Rcc['lock_timeout']): raise HttpReqError( 503, "unable to take RESOLVCONFLOCK for reading after %s seconds" % Rcc['lock_timeout'], ) hostnamebakfile = None hostsbakfile = None try: try: hostnamebakfile = _write_config_file( 'hostname', {'_XIVO_HOSTNAME': args['hostname']}, ) hostsbakfile = _write_config_file( 'hosts', { '_XIVO_HOSTNAME': args['hostname'], '_XIVO_DOMAIN': args['domain'] }, ) subprocess.call(['hostname', '-F', Rcc['hostname_file']]) return True except Exception as e: if hostnamebakfile: copy2(hostnamebakfile, Rcc['hostname_file']) if hostsbakfile: copy2(hostsbakfile, Rcc['hosts_file']) raise e.__class__(str(e)) finally: RESOLVCONFLOCK.release()
def _validate_options(self, options): for param in ('old_context', 'old_mailbox', 'new_context', 'new_mailbox'): value = options.get(param) if not value: raise HttpReqError(400, "missing '{}' arg".format(param), json=True) if not self.is_valid_path_component(value): raise HttpReqError(400, 'invalid {}'.format(param))
def _validate_resolv_conf(args): nameservers = args.get('nameservers', []) if not 0 < len(nameservers) < 4: raise HttpReqError(415, "invalid arguments for command") for nameserver in nameservers: if not helpers.ipv4_address_or_domain(nameserver): raise HttpReqError(415, "invalid arguments for command") searches = args.get('search', []) if not 0 < len(searches) < 7: raise HttpReqError(415, "invalid arguments for command") for search in searches: if not helpers.search_domain(search): raise HttpReqError(415, "invalid arguments for command")
def dhcpd_update(args, options): """Download the latest ISC dhcp server configuration files and regenerate the affected configuration files via the dhcpd-update command. """ try: returncode = subprocess.call(DHCPD_UDPATE_COMMAND, close_fds=True) except OSError as e: raise HttpReqError(500, "error while executing dhcpd-update command: %s" % e) else: if returncode: raise HttpReqError(500, "dhcpd-update command returned %s" % returncode) else: return True
def delete_voicemail(self, args, options): if 'mailbox' not in options: raise HttpReqError(400, "missing 'mailbox' arg", json=True) context = options.get('context', 'default') mailbox = options['mailbox'] if not self.is_valid_path_component(context): raise HttpReqError(400, 'invalid context') if not self.is_valid_path_component(mailbox): raise HttpReqError(400, 'invalid mailbox') vmpath = os.path.join(self._base_vmail_path, context, mailbox) self.remove_directory(vmpath) return True
def generate(self, args, options): try: p = subprocess.Popen([self.generate_cmd], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) except OSError as e: logger.exception(e) raise HttpReqError(500, "can't generate commonconf file") ret = p.wait() output = p.stdout.read() logger.debug("commonconf generate: return code %d" % ret) if ret != 0: logger.error("Error while generating commonconf: %s", output) raise HttpReqError(500, "can't generate commonconf file")
def _run_action_for_service_validated(service, action): output = '' try: command = ['/bin/systemctl', action, '{}.service'.format(service)] p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) output = p.communicate()[0] logger.debug("%s : return code %d", ' '.join(command), p.returncode) if p.returncode != 0: raise HttpReqError(500, output) except OSError: logger.exception("Error while executing action") raise HttpReqError(500, "can't manage services") return output
def handle_request(self, args, options): try: request = self._request_factory.new_request(args) except Exception: logger.exception('Error while creating new request %s', args) raise HttpReqError(400) else: self._add_completed_observer(request) self._queue_request(request) return request.uuid
def xivoctl(args, options): for service, act in args.iteritems(): if service == 'wazo-service': try: if act == 'start': services({'asterisk': 'stop'}, {}) p = subprocess.Popen(["%s" % service, act], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) output = p.communicate()[0] logger.debug("%s %s : %d", service, act, p.returncode) if p.returncode != 0: raise HttpReqError(500, output) except OSError: logger.exception("Error while executing %s script", service) raise HttpReqError(500, "can't manage xivoctl") else: logger.error("service not exist: %s", service) return output
def _validate_hosts(args): if not helpers.domain_label(args.get('hostname')): raise HttpReqError(415, "invalid arguments for command") if not helpers.search_domain(args.get('domain')): raise HttpReqError(415, "invalid arguments for command")
def ResolvConf(args, options): """ POST /resolv_conf >>> resolv_conf({'nameservers': '192.168.0.254'}) >>> resolv_conf({'nameservers': ['192.168.0.254', '10.0.0.254']}) >>> resolv_conf({'search': ['toto.tld', 'tutu.tld'] 'nameservers': ['192.168.0.254', '10.0.0.254']}) """ if 'nameservers' in args: args['nameservers'] = helpers.extract_scalar(args['nameservers']) nameservers = helpers.unique_case_tuple(args['nameservers']) if len(nameservers) == len(args['nameservers']): args['nameservers'] = list(nameservers) else: raise HttpReqError( 415, "duplicated nameservers in %r" % list(args['nameservers'])) if 'search' in args: args['search'] = helpers.extract_scalar(args['search']) search = helpers.unique_case_tuple(args['search']) if len(search) == len(args['search']): args['search'] = list(search) else: raise HttpReqError( 415, "duplicated search in %r" % list(args['search'])) if len(''.join(args['search'])) > 255: raise HttpReqError( 415, "maximum length exceeded for option search: %r" % list(args['search']), ) _validate_resolv_conf(args) if not os.access(Rcc['resolvconf_path'], (os.X_OK | os.W_OK)): raise HttpReqError( 415, "path not found or not writable or not executable: %r" % Rcc['resolvconf_path'], ) if not RESOLVCONFLOCK.acquire_read(Rcc['lock_timeout']): raise HttpReqError( 503, "unable to take RESOLVCONFLOCK for reading after %s seconds" % Rcc['lock_timeout'], ) resolvconfbakfile = None try: try: resolvconfbakfile = _write_config_file( 'resolvconf', _resolv_conf_variables(args)) return True except Exception as e: if resolvconfbakfile: copy2(resolvconfbakfile, Rcc['resolvconf_file']) raise e.__class__(str(e)) finally: RESOLVCONFLOCK.release()