Beispiel #1
0
    def do_create(self, params=None):
        """
        create database with role-assigment and tables
        """
        if len(params) >= 1:
            db_name = params[0]
        else:
            db_name = cfg.read_param("database_name",
                                     "Please provide the database to create")
        logger.debug("db_name: '%s'", db_name)

        admin_url = self.get_admin_db_url(db_name)
        if not admin_url:
            return -1

        admin_db = self.get_db(admin_url, db_name)
        if not admin_db:
            return -1

        if self.create_db(db_name, admin_url, admin_db) < 0:
            return -1

        db_url = self.get_db_url(db_name)
        if not db_url:
            return -1

        if self.ensure_user(db_url, db_name, admin_db) < 0:
            return -1

        if self.create_tables(db_name, db_url, admin_db) < 0:
            return -1

        admin_db.destroy()
        return 0
Beispiel #2
0
    def do_delete(self, params=None):

        if len(params) < 1:
            name = cfg.read_param(
                None, "Please provide the username you want to delete")
            if not name:
                logger.warning("no username to delete!")
                return -1
        else:
            name = params[0]
        username, domain = self.user_get_domain(name)

        db = self.user_db_connect()

        delete_dict = {USER_NAME_COL: username, USER_DOMAIN_COL: domain}
        # check if the user already exists
        if not db.entry_exists(USER_TABLE, delete_dict):
            logger.warning("User {}@{} does not exist".format(
                username, domain))
            return -1

        db.delete(USER_TABLE, delete_dict)
        logger.debug(
            "User's {}@{} password has been been successfully deleted".format(
                username, domain))
        db.destroy()
        return True
Beispiel #3
0
    def parse_params(self, cmd, params):

        # first, we check to see if we have only named parameters
        nparams = self.get_params_set(params)
        if nparams is not None:
            logger.debug("named parameters are used")
            new_params = {}
            for p in params:
                s = p.split("=", 1)
                value = "" if len(s) == 1 else s[1]
                # check to see if we have to split them in array or not
                if cmd in MI_ARRAY_PARAMS_COMMANDS and \
                        MI_ARRAY_PARAMS_COMMANDS[cmd][1] == s[0]:
                    new_params[s[0]] = shlex.split(value)
                else:
                    new_params[s[0]] = value
        else:
            # old style positional parameters
            logger.debug("positional parameters are used")
            # if the command is not in MI_ARRAY_PARAMS_COMMANDS, return the
            # parameters as they are
            if not cmd in MI_ARRAY_PARAMS_COMMANDS:
                return params
            # build params based on their index
            new_params = params[0:MI_ARRAY_PARAMS_COMMANDS[cmd][0]]
            new_params.append(params[MI_ARRAY_PARAMS_COMMANDS[cmd][0]:])
        return new_params
Beispiel #4
0
    def create(self, db_name=None):
        """
        create a database object
        """
        if db_name is None:
            db_name = self.db_name
        # TODO: do this only for SQLAlchemy
        if not self.__conn:
            raise osdbError("connection not available")

        logger.debug("Create Database '%s' for dialect '%s' ...",
                     self.db_name, self.dialect)

        # all good - it's time to create the database
        if self.dialect == "postgres":
            self.__conn.connection.connection.set_isolation_level(0)
            try:
                self.__conn.execute("CREATE DATABASE {}".format(self.db_name))
                self.__conn.connection.connection.set_isolation_level(1)
            except sqlalchemy.exc.OperationalError as se:
                logger.error("cannot create database: {}!".format(se))
        else:
            self.__conn.execute("CREATE DATABASE {}".format(self.db_name))

        logger.debug("success")
        return True
Beispiel #5
0
    def connect(self, db_name=None):
        """
        connect to database
        """
        if db_name is not None:
            self.db_name = db_name
            # TODO: do this only for SQLAlchemy

        try:
            if self.dialect == "postgres":
                self.db_url = self.set_url_db(self.db_url, self.db_name)
                if sqlalchemy_utils.database_exists(self.db_url) is True:
                    engine = sqlalchemy.create_engine(
                        self.db_url, isolation_level='AUTOCOMMIT')
                    if self.__conn:
                        self.__conn.close()
                    self.__conn = engine.connect()
                    # connect the Session object to our engine
                    self.Session.configure(bind=self.__engine)
                    # instanciate the Session object
                    self.session = self.Session()
                    logger.debug("connected to database URL '%s'", self.db_url)
            else:
                self.__conn.execute("USE {}".format(self.db_name))
        except Exception as e:
            logger.error("failed to connect to %s", self.db_url)
            logger.error(e)
            return False

        return True
Beispiel #6
0
 def run_command(self, module, cmd, params):
     """
     run a module command with given parameters
     """
     try:
         mod = self.modules[module]
     except (AttributeError, KeyError):
         if module in self.excluded_errs:
             for err_msg in self.excluded_errs[module]:
                 logger.error(err_msg)
             return -1
         else:
             logger.error("no module '{}' loaded".format(module))
             return -1
     # if the module does not return any methods (returned None)
     # we simply call the module's name method
     if not mod[1]:
         if params is not None:
             params.insert(0, cmd)
         cmd = mod[0].__module__
         if cmd.startswith("opensipscli.modules."):
             cmd = cmd[20:]
     elif not cmd and '' not in mod[1]:
         logger.error(
             "module '{}' expects the following commands: {}".format(
                 module, ", ".join(mod[1])))
         return -1
     elif cmd and not cmd in mod[1]:
         logger.error("no command '{}' in module '{}'".format(cmd, module))
         return -1
     logger.debug("running command '{}' '{}'".format(cmd, params))
     return mod[0].__invoke__(cmd, params)
Beispiel #7
0
def valid():
    opensips_fifo = cfg.get('fifo_file')
    if not os.path.exists(opensips_fifo):
        msg = "fifo file {} does not exist!".format(opensips_fifo)
        logger.debug(msg)
        return (False, [msg, 'Is OpenSIPS running?'])
    return (True, None)
Beispiel #8
0
 def cmdloop(self, intro=None):
     """
     command loop, catching SIGINT
     """
     if self.execute:
         if len(self.command) < 1:
             logger.error("no modules to run specified!")
             return -1
         if len(self.command) < 2:
             logger.debug("no method to in '{}' run specified!".
                     format(self.command[0]))
             command = None
             params = None
         else:
             command = self.command[1]
             params = self.command[2:]
         logger.debug("running in non-interactive mode '{}'".format(self.command))
         ret = self.run_command(self.command[0], command, params)
         # assume that by default it exists with success
         if ret is None:
             ret = 0
         return ret
     while True:
         try:
             super(OpenSIPSCLIShell, self).cmdloop(intro='')
             break
         except KeyboardInterrupt:
             print('^C')
     # any other commands exits with negative value
     return -1
Beispiel #9
0
    def get_admin_db_url(self, db_name):
        engine = osdb.get_db_engine()
        if not engine:
            return None

        if cfg.exists('database_admin_url'):
            admin_url = cfg.get("database_admin_url")
            if engine == "postgres":
                admin_url = osdb.set_url_db(admin_url, 'postgres')
        else:
            if engine == 'postgres':
                if getuser() != "postgres":
                    logger.error("Command must be run as 'postgres' user: "******"sudo -u postgres opensips-cli ...")
                    return None
                """
                For PG, do the initial setup using 'postgres' as role + DB
                """
                admin_url = "postgres://postgres@localhost/postgres"
            else:
                admin_url = "{}://root@localhost".format(engine)

        if osdb.get_url_pswd(admin_url) is None:
            pswd = getpass("Password for admin {} user ({}): ".format(
                osdb.get_url_driver(admin_url, capitalize=True),
                osdb.get_url_user(admin_url)))
            logger.debug("read password: '******'", pswd)
            admin_url = osdb.set_url_password(admin_url, pswd)

        logger.debug("admin DB URL: '{}'".format(admin_url))
        return admin_url
Beispiel #10
0
    def grant_db_options(self, role_name="opensips", role_options="ALL PRIVILEGES"):
        """
        assign attibutes to a role object (PostgreSQL specific)
        """
        # TODO: is any other dialect using the "role" concept?
        if self.dialect != "postgres":
            return False

        # TODO: do this only for SQLAlchemy
        if not self.__conn:
            raise osdbError("connection not available")
            return False

        logger.debug("Role '%s' will be granted with options '%s' on database '%s'",
					 role_name, role_options, self.db_name)

        sqlcmd = "GRANT {} ON DATABASE {} TO {}".format(role_options, self.db_name, role_name)
        try:
            result = self.__conn.execute(sqlcmd)
            if result:
                logger.info("granted options '%s' to role '%s' on database '%s'",
                    role_options, role_name, self.db_name)
        except:
            logger.error("granting options '%s' to role '%s' on database '%s' failed",
                    role_options, role_name, self.db_name)
            return False
        return
Beispiel #11
0
    def do_trap(self, params):

        self.pids = []
        self.gdb_outputs = {}
        self.process_info = ""

        trap_file = cfg.get("trap_file")

        logger.info("Trapping {} in {}".format(PROCESS_NAME, trap_file))
        if params and len(params) > 0:
            self.pids = params
        else:
            thread = Thread(target=self.get_pids)
            thread.start()
            thread.join(timeout=1)
            if len(self.pids) == 0:
                logger.warning("could not get OpenSIPS pids through MI!")
                try:
                    ps_pids = subprocess.check_output(["pidof",PROCESS_NAME])
                    self.pids = ps_pids.decode().split()
                except:
                    logger.warning("could not find any OpenSIPS running!")
                    self.pids = []

        if len(self.pids) < 1:
            logger.error("could not find OpenSIPS' pids")
            return -1

        logger.debug("Dumping PIDs: {}".format(", ".join(self.pids)))

        threads = []
        for pid in self.pids:
            thread = Thread(target=self.get_gdb_output, args=(pid,))
            thread.start()
            threads.append(thread)

        for thread in threads:
            thread.join()

        if len(self.gdb_outputs) == 0:
            logger.error("could not get output of gdb")
            return -1

        with open(trap_file, "w") as tf:
            tf.write(self.process_info)
            for pid in self.pids:
                if pid not in self.gdb_outputs:
                    logger.warning("No output from pid {}".format(pid))
                    continue
                try:
                    procinfo = subprocess.check_output(
                        ["ps", "--no-headers", "-ww", "-fp", pid]).decode()[:-1]
                except:
                    procinfo = "UNKNOWN"

                tf.write("\n\n---start {} ({})\n{}".
                        format(pid, procinfo, self.gdb_outputs[pid]))

        print("Trap file: {}".format(trap_file))
Beispiel #12
0
    def do_migrate(self, params):
        if len(params) < 3:
            print(
                "Usage: database migrate <flavour> <old-database> <new-database>"
            )
            return 0

        flavour = params[0].lower()
        old_db = params[1]
        new_db = params[2]

        if flavour not in DB_MIGRATIONS:
            logger.error("unsupported migration flavour: {}".format(flavour))
            return -1

        admin_url = self.get_admin_db_url(new_db)
        if not admin_url:
            return -1

        db = self.get_db(admin_url, new_db)
        if not db:
            return -1

        if db.dialect != "mysql":
            logger.error("'migrate' is only available for MySQL right now! :(")
            return -1

        if not db.exists(old_db):
            logger.error(
                "the source database ({}) does not exist!".format(old_db))
            return -2

        print("Creating database {}...".format(new_db))
        if self.create_db(new_db, admin_url, db) < 0:
            return -1
        if self.create_tables(new_db, admin_url, db) < 0:
            return -1

        backend = osdb.get_url_driver(admin_url)

        # obtain the DB schema files for the in-use backend
        schema_path = self.get_schema_path(backend)
        if schema_path is None:
            return -1

        migrate_scripts = self.get_migrate_scripts_path(backend)
        if migrate_scripts is None:
            logger.debug("migration scripts for %s not found", backend)
            return -1
        else:
            logger.debug("found migration scripts for %s", backend)

        logger.info("Migrating all matching OpenSIPS tables...")
        db.migrate(
            flavour.replace('.', '_').upper(), migrate_scripts, old_db, new_db,
            DB_MIGRATIONS[flavour])

        db.destroy()
        return True
Beispiel #13
0
    def update_instance(self, instance):

        # first of all, let's handle logging
        self.current_instance = instance
        self.update_logger()

        # Update the intro and prompt
        self.intro = cfg.get('prompt_intro')
        self.prompt = '(%s): ' % cfg.get('prompt_name')

        # initialize communcation handler
        self.handler = comm.initialize()

        # remove all loaded modules
        self.modules = {}

        if not self.execute:
            print(self.intro)
            # add the built-in modules and commands list
            for mod in ['clear', 'help', 'history', 'exit', 'quit']:
                self.modules[mod] = (self, None)

        if not cfg.exists('skip_modules'):
            skip_modules = []
        else:
            skip_modules = cfg.get('skip_modules')

        available_modules = {
            key[20:]: sys.modules[key]
            for key in sys.modules.keys()
            if key.startswith("opensipscli.modules.")
            and key[20:] not in skip_modules
        }
        for name, module in available_modules.items():
            m = importlib.import_module("opensipscli.modules.{}".format(name))
            if not hasattr(m, "Module"):
                logger.debug(
                    "Skipping module '{}' - does not extend Module".format(
                        name))
                continue
            if not hasattr(m, name):
                logger.debug(
                    "Skipping module '{}' - module implementation not found".
                    format(name))
                continue
            mod = getattr(module, name)
            if not hasattr(mod, '__exclude__') or not hasattr(
                    mod, '__get_methods__'):
                logger.debug(
                    "Skipping module '{}' - module does not implement Module".
                    format(name))
                continue
            if mod.__exclude__(mod):
                logger.debug(
                    "Skipping module '{}' - excluded on purpose".format(name))
                continue
            logger.debug("Loaded module '{}'".format(name))
            imod = mod()
            self.modules[name] = (imod, mod.__get_methods__(imod))
Beispiel #14
0
    def migrate(self, migrate_scripts, old_db, new_db, tables=[]):
        if self.dialect != "mysql":
            logger.error("Table data migration is only supported for MySQL!")
            return
        """
        migrate from source to destination database using SQL schema files
        """
        self.connect(old_db)

        try:
            ret = self.find('mysql.proc', "count(*)", {
                'db': old_db,
                'name': 'OSIPS_DB_MIGRATE_2_4_TO_3_0'
            })
            if ret and ret.first()[0] != 0:
                self.__conn.execute(
                    sqlalchemy.sql.text(
                        "DROP PROCEDURE IF EXISTS OSIPS_DB_MIGRATE_2_4_TO_3_0"
                    ).execution_options(autocommit=True))

            ret = self.find('mysql.proc', "count(*)", {
                'db': old_db,
                'name': 'OSIPS_TB_COPY_2_4_TO_3_0'
            })
            if ret and ret.first()[0] != 0:
                self.__conn.execute(
                    sqlalchemy.sql.text(
                        "DROP PROCEDURE IF EXISTS OSIPS_TB_COPY_2_4_TO_3_0").
                    execution_options(autocommit=True))
        except Exception as e:
            logger.exception(e)
            logger.error("Failed to re-create migration stored procedures!")

        for ms in migrate_scripts:
            logger.debug("Importing {}...".format(ms))
            self.exec_sql_file(ms)

        if tables:
            for tb in tables:
                print("Migrating {} data... ".format(tb), end='')
                try:
                    self.__conn.execute(
                        sqlalchemy.sql.text(
                            "CALL {}.OSIPS_TB_COPY_2_4_TO_3_0('{}', '{}', '{}')"
                            .format(old_db, old_db, new_db, tb)))
                except Exception as e:
                    logger.exception(e)
                    logger.error(
                        "Failed to migrate '{}' table data, ".format(tb) +
                        "see above errors!")
        else:
            try:
                self.__conn.execute(
                    sqlalchemy.sql.text(
                        "CALL {}.OSIPS_DB_MIGRATE_2_4_TO_3_0('{}', '{}')".
                        format(old_db, old_db, new_db)))
            except Exception as e:
                logger.exception(e)
                logger.error("Failed to migrate database!")
Beispiel #15
0
 def preloop(self):
     history_file = cfg.get('history_file')
     if readline and os.path.exists(history_file):
         readline.read_history_file(history_file)
         logger.debug("using history file {}".format(history_file))
     readline.set_history_length(int(cfg.get('history_file_size')))
     if not self.registered_atexit:
         atexit.register(self.history_write)
Beispiel #16
0
 def history_write(self):
     """
     save history file
     """
     history_file = cfg.get('history_file')
     logger.debug("saving history in {}".format(history_file))
     os.makedirs(os.path.expanduser(os.path.dirname(history_file)),
                 exist_ok=True)
     readline.write_history_file(os.path.expanduser(history_file))
Beispiel #17
0
    def migrate(self, proc_suffix, migrate_scripts, old_db, new_db, tables=[]):
        """
        migrate from source to destination database using SQL schema files
        @flavour: values should resemble: '2.4_to_3.0', '3.0_to_3.1'
        @sp_suffix: stored procedure name suffix, specific to each migration
        """

        if self.dialect != "mysql":
            logger.error("Table data migration is only supported for MySQL!")
            return

        proc_db_migrate = 'OSIPS_DB_MIGRATE_{}'.format(proc_suffix)
        proc_tb_migrate = 'OSIPS_TB_COPY_{}'.format(proc_suffix)

        self.connect(old_db)

        # separately drop DB/table migration stored procedures if already
        # present, since there are issues with multiple statements in 1 import
        try:
            self.__conn.execute(
                sqlalchemy.sql.text("DROP PROCEDURE IF EXISTS {}".format(
                    proc_db_migrate)).execution_options(autocommit=True))

            self.__conn.execute(
                sqlalchemy.sql.text("DROP PROCEDURE IF EXISTS {}".format(
                    proc_tb_migrate)).execution_options(autocommit=True))
        except:
            logger.exception("Failed to drop migration stored procedures!")

        for ms in migrate_scripts:
            logger.debug("Importing {}...".format(ms))
            self.exec_sql_file(ms)

        if tables:
            for tb in tables:
                logger.info("Migrating {} data... ".format(tb))
                try:
                    self.__conn.execute(
                        sqlalchemy.sql.text(
                            "CALL {}.{}('{}', '{}', '{}')".format(
                                old_db, proc_tb_migrate, old_db, new_db, tb)))
                except Exception as e:
                    logger.exception(e)
                    logger.error(
                        "Failed to migrate '{}' table data, ".format(tb) +
                        "see above errors!")
        else:
            try:
                self.__conn.execute(
                    sqlalchemy.sql.text("CALL {}.{}('{}', '{}')".format(
                        old_db, proc_db_migrate, old_db, new_db)))
            except Exception as e:
                logger.exception(e)
                logger.error("Failed to migrate database!")

        print("Finished copying OpenSIPS table data " +
              "into database '{}'!".format(new_db))
Beispiel #18
0
    def get_db_url(self, db_name=cfg.get('database_name')):
        engine = osdb.get_db_engine()
        if not engine:
            return None

        # make sure to inherit the 'database_admin_url' engine
        db_url = osdb.set_url_driver(cfg.get("database_url"), engine)

        logger.debug("DB URL: '{}'".format(db_url))
        return db_url
Beispiel #19
0
 def preloop(self):
     history_file = cfg.get('history_file')
     logger.debug("using history file {}".format(history_file))
     try:
         readline.read_history_file(os.path.expanduser(history_file))
     except FileNotFoundError:
         pass
     readline.set_history_length(int(cfg.get('history_file_size')))
     if not self.registered_atexit:
         atexit.register(self.history_write)
Beispiel #20
0
    def do_migrate(self, params):
        if len(params) < 2:
            print("Usage: database migrate <old-database> <new-database>")
            return 0

        old_db = params[0]
        new_db = params[1]

        db_url = self.ask_db_url()
        if db_url is None:
            return -1

        # create an object store database instance
        db = self.get_db(db_url, old_db)
        if db is None:
            return -1

        if not db.exists(old_db):
            logger.error(
                "the source database ({}) does not exist!".format(old_db))
            return -2

        print("Creating database {}...".format(new_db))
        if self._do_create_db([new_db], db_url=db_url) < 0:
            return -1
        if self.create_tables(new_db, db_url=db_url) < 0:
            return -1

        # get schema path for active database dialect
        db_schema = db.db_url.split(":")[0]
        schema_path = self.get_schema_path(db_schema)
        if schema_path is None:
            return -1

        # get schema scripts for active database dialect
        db_schema = db.db_url.split(":")[0]
        migrate_scripts = self.get_migrate_scripts_path(db_schema)
        if migrate_scripts is None:
            logger.debug("migration scripts for db_schema '%s' not found",
                         db_schema)
            return -1
        else:
            logger.debug("migration scripts for db_schema: '%s'",
                         migrate_scripts)

        print("Migrating all matching OpenSIPS tables...")
        db.migrate(migrate_scripts, old_db, new_db, MIGRATE_TABLES_24_TO_30)

        print("Finished copying OpenSIPS table data " +
              "into database '{}'!".format(new_db))

        db.destroy()
        return True
Beispiel #21
0
    def migrate(self, migrate_scripts, old_db, new_db):
        self.use(old_db)

        for ms in migrate_scripts:
            logger.debug("Importing {}...".format(ms))
            self.exec_sql_file(ms)

        self.__conn.execute(
            sqlalchemy.sql.text(
                "CALL {}.OSIPS_DB_MIGRATE_2_4_TO_3_0('{}', '{}')".format(
                    old_db, old_db,
                    new_db)).execution_options(autocommit=True))
Beispiel #22
0
    def do_migrate(self, params):
        if len(params) < 2:
            print("Usage: database migrate <old-database> <new-database>")
            return 0

        old_db = params[0]
        new_db = params[1]

        admin_url = self.get_admin_db_url(new_db)
        if not admin_url:
            return -1

        db = self.get_db(admin_url, new_db)
        if not db:
            return -1

        if db.dialect != "mysql":
            logger.error("'migrate' is only available for MySQL right now! :(")
            return -1

        if not db.exists(old_db):
            logger.error(
                "the source database ({}) does not exist!".format(old_db))
            return -2

        print("Creating database {}...".format(new_db))
        if self.create_db(new_db, admin_url, db) < 0:
            return -1
        if self.create_tables(new_db, db, admin_url) < 0:
            return -1

        backend = osdb.get_url_driver(admin_url)

        # obtain the DB schema files for the in-use backend
        schema_path = self.get_schema_path(backend)
        if schema_path is None:
            return -1

        migrate_scripts = self.get_migrate_scripts_path(backend)
        if migrate_scripts is None:
            logger.debug("migration scripts for %s not found", backend)
            return -1
        else:
            logger.debug("migration scripts for %s", migrate_scripts)

        print("Migrating all matching OpenSIPS tables...")
        db.migrate(migrate_scripts, old_db, new_db, MIGRATE_TABLES_24_TO_30)

        print("Finished copying OpenSIPS table data " +
              "into database '{}'!".format(new_db))

        db.destroy()
        return True
Beispiel #23
0
 def history_write(self):
     """
     save history file
     """
     history_file = cfg.get('history_file')
     logger.debug("saving history in {}".format(history_file))
     os.makedirs(os.path.expanduser(os.path.dirname(history_file)),
                 exist_ok=True)
     try:
         readline.write_history_file(os.path.expanduser(history_file))
     except PermissionError:
         logger.warning("failed to write CLI history to {} " +
                        "(no permission)".format(history_file))
Beispiel #24
0
    def do_create_module(self, module_name):
        """
        create database table for given module
        """

        db_url = cfg.read_param(
            "database_url",
            "Please provide the URL to connect to the database")
        if db_url is None:
            print()
            logger.error("no URL specified: aborting!")
            return -1

        db_name = cfg.read_param("database_name",
                                 "Please provide the database name",
                                 DEFAULT_DB_NAME)
        if db_name is None:
            logger.error("no URL specified: aborting!")
            return -1

        # create an object store database instance
        db = self.get_db(db_url, db_name)
        if db is None:
            return -1

        # connect to the database
        db.connect(db_name)

        # create table from schema-file for given module name
        module = ' '.join(module_name)
        logger.debug("module_name: '%s'", module)
        #re.sub('\ |\[|\'|\]', '', module)
        #module_name.strip('[']')
        db_schema = db_url.split(":")[0]
        schema_path = self.get_schema_path(db_schema)
        if schema_path is None:
            return -1
        module_schema_file = os.path.join(schema_path,
                                          "{}-create.sql".format(module))
        try:
            db.create_module(module_schema_file)
            logger.info(
                "database tables for module '%s' has been successfully created.",
                module_name)
        except osdbError as ex:
            logger.error("cannot import: {}".format(ex))

        # terminate active database connection
        db.destroy()

        return True
Beispiel #25
0
    def exists_role(self, role_name=None):
        """
        check for existence of a role object (PostgreSQL specific)
        """
        # TODO: is any other dialect using the "role" concept?
        if self.dialect != "postgres":
            return False

        # TODO: do this only for SQLAlchemy
        if not self.__conn:
            raise osdbError("connection not available")
            return False

        if role_name is None:
            role_name = 'opensips'

        filter_args = {'rolname': role_name}
        logger.debug("filter argument: '%s'", filter_args)

        role_count = self.__session.query(Roles).\
                filter_by(**filter_args).\
                count()
        logger.debug("Number of matching role instances: '%s'", role_count)

        if role_count >= 1:
            logger.debug("Role instance '%s' exists", role_name)
            return True
        else:
            logger.debug("Role instance '%s' does not exist", role_name)
            return False
Beispiel #26
0
    def __init__(self, db_url, db_name):
        """
        constructor
        """
        self.db_url = db_url
        self.db_name = db_name
        self.dialect = osdb.get_dialect(db_url)
        self.Session = sessionmaker()
        self.__engine = None
        self.__conn = None

	    # TODO: do this only for SQLAlchemy
        try:
            if self.dialect == "postgresql":
                self.__engine = sqlalchemy.create_engine(db_url, isolation_level='AUTOCOMMIT')
            else:
                self.__engine = sqlalchemy.create_engine(db_url)

            logger.debug("connecting to %s", db_url)
            self.__conn = self.__engine.connect().\
                    execution_options(autocommit=True)
            # connect the Session object to our engine
            self.Session.configure(bind=self.__engine)
            # instanciate the Session object
            self.__session = self.Session()
        except sqlalchemy.exc.OperationalError as se:
            if self.dialect == "mysql":
                try:
                    if int(se.args[0].split(",")[0].split("(")[2]) in [
                            2006, # MySQL
                            1044, # MariaDB
                            1045, # MariaDB
                            ]:
                        raise osdbAccessDeniedError
                except osdbAccessDeniedError:
                    raise
                except:
                    logger.error("unexpected parsing exception")
            elif self.dialect == "postgres" and \
                    (("authentication" in se.args[0] and "failed" in se.args[0]) or \
                     ("no password supplied" in se.args[0])):
                raise osdbAccessDeniedError

            raise osdbError("unable to connect to the database")
        except sqlalchemy.exc.NoSuchModuleError:
            raise osdbError("cannot handle {} dialect".
                    format(self.dialect))
        except sqlalchemy.exc.ArgumentError:
            raise osdbArgumentError("bad DB URL: {}".format(
                self.db_url))
Beispiel #27
0
 def drop(self):
     """
     drop a database object
     """
     # TODO: do this only for SQLAlchemy
     if not self.__conn:
         raise osdbError("connection not available")
     database_url = self.set_url_db(self.db_url, self.db_name)
     try:
         sqlalchemy_utils.drop_database(database_url)
         logger.debug("database '%s' dropped", self.db_name)
         return True
     except sqlalchemy.exc.NoSuchModuleError as me:
         logger.error("cannot check if database {} exists: {}".
                 format(self.db_name, me))
         raise osdbError("cannot handle {} dialect".
                 format(self.dialect)) from None
Beispiel #28
0
 def get_gdb_output(self, pid):
     if os.path.islink("/proc/{}/exe".format(pid)):
         # get process line of pid
         process = os.readlink("/proc/{}/exe".format(pid))
     else:
         logger.error("could not find OpenSIPS process {} running on local machine".format(pid))
         return -1
     # Check if process is opensips (can be different if CLI is running on another host)
     path, filename = os.path.split(process)
     if filename != PROCESS_NAME:
         logger.error("process ID {} is not OpenSIPS process".format(pid))
         return -1
     logger.debug("Dumping backtrace for {} pid {}".format(process, pid))
     cmd = ["gdb", process, pid, "-batch", "--eval-command", "bt full"]
     out = subprocess.check_output(cmd)
     if len(out) != 0:
         self.gdb_outputs[pid] = out.decode()
Beispiel #29
0
    def preloop(self):
        """
        preload a history file
        """
        history_file = cfg.get('history_file')
        logger.debug("using history file {}".format(history_file))
        try:
            readline.read_history_file(os.path.expanduser(history_file))
        except PermissionError:
            logger.warning("failed to read CLI history from {} " +
                           "(no permission)".format(history_file))
        except FileNotFoundError:
            pass

        readline.set_history_length(int(cfg.get('history_file_size')))
        if not self.registered_atexit:
            atexit.register(self.history_write)
Beispiel #30
0
    def __init__(self, options):
        """
        contructor for OpenSIPS-Cli
        """

        self.debug = options.debug
        self.execute = options.execute
        self.command = options.command
        self.modules_dir_inserted = None

        if self.debug:
            logger.setLevel("DEBUG")

        if not options.config:
            cfg_file = None
            for f in defaults.CFG_PATHS:
                if os.path.isfile(f) and os.access(f, os.R_OK):
                    # found a valid config file
                    cfg_file = f
                    break
        else:
            cfg_file = options.config
        if not cfg_file:
            logger.debug("no config file found in any of {}".format(", ".join(
                defaults.CFG_PATHS)))
        else:
            logger.debug("using config file {}".format(cfg_file))

        # __init__ of the configuration file
        cfg.parse(cfg_file)
        if not cfg.has_instance(options.instance):
            logger.warning(
                "Unknown instance '{}'! Using default instance '{}'!".format(
                    options.instance, defaults.DEFAULT_SECTION))
            instance = defaults.DEFAULT_SECTION
        else:
            instance = options.instance
        cfg.set_instance(instance)
        cfg.set_custom_options(options.extra_options)

        if not self.execute:
            # __init__ of cmd.Cmd module
            cmd.Cmd.__init__(self)

        # Opening the current working instance
        self.update_instance(cfg.current_instance)