def check_docker_volume(config): vprint("Checking docker volume driver") if not exe_check("docker ps >/dev/null 2>&1"): return ff("Docker is not installed", "42BAAC76") if exe_check("docker plugin ls | grep {}".format(PLUGIN)): return ff("Datera Docker plugin is not installed", "6C531C5D") plugin = exe("docker plugin ls | grev -v DESCRIPTION | " "grep {}".format(PLUGIN)) if len(plugin.strip().split('\n')) > 1: wf("More than one version of Datera docker driver installed", "B3BF691D") if 'enabled' not in plugin or 'disabled' in plugin: ff("Datera docker plugin is not enabled") test_name = "ddct-test1" if not exe_check( "docker volume create -d {} --name {} --opt replica=1 --opt " "size=1".format(PLUGIN, test_name)): return ff("Could not create a volume with the Datera Docker plugin", "621A6F51") api = config['api'] try: api.app_instances.get(test_name) except ApiNotFoundError: return ff("Docker volume {} did not create on the Datera backend" "".format(test_name), "B106D1CD") if not exe_check("docker volume rm {}".format(test_name)): ff("Could not delete Docker volume {}".format(test_name), "AF3DB8B3")
def check_kubernetes_driver_flex(config): # Is kubectl present? if not exe_check("which kubectl"): return ff("Could not detect kubectl installation", "572B0511") # Does kubectl have a supported version? kversion = exe("kubectl version").strip().split("\n") for line in kversion: m1 = KCTL_MA_RE.search(line) m2 = KCTL_MI_RE.search(line) if not m1 and m2: return ff("Could not detect kubectl version", "C1802A6E") supported = calc_version(SUPPORTED_MAJOR, SUPPORTED_MINOR) major = m1.group(1) minor = m2.group(1) found = calc_version(major, minor) if found < supported: return ff( "Kubectl has version {}, which is lower than supported " "version {}".format(found, supported), "D2DA6596") # Are dependencies installed? if not exe_check("which mkfs"): ff("mkfs is not installed", "FE13A328") if not exe_check("which iscsiadm"): ff("sg3_utils does not appear to be installed", "94BF0B77") # Is attach-detach disabled in kubelet? exstart = exe("systemctl show kubelet.service | grep ExecStart") if "--enable-controller-attach-detach=false" not in exstart: wf( "Attach-detach is enabled in kublet's systemctl entry. Run " "--enable-controller-attach-detach=false when starting kubelet " "to disable", "5B3729F2") if "Active: active" in exe("systemctl status kubelet"): kpath = KPATH_RE.search(exstart).group(1) exstart = exe("ps -ef | grep {} | grep -v grep".format(kpath)) if "--enable-controller-attach-detach=false" not in exstart: ff( "Attach-detach is enabled in kublet. Run " "--enable-controller-attach-detach=false when starting kubelet " "to disable", "86FFD7F2") else: ff("The kubelet service is not running", "0762A89B") # Agents are running? pods = exe("kubectl --namespace=datera get pods").strip() if not pods: return ff("Installer agents and provisioner agents are not running", "244C0B34") installer_agent = False provisioner_agent = False for line in pods.split("\n"): if "datera-installer-agent" in line: installer_agent = True if "datera-provisioner-agent" in line: provisioner_agent = True if not installer_agent: ff("Installer agents not found", "08193032") if not provisioner_agent: ff("Provisioner agents not found", "3AAF82CA")
def check_vip2(config): vprint("Checking vip2 interface mtu match") vip2 = config.get('vip2_ip') if not vip2: wf("No vip2_ip found", "416B534D") return if is_l3: check_mtu_l3(vip2, config) else: check_mtu_normal("VIP2", vip2, config)
def vip1_check(config): vip1 = config["vip1_ip"] if not exe_check("ping -c 2 -W 1 {}".format(vip1), err=False): ff("Could not ping vip1 ip {}".format(vip1), "1827147B", fix=NET_FIX) timeout = 5 while not exe_check( "ip neigh show | grep {} | grep REACHABLE".format(vip1)): timeout -= 1 time.sleep(1) if timeout < 0: wf("Arp state for vip1 [{}] is not 'REACHABLE'".format(vip1), "3C33D70D") break
def check_iscsi(config): vprint("Checking ISCSI settings") if not exe_check("which iscsiadm"): if get_pkg_manager() == APT: fix = "apt-get install open-iscsi" elif get_pkg_manager() == YUM: fix = "yum install iscsi-initiator-utils" ff("iscsiadm is not available, has open-iscsi been installed?", "EFBB085C", fix=fix) if not exe_check("ps -ef | grep iscsid | grep -v grep"): fix = "service iscsi start || systemctl start iscsid.service" ff("iscsid is not running. Is the iscsid service running?", "EB22737E", fix=fix) ifile = "/etc/iscsi/iscsid.conf" if not os.path.exists(ifile): ff("iscsid configuration file does not exist", "C6F2B356") return with io.open(ifile, 'r') as f: iconf = f.readlines() noopt = "node.session.timeo.noop_out_timeout" noopt_found = False noopi = "node.session.timeo.noop_out_interval" noopi_found = False for index, line in enumerate(iconf): if not noopt_found and noopt in line: noopt_found = True if "2" not in line: ff("{} is not set to '2' in iscsid.conf".format(noopt), "F6A49337") elif noopt_found and noopt in line: wf( "{} duplicate found in iscsid.conf, line {}".format( noopt, index), "D3E55910") if noopi in line: noopi_found = True if "2" not in line: ff("{} is not set to '2' in iscsid.conf".format(noopi), "E48C1907") elif noopi_found and noopi in line: wf( "{} duplicate found in iscsid.conf, line {}".format( noopi, index), "CA9AA865") if not noopt_found: ff("'{} = 2' is not present in iscsid.conf".format(noopt), "E29BF18A") if not noopi_found: ff("'{} = 2' is not present in iscsid.conf".format(noopi), "A2EED511")
def vip2_check(config): vip2 = config.get("vip2_ip") if not vip2: wf("No vip2_ip found", "16EB208B") return if vip2 and not exe_check("ping -c 2 -W 1 {}".format(vip2), err=False): ff("Could not ping vip2 ip {}".format(vip2), "3D76CE5A", fix=NET_FIX) timeout = 5 while not exe_check( "ip neigh show | grep {} | grep REACHABLE".format(vip2)): timeout -= 1 time.sleep(1) if timeout < 0: wf("Arp state for vip2 [{}] is not 'REACHABLE'".format(vip2), "4F6B8D91") break
def mgmt_check(config): mgmt = config["mgmt_ip"] if not exe_check("ping -c 2 -W 1 {}".format(mgmt), err=False): ff("Could not ping management ip {}".format(mgmt), "65FC68BB", fix=NET_FIX) timeout = 5 while not exe_check( "ip neigh show | grep {} | grep REACHABLE".format(mgmt)): timeout -= 1 time.sleep(1) if timeout < 0: fix = "Check the connection to {}".format(mgmt) wf("Arp state for mgmt [{}] is not 'REACHABLE'".format(mgmt), "BF6A912A", fix=fix) break
def check_multipath_conf(config): dist = get_os() vfile = CONFS.get(dist) if not vfile: wf("No supported multipath.conf file for: {}".format(dist), "381CE248") mfile = "/etc/multipath.conf" if not os.path.exists(mfile): if not vfile: fix = "copy a multipath.conf file from the Datera Deployment Guide" else: fix = "copy {} to /etc/multipath.conf".format(vfile) return ff("/etc/multipath.conf file not found", "1D506D89", fix=fix) with io.open(mfile, 'r') as f: mconf = parse_mconf(f.read()) # Check defaults section defaults = filter(lambda x: x[0] == 'defaults', mconf) fix = ("check the example multipath.conf file from Datera deployment" "guide") if not defaults: ff("Missing defaults section", "1D8C438C", fix=fix) else: defaults = defaults[0] ct = False for d in defaults[1]: if 'checker_timeout' in d: ct = True if not ct: ff("defaults section missing 'checker_timeout'", "70191A9A", fix=fix) # Check devices section devices = filter(lambda x: x[0] == 'devices', mconf) if not devices: ff("Missing devices section", "797A6031", fix=fix) else: devices = devices[0][1] dat_block = None for _, device in devices: ddict = {} for entry in device: ddict[entry[0]] = entry[1] if ddict['vendor'] == 'DATERA': dat_block = ddict if not dat_block: return ff("No DATERA device section found", "99B9D136", fix=fix) if not dat_block['product'] == "IBLOCK": ff("Datera 'product' entry should be \"IBLOCK\"", "A9DF3F8C", fix=fix) # Blacklist exceptions be = filter(lambda x: x[0] == 'blacklist_exceptions', mconf) if not be: ff("Missing blacklist_exceptions section", "B8C8A19C") else: be = be[0][1] dat_block = None for _, device in be: bdict = {} for entry in device: bdict[entry[0]] = entry[1] if bdict['vendor'] == 'DATERA.*': dat_block = bdict if not dat_block: ff("No Datera blacklist_exceptions section found", "09E37E51", fix=fix) if dat_block['vendor'] != 'DATERA.*': ff("Datera blacklist_exceptions vendor entry malformed", "9990F32F", fix=fix) if dat_block['product'] != 'IBLOCK.*': ff("Datera blacklist_exceptions product entry malformed", "642753A0", fix=fix)
def check_glance_conf(config): pass section = None with io.open(ETC, 'r') as f: for line in f: default = ETC_DEFAULT_RE.match(line) if default: break if not default: ff("[DEFAULT] section missing from {}".format(ETC), "228241A8") for line in f: section = ETC_SECTION_RE.match(line) if section: break if not section: return ff("[glance_store] section missing from {}".format(ETC), "AFCBBDD7") dsection = [] section_match = re.compile(r"^\[.*\]") for line in f: if section_match.match(line): break dsection.append(line) ip = config['mgmt_ip'] user = config['username'] passwd = config['password'] san_check = False user_check = False pass_check = False stores_check = False default_check = False for line in dsection: if line.startswith("stores"): stores_check = True if "datera" not in line: ff("datera is not set under 'stores' in {}".format(ETC), "0D862946") if line.startswith("default_store"): default_check = True if "datera" not in line: wf("datera is not set as default_store in {}".format(ETC), "B74CEBC3") if line.startswith("datera_san_ip"): san_check = True if line.split("=")[-1].strip() != ip: ff("datera_san_ip doesn't match mgmt ip", "2330CACB") if line.startswith("datera_san_login"): user_check = True if line.split("=")[-1].strip() != user: ff("datera_san_login doesn't match username", "E9F02293") if line.startswith("datera_san_password"): pass_check = True if line.split("=")[-1].strip() != passwd: ff("datera_san_password doesn't match password", "4B16C4F7") if not stores_check: ff("'stores' entry not found under [glance_store]", "11F30DCF") if not default_check: ff("'default_store' entry not found under [glance_store]", "540C3008") if not san_check: ff("'datera_san_ip' entry not found under [glance_store]", "42481C71") if not user_check: ff("'datera_san_login' entry not found under [glance_store]", "6E281004") if not pass_check: ff("'datera_san_password' entry not found under [glance_store]", "F5DEC8B1")
def check_cinder_volume_conf(config): section = None with io.open(ETC, 'r') as f: for line in f: default = ETC_DEFAULT_RE.match(line) if default: break if not default: ff("[DEFAULT] section missing from /etc/cinder/cinder.conf", "7B98CFA1") for line in f: section = ETC_SECTION_RE.match(line) if section: break if line.startswith("enabled_backends"): if "datera" not in line: ff( "datera is not set under enabled_backends " "in /etc/cinder/cinder.conf", "A4402034") if line.startswith("default_volume_type"): if "datera" not in line: wf( "datera is not set as default_volume_type in" " /etc/cinder/cinder.conf", "C2B8C696") if not section: return ff( "[datera] section missing from " "/etc/cinder/cinder.conf", "525BAAB0") dsection = [] section_match = re.compile(r"^\[.*\]") for line in f: if section_match.match(line): break dsection.append(line) san_check = False user_check = False pass_check = False vbn_check = False debug_check = False defaults_check = False ip = config['mgmt_ip'] user = config['username'] passwd = config['password'] for line in dsection: if 'san_ip' in line and ip in line: san_check = True if 'san_login' in line and user in line: user_check = True if 'san_password' in line and passwd in line: pass_check = True if 'volume_backend_name' in line and 'datera' in line: vbn_check = True if 'datera_debug' in line and 'True' in line: debug_check = True if 'datera_volume_type_defaults' in line: defaults_check = True if not san_check: ff( "san_ip line is missing or not matching ip address:" " {}".format(ip), "8208B9E7") if not user_check: ff( "san_login line is missing or not matching username:"******" {}".format(user), "3A6A78D1") if not pass_check: ff( "san_password line is missing or not matching " "password: {}".format(passwd), "8DBC87E8") if not vbn_check: ff("volume_backend_name is not set", "5FEC0454") if not debug_check: wf("datera_debug is not enabled") if not defaults_check: wf( "datera_volume_type_defaults is not set, consider setting " "minimum QoS values here", "B5D29621")
def check_something(config): if not exe_check("ping -C 2 -W 1 1.1.1.1"): ff("This test failed") return if not exe_check("traceroute 1.1.1.1"): wf("This is a warning")
def callhome_check(config): api = config["api"] if not api.system.get()['callhome_enabled']: wf("Callhome is not enabled", "675E2887")