def _create_node(self, addr_port_tls, force=False): """ Instantiate and return a new node If cannot instantiate node, return None. Creates a new node if: 1) key(addr,port) is not available in self.aliases """ try: # tuple of length 3 for server version >= 3.10.0 (with tls name) addr, port, tls_name = addr_port_tls except Exception: try: # tuple of length 2 for server version < 3.10.0 ( without tls # name) addr, port = addr_port_tls tls_name = None except Exception: print "ip_port is expected to be a tuple of len 2, " + \ "instead it is of type %s and str value of %s" % ( type(addr_port_tls), str(addr_port_tls)) return None try: if self.is_present_as_alias(addr, port): # Alias entry already added for this endpoint n = self.get_node_for_alias(addr, port) if n: # Node already added for this endpoint # No need to check for offline/online as we already did # this while finding new nodes to add return n # else # Will create node again # if not existing: new_node = Node(addr, port, tls_name=tls_name, timeout=self._timeout, user=self.user, password=self.password, auth_mode=self.auth_mode, consider_alumni=Cluster.use_services_alumni, use_services_alt=Cluster.use_services_alt, ssl_context=self.ssl_context) if not new_node: return new_node if not new_node.alive: if not force: # Check other endpoints new_node.close() return None self.update_node(new_node) self.update_aliases(self.aliases, new_node.service_addresses, new_node.key) return new_node except Exception: return None
def setUp(self): self.cluster_patch = patch('lib.client.cluster.Cluster') #self.view_patch = patch('lib.view.CliView') real_stdoup = sys.stdout sys.stdout = StringIO() self.addCleanup(patch.stopall) self.addCleanup(reset_stdout) self.MockCluster = self.cluster_patch.start() #self.MockView = self.view_patch.start() Cluster._crawl = classmethod(lambda self: None) Cluster.call_node_method = classmethod( lambda self, nodes, method_name, *args, **kwargs: {"test": IOError("test error")}) n = Node("172.99.99.99") Cluster.get_node = classmethod(lambda self, key: [n]) pd = LookupDict() pd['test'] = 'test' Cluster.get_node_displaynames = classmethod(lambda self: pd) self.rc = BasicRootController()
def get_node_for_alias(self, addr, port): try: if self.is_present_as_alias(addr, port): return self.nodes[self.aliases[Node.create_key(addr, port)]] except Exception: pass return None
def get_info_mock(self, return_value, return_key_value={}, ip="127.0.0.1"): def info_cinfo_side_effect(*args): ip_last_digit = ip.split(".")[3] cmd = args[0] if cmd == "service": return str(ip)+":3000;" + "192.168.120." + ip_last_digit + ":3000" if cmd == "service-clear-std": return str(ip)+":3000;172.17.0.1:3000,172.17.1.1:3000" if cmd == "service-tls-std": return "172.17.0.1:4333,172.17.1.1:4333" if cmd == "service-clear-alt": return "172.17.0.2:3000,172.17.1.2:3000" if cmd == "service-tls-alt": return "172.17.0.2:4333,172.17.1.2:4333" if cmd == "services": return "192.168.120." + ip_last_digit + ":3000;127.0.0." + ip_last_digit + ":3000" if cmd == "services-alumni": return "192.168.123." + ip_last_digit + ":3000;127.3.0." + ip_last_digit + ":3000" if cmd == "services-alternate": return "192.168.122." + ip_last_digit + ":3000;127.2.0." + ip_last_digit + ":3000" if cmd == "peers-clear-std": return "10,3000,[[BB9050011AC4202,,[172.17.0.1]],[BB9070011AC4202,,[[2001:db8:85a3::8a2e]:6666]]]" if cmd == "peers-tls-std": return "10,4333,[[BB9050011AC4202,peers,[172.17.0.1]],[BB9070011AC4202,peers,[[2001:db8:85a3::8a2e]]]]" if cmd == "alumni-clear-std": return "0,3000,[[BB9050011AC4202,,[172.17.0.3]]]" if cmd == "alumni-tls-std": return "0,4333,[[BB9050011AC4202,peers-alumni,[172.17.0.3]]]" if cmd == "peers-clear-alt": return "0,3000,[[BB9050011AC4202,,[172.17.0.2]]]" if cmd == "peers-tls-alt": return "0,4333,[[BB9050011AC4202,peers-alt,[172.17.0.2]]]" if cmd in return_key_value: return return_key_value[cmd] return return_value Node._info_cinfo = Mock(side_effect=info_cinfo_side_effect) # Node._info_cinfo.return_value = side_effect n = Node(ip) return n
def test_update_aliases(self): cl = self.get_cluster_mock(3) aliases = {} endpoints = [('127.0.0.1', 3000)] key1 = Node.create_key('127.0.0.2', 3000) cl.update_aliases(aliases, endpoints, key1) expected = {'127.0.0.1:3000': '127.0.0.2:3000'} self.assertEqual(aliases, expected, "update_aliases did not return the expected result") key2 = Node.create_key('127.0.0.3', 3000) cl.update_aliases(aliases, endpoints, key2) self.assertEqual(aliases, expected, "update_aliases did not return the expected result") n = cl.nodes[key1] n.alive = False cl.nodes[key1] = n cl.update_aliases(aliases, endpoints, key2) expected = {'127.0.0.1:3000': '127.0.0.3:3000'} self.assertEqual(aliases, expected, "update_aliases did not return the expected result")
def get_info_mock(self, return_value, return_key_value={}): def info_cinfo_side_effect(*args): cmd = args[0] if cmd == "service": return "192.168.120.111:3000;127.0.0.1:3000" if cmd == "service-clear-std": return "172.17.0.1:3000,172.17.1.1:3000" if cmd == "service-tls-std": return "172.17.0.1:4333,172.17.1.1:4333" if cmd == "service-clear-alt": return "172.17.0.2:3000,172.17.1.2:3000" if cmd == "service-tls-alt": return "172.17.0.2:4333,172.17.1.2:4333" if cmd == "services": return "192.168.120.111:3000;127.0.0.1:3000" if cmd == "services-alumni": return "192.168.120.113:3000;127.0.0.3:3000" if cmd == "services-alternate": return "192.168.120.112:3000;127.0.0.2:3000" if cmd == "peers-clear-std": return "10,3000,[[BB9050011AC4202,,[172.17.0.1]],[BB9070011AC4202,,[[2001:db8:85a3::8a2e]:6666]]]" if cmd == "peers-tls-std": return "10,4333,[[BB9050011AC4202,peers,[172.17.0.1]],[BB9070011AC4202,peers,[[2001:db8:85a3::8a2e]]]]" if cmd == "alumni-clear-std": return "0,3000,[[BB9050011AC4202,,[172.17.0.3]]]" if cmd == "alumni-tls-std": return "0,4333,[[BB9050011AC4202,peers-alumni,[172.17.0.3]]]" if cmd == "peers-clear-alt": return "0,3000,[[BB9050011AC4202,,[172.17.0.2]]]" if cmd == "peers-tls-alt": return "0,4333,[[BB9050011AC4202,peers-alt,[172.17.0.2]]]" if cmd in return_key_value: return return_key_value[cmd] return return_value Node._info_cinfo = Mock(side_effect=info_cinfo_side_effect) # Node._info_cinfo.return_value = side_effect n = Node("127.0.0.1") return n
def update_aliases(self, aliases, endpoints, key): for e in endpoints: try: addr = e[0] port = e[1] node_key = Node.create_key(addr, port) if len(aliases) == 0 or not node_key in aliases: # same node's service addresses not added already aliases[node_key] = key else: # same node's service addresses added already # Ex. NIC down IP available in service list # Avoid creation of two nodes aliases_node_key = aliases[node_key] if aliases_node_key != key: node = self.nodes[aliases_node_key] if not node.alive: aliases[node_key] = key except Exception: pass
def get_down_nodes(self): cluster_down_nodes = [] for k in self.nodes.keys(): try: node = self.nodes[k] if not node.alive: # in case of using alumni services, we might have offline # nodes which can't detect online nodes continue alumni_peers = util.flatten(node.get_alumni_peers()) peers = util.flatten(node.get_peers()) not_visible = set(alumni_peers) - set(peers) if len(not_visible) >= 1: for n in not_visible: _key = Node.create_key(n[0], n[1]) if _key not in cluster_down_nodes: cluster_down_nodes.append(_key) except Exception: pass return cluster_down_nodes
def get_info_mock(self, return_value): Node._info_cinfo.return_value = return_value n = Node("127.0.0.1") return n
def get_info_mock(self, return_value): n = Node("127.0.0.1") return n
def is_present_as_alias(self, addr, port, aliases=None): if not aliases: aliases = self.aliases return Node.create_key(addr, port) in aliases