Beispiel #1
0
def add(name, new_lbinfos):
    """ 增加 lb.

    """
    # 检查集群是否存在.
    checkdict = {
        "name": name,
    }
    if not funcs.check(checkdict, check_exist=True):
        logger.error("No cluster:%s" % name)
        return False

    # 获取新增 lb.
    new_lbs = [i["hostname"] for i in new_lbinfos]
    if len(new_lbs) != len(set(new_lbs)):
        logger.error("Lb duplicates")
        return False

    # 检查新增 lb 是否已经存在.
    checkdict = {
        "lbs": new_lbs
    }
    if not funcs.check(checkdict, check_exist=False):
        logger.error("Some lbs exist")
        return False

    # 对所有 lb 安装 lvs fullnat.
    ret = funcs.lb_multi(new_lbs)
    fails = [ i for i in ret if not i["result"]]
    if fails != []:
        message = "Some lbs install failed:%s" % \
            ",".join(fails)
        logger.error(message)
        return False
    message = "All lbs install success:%s" % \
        ",".join(new_lbs)
    logger.info(message)

    # 获取已有集群信息.
    key = "cluster:%s" % name
    _type = client.hget(key, "type")
    old_lbinfos = eval(client.hget(key, "lbinfos"))
    device = client.hget(key, "device")

    # 获取新的 lbinfos.
    lbinfos = copy.deepcopy(old_lbinfos)
    lbinfos.extend(new_lbinfos)
    del old_lbinfos

    # 配置 lb.
    for lbinfo in new_lbinfos:
        lb = lbinfo["hostname"]
        internalip = lbinfo["internalip"]
        internalnetmask = lbinfo["internalnetmask"]
        internalgateway = lbinfo["internalgateway"]

        # 如果 _type 是 extra, 需要公网 IP;
        # 如果 _type 是 internal, 不需要公网 IP.
        extraip = lbinfo.get("extraip", None)
        extranetmask = lbinfo.get("extranetmask", None)
        extragateway = lbinfo.get("extragateway", None)

        # 配置 IP.
        ret = funcs.ip(lb, _type, device, internalip, 
                       internalnetmask, internalgateway, extraip, 
                       extranetmask, extragateway)
        if not ret:
            return False

        # 配置 lip.
        _lips = lips.get(internalip, internalnetmask)
        ret = funcs.lips(lb, internalip, _lips)
        if not ret:
            logger.error("Cfg lb lips failed:%s" % lb)
            return False
        logger.info("Cfg lb lips success:%s" % lb)

    # 保存集群信息.
    client.hset(key, "lbinfos", lbinfos)
    
    logger.info("Lbs added:%s" % ",".join(new_lbs)) 
    return True
Beispiel #2
0
def generate(_type, lbinfos, vip2ws, vipnets, device):
    """ 生成和传输 keepalived 配置.

    """
    j2_env = Environment(loader=FileSystemLoader(LVS_TEMPLATE_DIR),
                         trim_blocks=True)

    # 各个模板文件名.
    keepalived_template = "keepalived.conf"
    sub_keepalived_template = "sub_keepalived.conf"
    zebra_template = "zebra.conf"
    ospfd_template = "ospfd.conf"

    # 建立存放 lvs 临时配置文件基目录.
    # lb 的配置文件分别几个部分, 一个是 keepalived.conf 主配置
    # 文件, 这个文件需要引用每个 VIP 的配置, 额外还需要 ospfd.conf
    # 和 zebra.conf 配置. 对于 VIP 配置, 所有 lb 都是一样的, 
    # keepalived.conf 主配置文件、 ospfd.conf 和 zebra.conf
    # 则每个 lb 都不一样.
    # 基目录下目录结构这么存放:
    # lbcommon 里面存 每个 lb 都一样的 VIP 配置;
    # 对于 每个 lb 建立一个目录, 下面有两个子目录, 分别是:
    # keepalived 和 ospfd, keepalived 下面是 keepalived.conf,
    # ospfd 下面是 ospfd.conf 和 zebra.conf.
    # 比如:
    #   ./lbcommon/xxx.xxx.xxx.xxx.conf
    #   ./$lb/ospfd/ospfd.conf
    #   ./$lb/ospfd/zebra.conf
    #   ./$lb/keepalived/keepalived.conf
    now = time.strftime("%Y%m%d%H%I%M%S")
    base_dir = LVS_CFG_TMP_DIR + "/" + now
    os.mkdir(base_dir)

    # 拿到 lb 和 vip.
    lbs = [i["hostname"] for i in lbinfos]
    vips = [i["vip"] for i in vip2ws]

    try:
        for lbinfo in lbinfos:
            lb = lbinfo["hostname"]
            internalip = lbinfo["internalip"]
            internalnetmask = lbinfo["internalnetmask"]
            internalgateway = lbinfo["internalgateway"]
            routerid = lbinfo["routerid"]
            ospfnet = lbinfo["ospfnet"]

            if _type == "extra":
                extraip = lbinfo["extraip"]
                extranetmask = lbinfo["extranetmask"]
                extragateway = lbinfo["extragateway"]

            _lips = lips.get(internalip, internalnetmask)

            # 对每个 lb 创建临时目录.
            lb_dir = base_dir + "/" + lb
            lb_keepalived_dir = lb_dir + "/keepalived"
            lb_osfpd_dir = lb_dir + "/ospfd"
            os.mkdir(lb_dir)
            os.mkdir(lb_keepalived_dir)
            os.mkdir(lb_osfpd_dir)

            # 对于 lb 生成配置.
            with open(lb_keepalived_dir + "/keepalived.conf", 'w') as f:
                f.writelines(
                    j2_env.get_template(keepalived_template).render(
                        lips=_lips, vips=vips, lb=lb.split(".")[0]
                    )                    
                )
            with open(lb_osfpd_dir + "/zebra.conf", 'w') as f:
                f.writelines(
                    j2_env.get_template(zebra_template).render(
                        lb=lb
                    )                    
                )
            with open(lb_osfpd_dir + "/ospfd.conf", 'w') as f:
                f.writelines(
                    j2_env.get_template(ospfd_template).render(
                        lb=lb, routerid=routerid, device=device, 
                        ospfnet=ospfnet, vipnets=vipnets
                    )                    
                )

        # 创建公共临时目录.
        lb_common_dir = base_dir + "/lbcommon"
        os.mkdir(lb_common_dir)

        # 获取 ports 和 wss.
        for vip in vips:
            for i in vip2ws:
                if vip == i["vip"]:
                    if "ports" not in i:
                        ports = [
                            {"sport": 80,
                             "dport": 80,
                             "synproxy": 1,
                             "persistence_timeout": 50
                             },
                            {"sport": 443,
                             "dport": 443,
                             "synproxy": 1,
                             "persistence_timeout": 50
                             }
                        ]
                    else:
                        ports = list()
                        for j in i["ports"]:
                            if "synproxy" not in j:
                                j["synproxy"] = 1
                            elif "persistence_timeout" not in j:
                                j["persistence_timeout"] = 50
                            ports.append(j)
                    wss = i["wss"]
                    break

            # 把 wss 解析成 IP.
            wss_ip = utils.dns_resolv(wss)
            if not wss_ip:
                message = "Some ws dns resolv failed, wss:%s" % wss
                logger.error(message)
                return False

            # 生成公共的 VIP 配置.
            with open(lb_common_dir + "/" + vip + ".conf", 'w') as f:
                f.writelines(
                    j2_env.get_template(sub_keepalived_template).render(
                        vip=vip, ports=ports, wss=wss_ip
                    )
                )

        message = "Make keepalived cfg success"
        logger.info(message)
    except Exception, e:
        message = "Make keepalived cfg failed:%s" % e
        logger.error(message)
        return False