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
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
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
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
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
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()
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()
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
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