class LBController: def __init__(self, ctx_cluster: CtxCluster): self.node_client = Node(ctx_cluster) def add_labels(self, ip_list: List[str]): """添加lb的标签""" node_label_list = self._construct_node_label_list(ip_list) self.node_client.set_labels_for_multi_nodes(node_label_list) def delete_labels(self, ip_list: List[str]): node_label_list = self._construct_node_label_list(ip_list, LBLabelOp.DELETE) self.node_client.set_labels_for_multi_nodes(node_label_list) def _construct_node_label_list(self, ip_list: List[str], op: str = LBLabelOp.ADD) -> List: """查询节点的标签""" node_list = self.node_client.list(is_format=False) # 获取节点标签 node_label_list = [] for node in node_list.items: if node.inner_ip not in ip_list: continue labels = self._construct_labels_by_op(node.labels, op) node_label_list.append({"node_name": node.name, "labels": labels}) return node_label_list def _construct_labels_by_op(self, labels: Dict, op: str = LBLabelOp.ADD) -> Dict: if op == LBLabelOp.ADD: labels.update(K8S_LB_LABEL) else: for key in K8S_LB_LABEL: labels[key] = None return labels
def query_cluster_nodes(ctx_cluster: CtxCluster) -> Dict[str, Dict]: # 查询集群下node信息 client = Node(ctx_cluster) nodes = client.list() # 根据传入的inner_ip过滤节点信息 data = {} for node in nodes: node_data = node.data # 解析数据用于前端展示 metadata = node_data.get("metadata", {}) labels = metadata.get("labels", {}) # 过滤掉master if labels.get("node-role.kubernetes.io/master") == "true": continue taints = getitems(node_data, ["spec", "taints"], []) # 组装数据,用于展示 data[node.inner_ip] = { "inner_ip": node.inner_ip, "name": node.name, "labels": labels, "taints": taints, "status": get_node_status(getitems(node_data, ["status", "conditions"], [])), "unschedulable": getitems(node_data, ["spec", "unschedulable"], False), } return data
class NodeRespBuilder: """构造节点 API 返回 TODO: 现阶段返回先方便前端处理,拆分后,调整返回为{manifest: xxx, manifest_ext: xxx} manifest中放置原始node数据, manifest_ext中存放处理的状态等数据 """ def __init__(self, ctx_cluster: CtxCluster): self.client = Node(ctx_cluster) def list_nodes(self) -> Dict: """查询节点列表""" nodes = self.client.list(is_format=False) return { "manifest": nodes.data.to_dict(), "manifest_ext": { node.metadata["uid"]: { "status": node.node_status, "labels": { key: "readonly" for key in filter_label_keys(node.labels.keys()) }, } for node in nodes.items }, } def query_labels(self, node_names: List[str]) -> Dict[str, Dict]: """查询节点标签 TODO: 这里是兼容处理,方便前端使用,后续前端直接通过列表获取数据 """ node_labels = self.client.filter_nodes_field_data( "labels", filter_node_names=node_names, default_data={}) return node_labels
def query_cluster_nodes(ctx_cluster: CtxCluster, exclude_master: bool = True) -> Dict: """查询节点数据 包含标签、污点、状态等供前端展示数据 """ # 获取集群中的节点列表 node_client = Node(ctx_cluster) try: cluster_node_list = node_client.list(is_format=False) except ApiException: # 查询集群内节点异常,返回空字典 return {} nodes = {} for node in cluster_node_list.items: labels = node.labels # 现阶段节点页面展示及操作,需要排除master if exclude_master and labels.get( node_constants.K8S_NODE_ROLE_MASTER) == "true": continue # 使用inner_ip作为key,主要是方便匹配及获取值 nodes[node.inner_ip] = { "inner_ip": node.inner_ip, "name": node.name, "status": node.node_status, "labels": labels, "taints": node.taints, "unschedulable": node.data.spec.unschedulable or False, } return nodes
def _get_cluster_masters(self) -> List[Dict]: """查询集群中的master ip和name""" node_client = Node(self.ctx_cluster) # NOTE: 返回节点出现异常,直接报错 cluster_nodes = node_client.list(is_format=False) # 过滤 master 信息 masters = [] for node in cluster_nodes.items: if not node.is_master(): return masters.append({"inner_ip": node.inner_ip, "host_name": node.name}) return masters