예제 #1
0
    def run(self):
        # Test parse_connection with login-paths
        con_tests = ["test_user@localhost:3306", "test_mylogin:3306",
                     "test_user@localhost:1000", "test_mylogin:1000",
                     "test_user@localhost:1000:/my.socket",
                     "test_mylogin:1000:/my.socket",
                     "test_user@localhost:3306:/my.socket",
                     "test_mylogin:3306:/my.socket", "test-hyphen1234#:3306",
                     "test-hyphen1234#:13000:my.socket",
                     "test' \\\"-hyphen:3306",
                     "test' \\\"-hyphen:3306:my.socket",
                     "test' \\\"-hyphen:13001:my.socket"]

        for test_ in con_tests:
            con_dic = parse_connection(test_, options={"charset": "utf8"})
            # Sort the keys to fix the issue where the keys are printed in
            # different order on linux and windows.
            self.results.append(sorted(con_dic.iteritems()))

        # Test parse_user_password with login-paths
        user_pass_tests = ["test_user", "test_mylogin", "test_user:"******"user_x:", "user_x:pass_y"]
        for test_ in user_pass_tests:
            user_pass = parse_user_password(test_)
            self.results.append(user_pass)

        # Transform list of dictionaries into list of strings
        self.results = ["{0!s}\n".format(con_dic) for con_dic in self.results]

        # remove socket information from posix systems to have same output
        # on both posix and and windows systems
        self.replace_substring_portion(", ('unix_socket'", ".socket')", '')

        return True
예제 #2
0
    def run(self):
        # Test parse_connection with login-paths
        con_tests = [
            "test_user@localhost:3306", "test_mylogin:3306",
            "test_user@localhost:1000", "test_mylogin:1000",
            "test-hyphen1234#:3306", "test' \\\"-hyphen:3306"
        ]

        for test_ in con_tests:
            con_dic = parse_connection(test_, options={"charset": "utf8"})
            # Sort the keys to fix the issue where the keys are printed in
            # different order on linux and windows.
            self.results.append(sorted(con_dic.iteritems()))

        # Test parse_user_password with login-paths
        user_pass_tests = [
            "test_user", "test_mylogin", "test_user:"******"user_x:",
            "user_x:pass_y", "rpl:'L5!w1SJzVuj40(p?tF@(9Y70_@:z(HXc'"
        ]
        for test_ in user_pass_tests:
            try:
                user_pass = parse_user_password(test_)
                self.results.append(user_pass)
            except FormatError as err:
                self.results.append(err)

        # Transform list of dictionaries into list of strings
        self.results = ["{0!s}\n".format(con_dic) for con_dic in self.results]

        # remove socket information from posix systems to have same output
        # on both posix and and windows systems
        self.replace_substring_portion(", ('unix_socket'", ".socket')", '')

        return True
예제 #3
0
    def run(self):
        # Test parse_connection with login-paths
        con_tests = ["test_user@localhost", "test_mylogin",
                     "test_user@localhost:1000", "test_mylogin:1000",
                     "test_user@localhost:1000:/my.socket",
                     "test_mylogin:1000:/my.socket",
                     "test_user@localhost:/my.socket",
                     "test_mylogin:/my.socket"]
        for test in con_tests:
            con_dic = parse_connection(test)
            self.results.append(con_dic)

        # Test parse_user_password with login-paths
        user_pass_tests = ["test_user", "test_mylogin",
                           "test_user:"******"user_x:", "user_x:pass_y"]
        for test in user_pass_tests:
            user_pass = parse_user_password(test)
            self.results.append(user_pass)
        return True
예제 #4
0
    def run(self):
        # Test parse_connection with login-paths
        con_tests = [
            "test_user@localhost", "test_mylogin", "test_user@localhost:1000",
            "test_mylogin:1000", "test_user@localhost:1000:/my.socket",
            "test_mylogin:1000:/my.socket", "test_user@localhost:/my.socket",
            "test_mylogin:/my.socket"
        ]
        for test in con_tests:
            con_dic = parse_connection(test)
            self.results.append(con_dic)

        # Test parse_user_password with login-paths
        user_pass_tests = [
            "test_user", "test_mylogin", "test_user:"******"user_x:",
            "user_x:pass_y"
        ]
        for test in user_pass_tests:
            user_pass = parse_user_password(test)
            self.results.append(user_pass)
        return True
예제 #5
0
    def _get_slaves(self, max_depth, seed_conn=None, masters_found=None):
        """Find the attached slaves for a list of server connections.

        This method connects to each server in the list and retrieves its
        slaves. It can be called recursively if the recurse option is True.

        max_depth[in]       Maximum depth of recursive search
        seed_conn[in]       Current master connection dictionary. Initially,
                            this is the seed server (original master defined
                            in constructor)
        masters_found[in]   a list of all servers in master roles - used to
                            detect a circular replication topology. Initially,
                            this is an empty list as the master detection must
                            occur as the topology is traversed.

        Returns list - list of slaves connected to each server in list
        """
        if not masters_found:
            masters_found = []
        topology = []
        if seed_conn is None:
            seed_conn = self.seed_server

        master, master_info = self._connect(seed_conn)
        if master is None:
            return []

        # Check user permissions
        self._check_permissions(master, "REPLICATION SLAVE")

        # Save the master for circular replication identification
        masters_found.append(master_info)

        if not self.quiet:
            print "# Finding slaves for master: %s" % master_info

        # See if the user wants us to discover slaves.
        discover = self.options.get("discover", None)
        if discover is None:
            return

        # Get user and password (supports login-paths)
        try:
            user, password = parse_user_password(discover,
                                                 options=self.options)
        except FormatError:
            raise UtilError(USER_PASSWORD_FORMAT.format("--discover-slaves"))

        # Get replication topology
        slaves = master.get_slaves(user, password)
        slave_list = []
        depth = 0
        if len(slaves) > 0:
            for slave in slaves:
                if slave.find(":") > 0:
                    host, port = slave.split(":", 1)
                else:
                    host = slave
                    port = _START_PORT  # Use the default
                slave_conn = self.seed_server.copy()
                slave_conn['host'] = host
                slave_conn['port'] = port

                io_sql_running = None
                # If verbose then get slave threads (IO and SQL) status
                if self.verbose:
                    # Create slave instance
                    conn_dict = {
                        'conn_info': {
                            'user': user,
                            'passwd': password,
                            'host': host,
                            'port': port,
                            'socket': None
                        },
                        'role': slave,
                        'verbose': self.verbose
                    }
                    slave_obj = Slave(conn_dict)
                    # Get IO and SQL status
                    try:
                        slave_obj.connect()
                        thread_status = slave_obj.get_thread_status()
                        if thread_status:
                            io_sql_running = (thread_status[1],
                                              thread_status[2])
                    except UtilError:
                        # Connection error
                        io_sql_running = ('ERROR', 'ERROR')

                # Now check for circular replication topology - do not recurse
                # if slave is also a master.
                if self.recurse and slave not in masters_found and \
                   ((max_depth is None) or (depth < max_depth)):
                    new_list = self._get_slaves(max_depth, slave_conn,
                                                masters_found)
                    if new_list == []:
                        slave_list.append((slave, [], io_sql_running))
                    else:
                        # Add IO and SQL state to slave from recursion
                        if io_sql_running:
                            new_list = [(new_list[0][0], new_list[0][1],
                                         io_sql_running)]
                        slave_list.append(new_list)
                    depth += 1
                else:
                    slave_list.append((slave, [], io_sql_running))
        topology.append((master_info, slave_list))

        return topology
예제 #6
0
    def _setup_replication(self, master_vals, use_rpl_setup=True):
        """Setup replication among a master and a slave.

        master_vals[in]      Master server connection dictionary.
        use_rpl_setup[in]    Use Replication.setup() if True otherwise use
                             switch_master() on the slave. This is used to
                             control the first pass in the masters round-robin
                             scheduling.
        """
        conn_options = {
            "src_name": "master",
            "dest_name": "slave",
            "version": "5.0.0",
            "unique": True,
        }
        (master, slave,) = connect_servers(master_vals, self.slave_vals,
                                           conn_options)
        rpl_options = self.options.copy()
        rpl_options["verbosity"] = self.verbosity > 0

        # Start from beginning only on the first pass
        if rpl_options.get("from_beginning", False) and not use_rpl_setup:
            rpl_options["from_beginning"] = False

        # Create an instance of the replication object
        rpl = Replication(master, slave, rpl_options)

        if use_rpl_setup:
            # Check server ids
            errors = rpl.check_server_ids()
            for error in errors:
                self._report(error, logging.ERROR, True)

            # Check for server_id uniqueness
            errors = rpl.check_server_uuids()
            for error in errors:
                self._report(error, logging.ERROR, True)

            # Check InnoDB compatibility
            errors = rpl.check_innodb_compatibility(self.options)
            for error in errors:
                self._report(error, logging.ERROR, True)

            # Checking storage engines
            errors = rpl.check_storage_engines(self.options)
            for error in errors:
                self._report(error, logging.ERROR, True)

            # Check master for binary logging
            errors = rpl.check_master_binlog()
            if not errors == []:
                raise UtilRplError(errors[0])

            # Setup replication
            if not rpl.setup(self.rpl_user, 10):
                msg = "Cannot setup replication."
                self._report(msg, logging.CRITICAL, False)
                raise UtilRplError(msg)
        else:
            # Parse user and password (support login-paths)
            (r_user, r_pass,) = parse_user_password(self.rpl_user)

            # Switch master and start slave
            slave.switch_master(master, r_user, r_pass)
            slave.start({'fetch': False})

        # Disconnect from servers
        master.disconnect()
        slave.disconnect()
예제 #7
0
    def _setup_replication(self, master_vals, use_rpl_setup=True):
        """Setup replication among a master and a slave.

        master_vals[in]      Master server connection dictionary.
        use_rpl_setup[in]    Use Replication.setup() if True otherwise use
                             switch_master() on the slave. This is used to
                             control the first pass in the masters round-robin
                             scheduling.
        """
        conn_options = {
            "src_name": "master",
            "dest_name": "slave",
            "version": "5.0.0",
            "unique": True,
        }
        (master, slave,) = connect_servers(master_vals, self.slave_vals,
                                           conn_options)
        rpl_options = self.options.copy()
        rpl_options["verbosity"] = self.verbosity > 0

        # Start from beginning only on the first pass
        if rpl_options.get("from_beginning", False) and not use_rpl_setup:
            rpl_options["from_beginning"] = False

        # Create an instance of the replication object
        rpl = Replication(master, slave, rpl_options)

        if use_rpl_setup:
            # Check server ids
            errors = rpl.check_server_ids()
            for error in errors:
                self._report(error, logging.ERROR, True)

            # Check for server_id uniqueness
            errors = rpl.check_server_uuids()
            for error in errors:
                self._report(error, logging.ERROR, True)

            # Check InnoDB compatibility
            errors = rpl.check_innodb_compatibility(self.options)
            for error in errors:
                self._report(error, logging.ERROR, True)

            # Checking storage engines
            errors = rpl.check_storage_engines(self.options)
            for error in errors:
                self._report(error, logging.ERROR, True)

            # Check master for binary logging
            errors = rpl.check_master_binlog()
            if errors != []:
                raise UtilRplError(errors[0])

            # Setup replication
            if not rpl.setup(self.rpl_user, 10):
                msg = "Cannot setup replication."
                self._report(msg, logging.CRITICAL, False)
                raise UtilRplError(msg)
        else:
            # Parse user and password (support login-paths)
            try:
                (r_user, r_pass,) = parse_user_password(self.rpl_user)
            except FormatError:
                raise UtilError(USER_PASSWORD_FORMAT.format("--rpl-user"))

            # Switch master and start slave
            slave.switch_master(master, r_user, r_pass)
            slave.start({'fetch': False})

        # Disconnect from servers
        master.disconnect()
        slave.disconnect()
예제 #8
0
    def _get_slaves(self, max_depth, seed_conn=None, masters_found=None):
        """Find the attached slaves for a list of server connections.

        This method connects to each server in the list and retrieves its
        slaves. It can be called recursively if the recurse option is True.

        max_depth[in]       Maximum depth of recursive search
        seed_conn[in]       Current master connection dictionary. Initially,
                            this is the seed server (original master defined
                            in constructor)
        masters_found[in]   a list of all servers in master roles - used to
                            detect a circular replication topology. Initially,
                            this is an empty list as the master detection must
                            occur as the topology is traversed.

        Returns list - list of slaves connected to each server in list
        """
        if not masters_found:
            masters_found = []
        topology = []
        if seed_conn is None:
            seed_conn = self.seed_server

        master, master_info = self._connect(seed_conn)
        if master is None:
            return []

        # Check user permissions
        self._check_permissions(master, "REPLICATION SLAVE")

        # Save the master for circular replication identification
        masters_found.append(master_info)

        if not self.quiet:
            print "# Finding slaves for master: %s" % master_info

        # See if the user wants us to discover slaves.
        discover = self.options.get("discover", None)
        if discover is None:
            return

        # Get user and password (supports login-paths)
        user, password = parse_user_password(discover, options=self.options)

        # Get replication topology
        slaves = master.get_slaves(user, password)
        slave_list = []
        depth = 0
        if len(slaves) > 0:
            for slave in slaves:
                if slave.find(":") > 0:
                    host, port = slave.split(":", 1)
                else:
                    host = slave
                    port = _START_PORT  # Use the default
                slave_conn = self.seed_server.copy()
                slave_conn['host'] = host
                slave_conn['port'] = port

                io_sql_running = None
                # If verbose then get slave threads (IO and SQL) status
                if self.verbose:
                    # Create slave instance
                    conn_dict = {
                        'conn_info': {'user': user, 'passwd': password,
                                      'host': host, 'port': port,
                                      'socket': None},
                        'role': slave,
                        'verbose': self.verbose
                    }
                    slave_obj = Slave(conn_dict)
                    # Get IO and SQL status
                    try:
                        slave_obj.connect()
                        thread_status = slave_obj.get_thread_status()
                        if thread_status:
                            io_sql_running = (thread_status[1],
                                              thread_status[2])
                    except UtilError:
                        # Connection error
                        io_sql_running = ('ERROR', 'ERROR')

                # Now check for circular replication topology - do not recurse
                # if slave is also a master.
                if self.recurse and not slave in masters_found and \
                   ((max_depth is None) or (depth < max_depth)):
                    new_list = self._get_slaves(max_depth, slave_conn,
                                                masters_found)
                    if new_list == []:
                        slave_list.append((slave, [], io_sql_running))
                    else:
                        # Add IO and SQL state to slave from recursion
                        if io_sql_running:
                            new_list = [(new_list[0][0], new_list[0][1],
                                         io_sql_running)]
                        slave_list.append(new_list)
                    depth += 1
                else:
                    slave_list.append((slave, [], io_sql_running))
        topology.append((master_info, slave_list))

        return topology
예제 #9
0
    def _get_slaves(self, max_depth, seed_conn=None, masters_found=[]):
        """Find the attached slaves for a list of server connections.
        
        This method connects to each server in the list and retrieves its slaves.
        It can be called recursively if the recurse option is True.
    
        max_depth[in]       Maximum depth of recursive search
        seed_conn[in]       Current master connection dictionary. Initially,
                            this is the seed server (original master defined
                            in constructor)
        masters_found[in]   a list of all servers in master roles - used to
                            detect a circular replication topology. Initially,
                            this is an empty list as the master detection must
                            occur as the topology is traversed.
    
        Returns list - list of slaves connected to each server in list
        """
        topology = []
        if seed_conn is None:
            seed_conn = self.seed_server

        master, master_info = self._connect(seed_conn)
        if master is None:
            return []

        # Check user permissions
        self._check_permissions(master, "REPLICATION SLAVE")

        # Save the master for circular replication identification
        masters_found.append(master_info)

        if not self.quiet:
            print "# Finding slaves for master: %s" % master_info

        # See if the user wants us to discover slaves.
        discover = self.options.get("discover", None)
        if discover is None:
            return

        # Get user and password (supports login-paths)
        user, password = parse_user_password(discover, options=self.options)

        # Get replication topology
        slaves = master.get_slaves(user, password)
        slave_list = []
        depth = 0
        if len(slaves) > 0:
            for slave in slaves:
                if slave.find(":") > 0:
                    host, port = slave.split(":", 1)
                else:
                    host = slave
                    port = _START_PORT  # Use the default
                slave_conn = self.seed_server.copy()
                slave_conn['host'] = host
                slave_conn['port'] = port

                # Now check for circular replication topology - do not recurse
                # if slave is also a master.
                if self.recurse and not slave in masters_found and \
                   ((max_depth is None) or (depth < max_depth)):
                    new_list = self._get_slaves(max_depth, slave_conn,
                                                masters_found)
                    if new_list == []:
                        slave_list.append((slave, []))
                    else:
                        slave_list.append(new_list)
                    depth += 1
                else:
                    slave_list.append((slave, []))
        topology.append((master_info, slave_list))

        return topology
예제 #10
0
    def _get_slaves(self, max_depth, seed_conn=None, masters_found=[]):
        """Find the attached slaves for a list of server connections.
        
        This method connects to each server in the list and retrieves its slaves.
        It can be called recursively if the recurse option is True.
    
        max_depth[in]       Maximum depth of recursive search
        seed_conn[in]       Current master connection dictionary. Initially,
                            this is the seed server (original master defined
                            in constructor)
        masters_found[in]   a list of all servers in master roles - used to
                            detect a circular replication topology. Initially,
                            this is an empty list as the master detection must
                            occur as the topology is traversed.
    
        Returns list - list of slaves connected to each server in list
        """
        topology = []
        if seed_conn is None:
            seed_conn = self.seed_server
    
        master, master_info = self._connect(seed_conn)
        if master is None:
            return []
   
        # Check user permissions 
        self._check_permissions(master, "REPLICATION SLAVE")

        # Save the master for circular replication identification
        masters_found.append(master_info)
        
        if not self.quiet:
            print "# Finding slaves for master: %s" % master_info
    
        # See if the user wants us to discover slaves.
        discover = self.options.get("discover", None)
        if discover is None:
            return
        
        # Get user and password (supports login-paths)
        user, password = parse_user_password(discover, options=self.options)

        # Get replication topology
        slaves = master.get_slaves(user, password)
        slave_list = []
        depth = 0
        if len(slaves) > 0:
            for slave in slaves:
                if slave.find(":") > 0:
                    host, port = slave.split(":", 1)
                else:
                    host = slave
                    port = _START_PORT  # Use the default
                slave_conn = self.seed_server.copy()
                slave_conn['host'] = host
                slave_conn['port'] = port
                
                # Now check for circular replication topology - do not recurse
                # if slave is also a master.
                if self.recurse and not slave in masters_found and \
                   ((max_depth is None) or (depth < max_depth)):
                    new_list = self._get_slaves(max_depth, slave_conn,
                                                masters_found)
                    if new_list == []:
                        slave_list.append((slave, []))
                    else:
                        slave_list.append(new_list)
                    depth += 1
                else:
                    slave_list.append((slave, []))
        topology.append((master_info, slave_list))
    
        return topology