def test_remove_node_from_cluster_config(thr): thr.add_cluster_node('node3') unset_lazy(thr, "cluster_nodes") assert Ccfg().cluster_nodes == [Env.nodename, 'node3'] response = PostLeave().action('node3', thr=thr) assert Ccfg().cluster_nodes == [Env.nodename] assert response == {'status': 0}
def join(self, nodename, thr=None, **kwargs): if nodename in thr.cluster_nodes: new_nodes = thr.cluster_nodes thr.log.info("node %s rejoins", nodename) else: new_nodes = thr.cluster_nodes + [nodename] thr.add_cluster_node(nodename) result = { "status": 0, "data": { "node": { "data": { "node": {}, "cluster": {}, }, }, }, } config = shared.NODE.private_cd node_section = config.get("node", {}) cluster_section = config.get("cluster", {}) if "env" in node_section: result["data"]["node"]["data"]["node"]["env"] = shared.NODE.env if "nodes" in cluster_section: result["data"]["node"]["data"]["cluster"]["nodes"] = " ".join(new_nodes) if "name" in cluster_section: result["data"]["node"]["data"]["cluster"]["name"] = thr.cluster_name if "drpnodes" in cluster_section: result["data"]["node"]["data"]["cluster"]["drpnodes"] = " ".join(thr.cluster_drpnodes) if "id" in cluster_section: result["data"]["node"]["data"]["cluster"]["id"] = thr.cluster_id if "quorum" in cluster_section: result["data"]["node"]["data"]["cluster"]["quorum"] = thr.quorum if "dns" in cluster_section: result["data"]["node"]["data"]["cluster"]["dns"] = " ".join(shared.NODE.dns) for section in config: if section.startswith("hb#") or \ section.startswith("stonith#") or \ section.startswith("pool#") or \ section.startswith("network#") or \ section.startswith("arbitrator#"): result["data"]["node"]["data"][section] = config[section] from core.objects.ccfg import Ccfg svc = Ccfg(volatile=True, node=shared.NODE) if svc.exists(): result["data"]["cluster"] = { "data": svc.print_config_data(), "mtime": os.stat(svc.paths.cf).st_mtime, } return result
def networks_data(self): nets = self.networks_data_from_cni_confs() sections = list(self.conf_sections("network")) if "network#default" not in sections: sections.append("network#default") for section in sections: _, name = section.split("#", 1) config = {} config["type"] = self.oget(section, "type") for key in self.section_kwargs(section, config["type"]): config[key] = self.oget(section, key, rtype=config["type"]) if config["type"] == "routed_bridge": config["subnets"] = self.oget_scopes(section, "subnet", rtype=config["type"]) if not config: continue routes = self.routes(name, config) if config["type"] == "routed_bridge" and not any( config["subnets"][n] for n in config["subnets"]): self.log.info( "initial %s routed_bridge network subnets assignment:", name) kws = [] for route in routes: kw = "network#%s.subnet@%s=%s" % (name, route["node"], route["dst"]) kws.append(kw) self.log.info(" %s", kw) from core.objects.ccfg import Ccfg svc = Ccfg() svc.set_multi(kws, validation=False) self.unset_lazy("cd") config["subnets"] = self.oget_scopes(section, "subnet", rtype="routed_bridge") if name not in nets: nets[name] = {} nets[name]["config"] = config nets[name]["routes"] = routes nets[name]["tables"] = self.tables(name) nets["lo"] = { "config": { "type": "loopback", "network": "127.0.0.1/32", "tables": ["main"], }, } return nets
def cluster_name(self): """ Return the cluster name, read from cluster.name in the node configuration. If not set, return "default". """ node = self.get_node() try: return node.oget("cluster", "name").lower() except Exception as exc: pass name = "default" from core.objects.ccfg import Ccfg svc = Ccfg() svc.set_multi(["cluster.name=" + name], validation=False) return name
def cluster_id(self): """ Return the cluster id read from cluster.id in the node configuration. If not already set generate and store a random one. """ node = self.get_node() try: return node.conf_get("cluster", "id") except Exception as exc: pass import uuid from core.objects.ccfg import Ccfg cluster_id = str(uuid.uuid1()) svc = Ccfg() svc.set_multi(["cluster.id="+cluster_id], validation=False) return cluster_id
def cluster_key(self): """ Return the key read from cluster.secret in the node configuration. If not already set generate and store a random one. """ node = self.get_node() try: key = node.oget("cluster", "secret") return self.prepare_key(key) except Exception as exc: pass import uuid from core.objects.ccfg import Ccfg key = uuid.uuid1().hex svc = Ccfg() svc.set_multi(["cluster.secret="+key], validation=False) return self.prepare_key(key)
def cluster_nodes(self): """ Return the cluster nodes, read from cluster.nodes in the node configuration. If not set, return a list with the local node as the only element. """ node = self.get_node() if want_context(): return node._daemon_status()["cluster"]["nodes"] nodes = node.oget("cluster", "nodes") if nodes: if Env.nodename in nodes: return nodes else: nodes.append(Env.nodename) else: nodes = [Env.nodename] from core.objects.ccfg import Ccfg svc = Ccfg() svc.set_multi(["cluster.nodes=" + " ".join(nodes)], validation=False) node.unset_multi(["cluster.nodes"]) return nodes
def test_accept_remove_non_cluster_node(thr): assert Ccfg().cluster_nodes == [Env.nodename] response = PostLeave().action('node3', thr=thr) assert response == {'status': 0} assert Ccfg().cluster_nodes == [Env.nodename]
def test_return_dict_with_cluster_config_data(thr): response = PostJoin().action('node3', thr=thr) assert response['data']['cluster']['data'] == Ccfg().print_config_data()
def test_update_cluster_nodes(thr): PostJoin().action('node3', thr=thr) assert Ccfg().cluster_nodes == [Env.nodename, 'node3']
def test_update_cluster_nodes(thr): thr.add_cluster_node('node3') assert Ccfg().cluster_nodes == [Env.nodename, 'node3']