#!/usr/bin/python # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. from os import sys, path from utility import getHealthChecksData, formatPort def checkMaxconn(haproxyData, haCfgSections): if "maxconn" in haproxyData and "maxconn" in haCfgSections["global"]: if haproxyData["maxconn"] != haCfgSections["global"]["maxconn"][0].strip(): print "global maxconn mismatch occurred" return False return True def checkLoadBalance(haproxyData, haCfgSections): correct = True for lbSec in haproxyData: srcServer = lbSec["sourceIp"].replace('.', '_') + "-" + \ formatPort(lbSec["sourcePortStart"], lbSec["sourcePortEnd"]) secName = "listen " + srcServer if secName not in haCfgSections: print "Missing section for load balancing " + secName + "\n" correct = False else: cfgSection = haCfgSections[secName] if "server" in cfgSection: if lbSec["algorithm"] != cfgSection["balance"][0]: print "Incorrect balance method for " + secName + \ "Expected : " + lbSec["algorithm"] + \ " but found " + cfgSection["balance"][0] + "\n" correct = False bindStr = lbSec["sourceIp"] + ":" + formatPort(lbSec["sourcePortStart"], lbSec["sourcePortEnd"]) if cfgSection["bind"][0] != bindStr: print "Incorrect bind string found. Expected " + bindStr + " but found " + cfgSection["bind"][0] + "." correct = False if (lbSec["sourcePortStart"] == "80" and lbSec["sourcePortEnd"] == "80" and lbSec["keepAliveEnabled"] == "false") \ or (lbSec["stickiness"].find("AppCookie") != -1 or lbSec["stickiness"].find("LbCookie") != -1): if not ("mode" in cfgSection and cfgSection["mode"][0] == "http"): print "Expected HTTP mode but not found" correct = False expectedServerIps = lbSec["vmIps"].split(" ") for expectedServerIp in expectedServerIps: pattern = expectedServerIp + ":" + \ formatPort(lbSec["destPortStart"], lbSec["destPortEnd"]) foundPattern = False for server in cfgSection["server"]: s = server.split() if s[0].strip().find(srcServer + "_") == 0 and s[1].strip() == pattern: foundPattern = True break if not foundPattern: correct = False print "Missing load balancing for " + pattern + ". " return correct def main(): ''' Checks for max con and each load balancing rule - source ip, ports and destination ips and ports. Also checks for http mode. Does not check for stickiness policies. ''' haproxyData = getHealthChecksData("haproxyData") if haproxyData is None or len(haproxyData) == 0: print "No data provided to check, skipping" exit(0) with open("/etc/haproxy/haproxy.cfg", 'r') as haCfgFile: haCfgLines = haCfgFile.readlines() haCfgFile.close() if len(haCfgLines) == 0: print "Unable to read config file /etc/haproxy/haproxy.cfg" exit(1) haCfgSections = {} currSection = None currSectionDict = {} for line in haCfgLines: line = line.strip() if len(line) == 0: if currSection is not None and len(currSectionDict) > 0: haCfgSections[currSection] = currSectionDict currSection = None currSectionDict = {} continue if currSection is None: currSection = line else: lineSec = line.split(' ', 1) if lineSec[0] not in currSectionDict: currSectionDict[lineSec[0]] = [] currSectionDict[lineSec[0]].append(lineSec[1] if len(lineSec) > 1 else '') checkMaxConn = checkMaxconn(haproxyData[0], haCfgSections) checkLbRules = checkLoadBalance(haproxyData, haCfgSections) if checkMaxConn and checkLbRules: print "All checks pass" exit(0) else: exit(1) if __name__ == "__main__": if len(sys.argv) == 2 and sys.argv[1] == "advanced": main()