#!/usr/bin/python3
import sys
import os
try:
    from vmguestlib import VMGuestLib, VMGuestLibException
    from multiprocessing import cpu_count
    import xml.etree.ElementTree as ET
    import subprocess
    from socket import gethostname
    from syslog import openlog, syslog, LOG_ERR
    from optparse import OptionParser
except ImportError as e:
    if sys.stdout.isatty():
        print("Could not import all needed modules: %s\n" % str(e))
        print("Letting check pass.")
    sys.exit(0)

CHECKS_PASSED=0
CHECKS_FAILED=3

# RMX Alarms
NO_ALARM = 0;
MINOR_ALARM = 1;
MAJOR_ALARM = 2;

# Deployment constants
DEP_SINGLE_NODE_SRV=0
DEP_LOCAL_SEP_SRV=10
DEP_LOCAL_SEP_SRV_SG=11
DEP_SURV_SG=20
DEP_STANDALONE_SG=21
DEP_REDU_SG=30
DEP_APE=40
DEP_DSCXLV2_SIMPLEX=50
DEP_DSCXLV2_DUPLEX=60
DEP_DSCXLV2_DUPLEX_SG=61
DEP_DSCXLV2_LOCAL_SEP_DUPLEX=62
DEP_ECOAP=70
DEP_SURVIVABLE_ECOAP=71
DEP_DSCXLV2_DUPLEX_REPLACEMENT=99
DEP_UNDEFINED=100

# Required number of CPU cores for each VM deployment
CPUCoreRequirement = {
    "Quorum" : 2,
    "QuorumWithSoftGate" : 4,
    "SeparatedDuplex" : 4,
    "SimplexWithSoftGate" : 4,
    "Simplex" : 4,
    "Manager" : 0,
    "SurvivableUnit" : 4,
    "SurvivableSoftGateStandard" : 4,
    "SoftGateStandard" : 4,
}

# Required reserved CPU frequency for each VM deployment
# NOTE: Fixed only for Quorum.
# The other deployments should follow the formula: CPU_Cores x CPU_Frequency
CPUReservedRequirement = {
    "Quorum" : 500,
}

CPUReservedRequirement_preV8 = {
    "Quorum" : 500,
    "QuorumWithSoftGate" : 4000,
    "SeparatedDuplex" : 8000,
    "SimplexWithSoftGate" : 8000,
    "Simplex" : 8000,
    "Manager" : 0,
    "SurvivableUnit" : 8000,
    "SurvivableSoftGateStandard" : 8000,
}

# Required memory allocation for each VM deployment
MemoryRequirement = {
    "Quorum" : 2048,
    "QuorumWithSoftGate" : 4096,
    "SeparatedDuplex" : 6144,
    "SimplexWithSoftGate" : 8192,
    "Simplex" : 6144,
    "Manager" : 0,
    "SurvivableUnit" : 4096,
    "SurvivableSoftGateStandard" : 8192,
    "SoftGateStandard" : 4096,
}

# Required memory reservation for each VM deployment
ReservedMemoryRequirement = {
    "Quorum" : 1024,
    "QuorumWithSoftGate" : 4096,
    "SeparatedDuplex" : 4096,
    "SimplexWithSoftGate" : 8192,
    "Simplex" : 4096,
    "Manager" : 0,
    "SurvivableUnit" : 4096,
    "SurvivableSoftGateStandard" : 8192,
    "SoftGateStandard" : 4096,
}

# Print in colors for clearer display of results
def print_color(text, color):
    is_tty = sys.stdout.isatty()
    if is_tty:
        sys.stdout.write(color)
    sys.stdout.write(text)
    if is_tty:
        sys.stdout.write(print_color.RESET)
    sys.stdout.write("\n")

print_color.RED   = "\033[1;31m"
print_color.GREEN = "\033[0;32m"
print_color.RESET = "\033[0;0m"

def print_red(text):
    print_color(text, print_color.RED)

def print_green(text):
    print_color(text, print_color.GREEN)

def cmd(command):
    try:
        process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        stdout, stderr = process.communicate()
        return process.returncode, stdout
    except Exception as e:
        print("Error: Failed to execute command: %s" % command)
        print("Exception: %s" % str(e))
        return 127, ""

def send_hista(alarm, event, subevent, message):
    hostname = gethostname()
    is_host = cmd('/opt/webservice/scripts/is_running_with_a_central_CC_on_same_node.sh')[0] == 1
    identifier = ""
    if is_host:
        identifier = 'Host: '
    else:
        ltu = cmd('/opt/soco/native/os/linux/get_LTU.sh')[1].strip()
        slot = cmd('/opt/soco/native/os/linux/get_Slot.sh')[1].strip()
        if ltu:
            identifier = "LTU %s: " % ltu
        if slot:
            identifier += "Slot %s: " % slot

    message = "%s %s %s" % (identifier, hostname, message)

    if is_host:
        # Use direct HISTA message interface - via Atlantic LAN telnet interface.
        exit_code, output = cmd("/opt/dscxl/hcm-test/histamessage.py --alarm %s --event %s --subevent %s '%s'" % (alarm, event, subevent, message))
    else:
        # Use Inventory HISTA message interface - HISTA sent to Primary Node of Central Host.
        exit_code, output = cmd("/opt/inventory/inventory-client.sh notification HISTA_MESSAGE --alarm %s --event %s --subevent %s '%s'" % (alarm, event, subevent, message))

    if output.decode('UTF-8').find('HISTA message successfully sent') != -1:
        return True

    return False

def report_error(errorMessage, report=False, quiet=False, dont_report_hista=False):
    if not quiet:
        if sys.stdout.isatty():
            print_red("\nError: %s" % errorMessage)
        else:
            print("Error: %s" % errorMessage)

    if not report:
        return True

    # Report to syslog
    syslog(LOG_ERR, "Error: %s" % errorMessage)

    if dont_report_hista:
        return True
    # Report HISTA message via Inventory callback to Central Host RMX
    # event=0x2b and subevent=0x37 should result in MAINTENANCE message.
    return send_hista(NO_ALARM, 0x2b, 0x37, errorMessage)

def get_haipsetup_entry(name):
    if os.path.isfile('/var/opt/ha/conf/haipsetup.xml'):
        try:
            tree = ET.parse('/var/opt/ha/conf/haipsetup.xml')
            root = tree.getroot()
            for entry in root.findall("entry"):
                if entry.attrib['key'] == name:
                    return entry.text
        except ET.ParseError as e:
            print("Could not parse haipsetup.xml: %s" % str(e))
            return None
    else:
        return None

def deployment_name():
    """ Detect Platform deployment from system. Only returns VM relevant deployments. """
    ismanager = get_haipsetup_entry("system.isManager")
    if ismanager is None:
        ismanager = "0"
    ismanager = int(ismanager)
    if ismanager == 1:
        return "Manager"
    code = get_haipsetup_entry("system.multiNodeSystem")
    if code is None:
        return "Undefined"
    code = int(code)
    if code == DEP_LOCAL_SEP_SRV or code == DEP_DSCXLV2_LOCAL_SEP_DUPLEX:
          ret = cmd("/opt/webservice/scripts/is_quorum")[0]
          if ret == 1:
              ret = cmd("/opt/webservice/scripts/has_softgate")[0]
              if ret == 1:
                  return "QuorumWithSoftGate"
              else:
                  return "Quorum"
          return "SeparatedDuplex"
    elif code == DEP_SINGLE_NODE_SRV or code == DEP_DSCXLV2_SIMPLEX:
          ret = cmd("/opt/webservice/scripts/has_softgate")[0]
          if ret == 1:
              return "SimplexWithSoftGate"
          return "Simplex"
    elif code == DEP_SURV_SG:
          ret = cmd("/opt/webservice/scripts/has_softgate")[0]
          if ret == 0:
              return "SurvivableUnit"
          return "SurvivableSoftGateStandard"
    elif code == DEP_STANDALONE_SG:
          return "SoftGateStandard"
    else:
          return "Irrelevant"

def deployment_name_fi_deployment(fi_deployment):
    deployment_mapping = {
        "manager"             : "Manager",
        "simplex"             : "Simplex",
        "simplex_with_sg"     : "SimplexWithSoftGate",
        "quorum"              : "Quorum",
        "quorum_with_sg"      : "QuorumWithSoftGate",
        "separated_duplex"    : "SeparatedDuplex",
        "survivable"          : "SurvivableUnit",
        "survivable_softgate" : "SurvivableSoftGateStandard",
        "standalone_softgate" : "SoftGateStandard",
    }
    if fi_deployment in deployment_mapping:
        return deployment_mapping[fi_deployment]

    return "Irrelevant"

def platform_version():
    # This detects the version inside OS4k installer
    if os.path.isdir('/livecd/'):
        for File in reversed(sorted(os.listdir('/livecd/'))):
            if File.startswith('ver_'):
                return File[4:]

    # This is the interface for getting OS4k version on already installed system.
    return cmd("getydata -v")[1]

#def platform_major_release():
#    return platform_version().split('.')[0].split('_')[0].upper()

def GetTotalMemory():
    """ Returns the sum of virtual memory modules assigned to VM. """
    is_MB, is_GB = None, None
    try: 
        is_MB = int(cmd("dmidecode -t 17 | grep 'Size.*MB' | awk '{s+=$2} END {print s}'")[1])
    except ValueError: pass
    try: 
        is_GB = int(cmd("dmidecode -t 17 | grep 'Size.*GB' | awk '{s+=$2*2^10} END {print s}'")[1])
    except ValueError: pass

    if is_MB is not None:  return is_MB 
    if is_GB is not None:  return is_GB

def GetCPUCores():
    return cpu_count()

def VMGuestInstance():
    if VMGuestInstance.instance is None or VMGuestInstance.always_update:
        VMGuestInstance.instance = VMGuestLib()
        VMGuestInstance.instance.UpdateInfo()
    return VMGuestInstance.instance

VMGuestInstance.instance = None
VMGuestInstance.always_update = False

def AlwaysUpdateVMGuestInfo(value=True):
    VMGuestInstance.always_update = value

def GetReservedCPU():
    return VMGuestInstance().GetCpuReservationMHz()

def GetCPUShares():
    return VMGuestInstance().GetCpuShares()

def GetMemShares():
    return VMGuestInstance().GetMemShares()

def GetReservedMem():
    return VMGuestInstance().GetMemReservationMB()

def GetPhysicalCPUSpeed():
    return VMGuestInstance().GetHostProcessorSpeed()

def validate_CPUCores(Deployment, PlatformRelease, CPUCores, report=False, quiet=False):
    if Deployment in CPUCoreRequirement:
        if CPUCores < CPUCoreRequirement[Deployment]:
            report_error("VM has fewer CPU cores than required.\n"
                        " Has: %s cores  Required: %s" % (CPUCores, CPUCoreRequirement[Deployment]), report, quiet)
            return False
    return True

def validate_ReservedCPU(Deployment, PlatformRelease, ReservedCPU, PhysicalCPUFreq, CPUCores, CalledAutomatically, report=False, quiet=False):
    # Deployments with fixed CPU reservation requirement:
    if PlatformReleaseMajor < 8:
        # The requirements for V7R2 for CPU reservations were static.
        # SG requirements were based on the SG settings (channels and codec).
        # The Frequency Reservation requirement however followed the rule: Reserved = CPUCores x 2000 Mhz
        if Deployment in ["SoftGateStandard", "QuorumWithSoftGate"]:
            RequiredCPUReserved = CPUCores * 2000
            if ReservedCPU < RequiredCPUReserved:
                report_error("VM reserved CPU frequency lower than required.\n"
                            " Has: %s MHz Required: %s Mhz" % (ReservedCPU, RequiredCPUReserved), report, quiet)
                return False
            return True
        if Deployment in CPUReservedRequirement_preV8:
            if ReservedCPU < CPUReservedRequirement_preV8[Deployment]:
                report_error("VM reserved CPU frequency lower than required.\n"
                            " Has: %s MHz Required: %s Mhz" % (ReservedCPU, CPUReservedRequirement_preV8[Deployment]), report, quiet)
                return False
        return True
    else:
        if Deployment in CPUReservedRequirement:
            if ReservedCPU < CPUReservedRequirement[Deployment]:
                report_error("VM reserved CPU frequency lower than required.\n"
                            " Has: %s MHz Required: %s Mhz" % (ReservedCPU, CPUReservedRequirement[Deployment]), report, quiet)
                return False
            return True

    if Deployment in ["Manager"]:
        # print("Hint: Manager is an Application with no real-time requirements, hence no Reservations required")
        return True
        
    # V8 and later deployments: Check that Reserved CPU is following the formula: CPU_Cores x Physical_CPU_Frequency
    # Let check pass with 1% tolerance - to allow cases, when reservation in ESXi can't be set to exact Frequency of CPU.
    if ReservedCPU < (PhysicalCPUFreq * CPUCores * 0.99):
        # OSFOURK-7797 - adjust reporting to HISTA - only report to HISTA if ReservedCPU is under the V7 threshold (2000Mhz per core).
        v7_requirement_met = not (ReservedCPU < (CPUCores * 2000 * 0.99))
        if CalledAutomatically and v7_requirement_met:
            # Let check pass, but report error to syslog.
            syslog(LOG_ERR, "Error: VM reserved CPU frequency lower than required.\n"
                            " Has: %s MHz Required: %s MHz" % (ReservedCPU, PhysicalCPUFreq * CPUCores))
            return True
        report_error("VM reserved CPU frequency lower than required.\n"
                     " Has: %s MHz Required: %s MHz" % (ReservedCPU, PhysicalCPUFreq * CPUCores), report, quiet, dont_report_hista=v7_requirement_met)
        if not quiet:
            print("Hint: Recommended CPU reservation is the maximum setting possible for the number of vCPU.")
            print("      ReservedCPU = Number_of_vCPU_Cores * Physical_CPU_Speed")
        return False
    return True

def validate_CPUShares(Deployment, CPUCores, CPUShares, report=False, quiet=False):
    if Deployment in ["Manager"]:
        if CPUShares < 4000:
            report_error("VM CPU Shares are lower than required.\n"
                         ' Has: %s Required: %s ("Normal" setting)' % (CPUShares, 4000), report, quiet)
            return False
        return True
    if CPUShares/CPUCores < 2000:
        report_error("VM CPU Shares are lower than required.\n"
                     ' Has: %s Required: %s ("High" setting)' % (CPUShares, CPUCores * 2000), report, quiet)
        return False
    return True

def validate_Memory(Deployment, PlatformRelease, TotalMemory, CPUCores, report=False, quiet=False):
    # V7 Standalone SGs and Quorum SGs
    if PlatformReleaseMajor < 8:
        if Deployment in ["SoftGateStandard", "QuorumWithSoftGate"]:
            MemoryRequiredSG = CPUCores * 1024
            if TotalMemory < MemoryRequiredSG:
                report_error("VM Memory allocation is lower than required.\n"
                            " Has: %s MB Required: %s MB" % (TotalMemory, MemoryRequiredSG), report, quiet)
                if not quiet:
                    print("")
                    print("# Hint: Here's a table of the V7 requirements for SG and Quorum w/ SG:")
                    print("# +-------------------------+-----------------------+")
                    print("# | OpenScape 4000          |         Codecs        |")
                    print("# | V7 R2 SG Mem requirement|   G.711   |   G.729   |")
                    print("# +-------------------------+-----------+-----------+")
                    print("# |          |         SG50 |    2 GB   |    4 GB   |")
                    print("# |          |        SG500 |    4 GB   |    8 GB   |")
                    print("# |          |       SG1000 |    4 GB   |    8 GB   |")
                    print("# | SOCOTYPE |  Quorum+SG50 |    2 GB   |    4 GB   |")
                    print("# |(Channels)| Quorum+SG500 |    4 GB   |    8 GB   |")
                    print("# |          |Quorum+SG1000 |    4 GB   |    8 GB   |")
                    print("# +----------+--------------+-----------+-----------+")
                return False
            return True
        if Deployment in MemoryRequirement:
            if TotalMemory < MemoryRequirement[Deployment]:
                report_error("VM Memory allocation is lower than required.\n"
                            " Has: %s MB Required: %s MB" % (TotalMemory, MemoryRequirement[Deployment]), report, quiet)
                return False
        return True

    # V8 and later

    # Special case: Might be a Standalone SG upgraded from V7R2 SG50 - only had 2GB requirement.
    if Deployment in ["SoftGateStandard", "QuorumWithSoftGate"] and CPUCores == 2:
        SG50_MemoryRequirement = 2048
        if TotalMemory < SG50_MemoryRequirement:
            report_error("VM Memory allocation is lower than required.\n"
                        " Has: %s MB Required: %s MB" % (TotalMemory, SG50_MemoryRequirement), report, quiet)
            return False
        return True

    if Deployment in MemoryRequirement:
        if TotalMemory < MemoryRequirement[Deployment]:
            report_error("VM Memory allocation is lower than required.\n"
                        " Has: %s MB Required: %s MB" % (TotalMemory, MemoryRequirement[Deployment]), report, quiet)
            return False
    return True

def validate_MemoryReservation(Deployment, PlatformRelease, ReservedMem, CPUCores, report=False, quiet=False):
    if PlatformReleaseMajor < 8:
        if Deployment in ["SoftGateStandard", "QuorumWithSoftGate"]:
            ReservedMemoryRequiredSG = CPUCores * 1024
            if ReservedMem < ReservedMemoryRequiredSG:
                report_error("VM Memory reservation is lower than required.\n"
                            " Has: %s MB Required: %s MB" % (ReservedMem, ReservedMemoryRequiredSG), report, quiet)
                if not quiet:
                    print("")
                    print("# Hint: Here's a table of the V7 requirements for SG and Quorum w/ SG:")
                    print("# +-------------------------+-----------------------+")
                    print("# | OpenScape 4000          |         Codecs        |")
                    print("# | V7 R2 SG Mem requirement|   G.711   |   G.729   |")
                    print("# +-------------------------+-----------+-----------+")
                    print("# |          |         SG50 |    2 GB   |    4 GB   |")
                    print("# |          |        SG500 |    4 GB   |    8 GB   |")
                    print("# |          |       SG1000 |    4 GB   |    8 GB   |")
                    print("# | SOCOTYPE |  Quorum+SG50 |    2 GB   |    4 GB   |")
                    print("# |(Channels)| Quorum+SG500 |    4 GB   |    8 GB   |")
                    print("# |          |Quorum+SG1000 |    4 GB   |    8 GB   |")
                    print("# +----------+--------------+-----------+-----------+")
                return False
            return True
        if Deployment in ReservedMemoryRequirement:
            if ReservedMem < ReservedMemoryRequirement[Deployment]:
                report_error("VM Memory reservation is lower than required.\n"
                            " Has: %s MB Required: %s MB" % (ReservedMem, ReservedMemoryRequirement[Deployment]), report, quiet)
                return False
        return True

    # V8 and later

    if Deployment in ["SoftGateStandard", "QuorumWithSoftGate"]:
        ReservedMemoryRequiredSG = CPUCores * 1024
        if ReservedMem < ReservedMemoryRequiredSG:
            report_error("VM Memory reservation is lower than required.\n"
                        " Has: %s MB Required: %s MB" % (ReservedMem, ReservedMemoryRequiredSG), report, quiet)
            return False
        return True

    if Deployment in ReservedMemoryRequirement:
        if ReservedMem < ReservedMemoryRequirement[Deployment]:
            report_error("VM Memory reservation is lower than required.\n"
                        " Has: %s MB Required: %s MB" % (ReservedMem, ReservedMemoryRequirement[Deployment]), report, quiet)
            return False
    return True

def validate_MemoryShares(TotalMemory, MemShares, report=False, quiet=False):
    if TotalMemory <= 0 or MemShares/TotalMemory < 10:
        report_error("VM Memory shares are lower than required.\n"
                     ' Has: %s Required: %s ("Normal" setting)' % (MemShares, TotalMemory * 10), report, quiet)
        return False
    return True

def validate_all(Deployment, PlatformRelease, CPUCores, PhysicalCPUFreq,
                 ReservedCPU, CPUShares, TotalMemory,
                 ReservedMem, MemShares, CalledAutomatically, report=False, quiet=False):
    """ Perform all available checks, return True if all passed """
    cores_valid = validate_CPUCores(Deployment, PlatformRelease, CPUCores, report, quiet)
    cpu_reserved_valid = validate_ReservedCPU(Deployment, PlatformRelease, ReservedCPU, PhysicalCPUFreq, CPUCores, CalledAutomatically, report, quiet)
    cpu_shares_valid = validate_CPUShares(Deployment, CPUCores, CPUShares, report, quiet)
    memory_valid = validate_Memory(Deployment, PlatformRelease, TotalMemory, CPUCores, report, quiet)
    mem_reservation_valid = validate_MemoryReservation(Deployment, PlatformRelease, ReservedMem, CPUCores, report, quiet)
    mem_shares_valid = validate_MemoryShares(TotalMemory, MemShares, report, quiet)

    if (cores_valid and cpu_reserved_valid and
        cpu_shares_valid and memory_valid and
        mem_reservation_valid and mem_shares_valid):
        return True

    if not quiet:
        print("")
        print("--------------------------------------------------")
        print("Recommended actions:")
        if not cores_valid:
            print("Increase Number of Cores:")
            print("  To change number of vCPU cores, the VM needs to be Powered-Off.")
            print("  Once VM is powered-off you can go to VM Settings > Hardware > CPUs.")
            print("  Increase number of virtual sockets to the Required value of CPU cores.")
            print("")
        if not memory_valid:
            print("Increase Memory size:")
            print("  To change size of Total Memory, the VM needs to be Powered-Off.")
            print("  Once VM is powered-off you can go to VM Settings > Hardware > Memory.")
            print("  Increase memory size to the Required value.")
            print("")
        if not cpu_reserved_valid:
            print("Increase CPU reservation:")
            print("  CPU Reservation can be changed on-the-fly.")
            print("  You can go right now to VM Settings > Resources > CPU.")
            print("  Increase \"Reservation\" to the Required value.")
            print("  Set it to maximum value possible,")
            print("  in case ESXi does not allow to set this exactly to the Required value.")
            print("")
        if not cpu_shares_valid:
            print("Increase CPU shares:")
            print("  CPU Shares can be changed on-the-fly.")
            print("  You can go right now to VM Settings > Resources > CPU.")
            print("  Increase Shares to the Required value.")
            print("")
        if not mem_reservation_valid:
            print("Increase Memory Reservation:")
            print("  Memory reservation can be changed on-the-fly.")
            print("  You can go right now to VM Settings > Resources > Memory.")
            print("  Increase Reservation to the Required value.")
            print("")
        if not mem_shares_valid:
            print("Increase Memory Shares:")
            print("  Memory shares can be changed on-the-fly.")
            print("  You can go right now to VM Settings > Resources > Memory.")
            print("  Increase Shares to the Required value.")
            print("")

    return False

def vmware_detected():
    exit_code, output = cmd('vmxcap -i')
    if exit_code != 0:
        return False
#    if output.find('vmware_esx') == -1:
#        return False
    return True

def GUIMemShareLevel(MemShares, TotalMemory):
    """ Approximate the Memory Shares setting in VMWare GUI. """
    if MemShares/TotalMemory == 20:
        return "High"
    if MemShares/TotalMemory == 10:
        return "Normal"
    if MemShares/TotalMemory == 5:
        return "Low"
    return "Custom"

def GUICpuSharesLevel(CPUShares, CPUCores):
    """ Approximate the CPU Shares setting in VMWare GUI """
    if CPUShares/CPUCores == 2000:
        return "High"
    if CPUShares/CPUCores == 1000:
        return "Normal"
    if CPUShares/CPUCores == 500:
        return "Low"
    return "Custom"

def CheckVMResources(report=False, quiet=True, release=None):
    """
    Returns True if the VM resources match requirements.
    Also returns True if not a VM or if this check is otherwise not relevant.
    Returns False if the checks did not pass.
    """
    if not vmware_detected():
        return True

    Deployment = deployment_name()
    if Deployment == "Irrelevant":
        return True

    CPUCores = GetCPUCores()

    try:
        ReservedCPU = GetReservedCPU()
        CPUShares = GetCPUShares()
        MemShares = GetMemShares()
        ReservedMem = GetReservedMem()
    except VMGuestLibException as e:
        return True

    PhysicalCPUFreq = GetPhysicalCPUSpeed()
    TotalMemory = GetTotalMemory()

    if release is not None:
        PlatformRelease = release[:2].upper()
    else:
        PlatformRelease = "V10" #platform_major_release()
        PlatformReleaseMajor = int(PlatformRelease.strip('V')) #OSFOURK-16344 check_vmguest tolerance is not working in V10. Make the check against Major version integer

    if PhysicalCPUFreq == "" or TotalMemory == "":
        return True

    if validate_all(Deployment, PlatformRelease, CPUCores, PhysicalCPUFreq,
                    ReservedCPU, CPUShares, TotalMemory,
                    ReservedMem, MemShares, CalledAutomatically, report, quiet):
        return True

    return False

if __name__ == "__main__":
    parser = OptionParser()
    parser.add_option("-r", "--report", dest="report",
                            action="store_true", default=False,
                            help="Report errors to syslog and to HISTA (to Central Host)")
    parser.add_option("-q", "--quiet",
                            action="store_true", dest="quiet", default=False,
                            help="Don't print any output to stdout.")
    parser.add_option("-v", "--version",
                            action="store", dest="release", default=None,
                            help="Override detection of Platform major version release with this parameter.")
    parser.add_option("-d", "--deployment",
                            action="store", dest="deployment", default=None,
                            help="Override detection of Platform deployment with this parameter.")

    (options, args) = parser.parse_args()

    if __file__ == "/etc/cron.hourly/check_vmguest":
        # If executed from cron, there will be no output, only HISTA error report
        report, quiet = True, True
    else:
        report, quiet = options.report, options.quiet

    """if __file__ == "/opt/soco-common/check_vmguest":
        # If executed from swupdated or from SG - this is detected if the script is called with full path.
        # The check behaviour is a little different than when it is called manually via "check_vmguest" (symlink /usr/local/bin/check_vmguest).
        CalledAutomatically = True
    else:
        CalledAutomatically = False
    """
    #OSFOURK-21734 check_vmguest returns a different result depending on how it is called ; disabled code from OSFOURK-7797
    CalledAutomatically = False
    if not sys.stdout.isatty() and os.path.isfile('/disable_check_vmguest'):
        sys.exit(0)

    if not vmware_detected():
        if not quiet: print("Not a VMWare Virtual Machine - checks not possible.")
        sys.exit(0)

    if options.deployment is not None:
        Deployment = deployment_name_fi_deployment(options.deployment)
    else:
        Deployment = deployment_name()

    if Deployment == "Irrelevant":
        if not quiet: print("These checks are not relevant for this deployment.")
        sys.exit(0)
    if Deployment == "Undefined":
        if not quiet: print("The deployment is not defined. Letting check pass.")
        sys.exit(0)

    if options.release is not None:
        PlatformRelease = options.release[:2].upper()
    else:
        PlatformRelease = "V10" #platform_major_release()
        PlatformReleaseMajor = int(PlatformRelease.strip('V'))  #OSFOURK-16344 check_vmguest tolerance is not working in V10. Make the check against Major version integer

    CPUCores = GetCPUCores()

    try:
        ReservedCPU = GetReservedCPU()
        CPUShares = GetCPUShares()
        MemShares = GetMemShares()
        ReservedMem = GetReservedMem()
        PhysicalCPUFreq = GetPhysicalCPUSpeed()
    except VMGuestLibException as e:
        if not quiet: print("Could not load VM parameters using VMWare Tools API.")
        sys.exit(0)

    TotalMemory = GetTotalMemory()

    if PhysicalCPUFreq == "" or TotalMemory == "":
        sys.exit(0)

    CPUSharesLevel = GUICpuSharesLevel(CPUShares, CPUCores)
    MemSharesLevel = GUIMemShareLevel(MemShares, TotalMemory)

    if not quiet:
        print("Current VM resources:")
        print("   Platform Release:", PlatformRelease)
        print("      VM Deployment:", Deployment)
        print("Number of CPU Cores:", CPUCores)
        print("  Physical CPU freq:", PhysicalCPUFreq, "MHz")
        print("       Reserved cpu:", ReservedCPU, "MHz")
        print("         CPU Shares:", CPUShares, "(", CPUSharesLevel, ")")
        print("       Total Memory:", TotalMemory, "MB")
        print("    Memory Reserved:", ReservedMem, "MB")
        print("      Memory shares:", MemShares, "(", MemSharesLevel, ")")
        print("")

    openlog("check_vmguest")

    all_valid = validate_all(Deployment, PlatformRelease, CPUCores, PhysicalCPUFreq,
                             ReservedCPU, CPUShares, TotalMemory,
                             ReservedMem, MemShares, CalledAutomatically, report, quiet)

    if not quiet: print("\nCheck result: ", end=' ')

    if all_valid:
        if not quiet: print_green('PASSED')
        sys.exit(CHECKS_PASSED)
    else:
        if not quiet: print_red('FAILED')
        sys.exit(CHECKS_FAILED)

