Ejemplo n.º 1
0
    def _set_sys_env_props(
        cls, session, properties: dict, s_attr_prop: list, env_prop_type: SysEnvProperty
    ):
        """Update system environment properties"""

        s_attr_rand_prop = ["start", "end"]

        if "event" in properties and properties["event"]:
            event = properties["event"]
        else:
            event = None

        query = []

        query.append("MERGE (sys:SystemEnvironment { sref: 1 })")
        query.append(
            'MERGE (sys)-[:HAS_PROP]->(env_prop:EnvProp {{ name: "{}" }})'.format(
                env_prop_type.name
            )
        )

        if event:
            query.append(
                'MERGE (env_prop)-[:HAS_PROP]->(event:EnvProp {{ event: "{}" }})'.format(
                    event
                )
            )

        set_stm = []

        if event:
            set_stm.append(
                qh.get_set_stm(
                    properties, node_name="env_prop", supported_attr=s_attr_rand_prop
                )
            )
            set_stm.append(qh.get_set_stm(properties, "event", s_attr_prop))
        else:
            set_stm.append(
                qh.get_set_stm(
                    properties,
                    node_name="env_prop",
                    supported_attr=s_attr_rand_prop + s_attr_prop,
                )
            )

        query.extend(map(lambda x: "SET {}".format(x) if x else "", set_stm))

        return session.run("\n".join(query))
Ejemplo n.º 2
0
    def set_controller_prop(cls, session, server_key, controller, properties):
        """Update controller state
        Args:
            session:  database session
            server_key(int): key of the server controller belongs to
            controller(int): controller number
            properties(dict): settable controller props e.g. 'mem_c_errors', 'mem_uc_errors', 'alarm'
        Returns:
            bool: True if properties were updated, False if controller number is invalid
        """
        query = []

        s_attr = ["mem_c_errors", "mem_uc_errors", "alarm"]

        # query as (server)->(storage_controller)
        query.append("MATCH (server:Asset {{ key: {} }})".format(server_key))
        query.append(
            "MATCH (server)-[:HAS_CONTROLLER]->(ctrl:Controller {{ controllerNum: {} }})"
            .format(controller))

        set_stm = qh.get_set_stm(properties,
                                 node_name="ctrl",
                                 supported_attr=s_attr)
        query.append("SET {}".format(set_stm))
        query.append("RETURN ctrl")

        result = session.run("\n".join(query)).single()

        return (result and result.get("ctrl")) is not None
Ejemplo n.º 3
0
    def set_cv_replacement(cls, session, server_key, controller, repl_status,
                           wt_on_fail):  # TODO: cachevault serial NUMBER!
        """Update cachevault replacement status
        Args:
            session:  database session
            server_key(int): key of the server cachevault belongs to
            controller(int): controller num
        Returns:
            bool: True if properties were updated, False if controller number is invalid
        """

        query = []
        query.extend([
            "MATCH (:Asset {{ key: {} }})-[:HAS_CONTROLLER]->(ctrl:Controller {{ controllerNum: {} }})"
            .format(server_key, controller),
            "MATCH (ctrl)-[:HAS_CACHEVAULT]->(cv:CacheVault)",
        ])

        set_stm = qh.get_set_stm(
            {
                "replacement": repl_status,
                "writeThrough": wt_on_fail
            },
            node_name="cv",
            supported_attr=["replacement", "writeThrough"],
        )

        query.append("SET {}".format(set_stm))
        query.append("RETURN ctrl, cv")

        result = session.run("\n".join(query)).single()
        return (result and result.get("ctrl") and result.get("cv")) is not None
Ejemplo n.º 4
0
    def set_physical_drive_prop(cls, session, server_key, controller, did,
                                properties):
        """Update physical drive properties (such as error counts or state)
        Args:
            session:  database session
            server_key(int): key of the server physical drive belongs to
            controller(int): controller number
            did(int): drive id
            properties(dict): e.g. 'media_error_count', 'other_error_count'
                                   'predictive_error_count' or 'state'
        Returns:
            bool: True if properties were updated,
                  False if controller and/or did are invalid
        """
        query = []

        s_attr = [
            "media_error_count",
            "other_error_count",
            "predictive_error_count",
            "State",
            "time_stamp",
            "rebuild_time",
        ]

        properties[
            "State"] = properties["state"] if "state" in properties else None

        # query as (server)->(storage_controller)->(physical drive)
        query.append("MATCH (server:Asset {{ key: {} }})".format(server_key))
        query.append(
            "MATCH (server)-[:HAS_CONTROLLER]->(ctrl:Controller {{ controllerNum: {} }})"
            .format(controller))
        query.append(
            "MATCH (ctrl)-[:HAS_PHYSICAL_DRIVE]->(pd:PhysicalDrive {{ DID: {} }})"
            .format(did))

        # record uptime so that the rebuilding process gets simulated
        if properties["State"] and properties["State"] == "Onln":
            properties["time_stamp"] = time.time()

        set_stm = qh.get_set_stm(properties,
                                 node_name="pd",
                                 supported_attr=s_attr)
        query.append("SET {}".format(set_stm))
        query.append("RETURN ctrl, pd")

        result = session.run("\n".join(query)).single()

        return (result and result.get("ctrl") and result.get("pd")) is not None
Ejemplo n.º 5
0
def set_thermal_cpu_target(attr):
    """Set-up a new thermal relationship between a sensor and CPU load 
    of the server sensor belongs to

    Returns:
        bool: True if a new relationship was created
    """

    try:
        _ = json.loads(attr["model"])
    except ValueError as error:
        raise ValueError("Model .json is not valid: {}".format(error))

    query = []

    # find the source sensor & server asset
    query.append(
        "MATCH (cpu:CPU)<-[:HAS_CPU]-(server:Asset {{ key: {} }})".format(
            attr["asset_key"]
        )
    )

    # find the destination or target sensor
    query.append(
        'MATCH (target {{ name: "{}" }} )<-[:HAS_SENSOR]-(server)'.format(
            attr["target_sensor"]
        )
    )

    # set the thermal relationship & relationship attributes
    set_stm = qh.get_set_stm(attr, node_name="rel", supported_attr=["model"])

    query.append("MERGE (cpu)<-[rel:HEATED_BY]-(target)")
    query.append("SET {}".format(set_stm))

    rel_query = []
    rel_query.append("MATCH (cpu)<-[ex_rel:HEATED_BY]-(target)")
    rel_query.append("RETURN ex_rel")

    with GRAPH_REF.get_session() as session:
        result = session.run("\n".join(query[0:2] + rel_query))
        rel_exists = result.single()

        session.run("\n".join(query))
        return rel_exists is None
Ejemplo n.º 6
0
def configure_asset(key, attr):
    """Update existing properties

    Args:
        key(int): key of the asset to be configured
        attr(dict): asset props' updates
    """

    if "asset_key" in attr and attr["asset_key"]:
        del attr["asset_key"]

    with GRAPH_REF.get_session() as session:

        set_statement = qh.get_set_stm(attr)
        query = "MATCH (asset:Asset {{ key: {key} }}) SET {set_stm}".format(
            key=key, set_stm=set_statement)

        session.run(query)
Ejemplo n.º 7
0
def _set_thermal_target(attr, query):
    """Set thermal relationship between 2 ndoes
    Args:
        attr(dict): relationship properties (such as rate, event, degrees etc. )
        query(list): query that includes look up of the 'target' & 'source' nodes
    Returns:
        bool: True if the relationship is new
    """

    # determine relationship type
    thermal_rel_type = ""
    if attr["action"] == "increase":
        thermal_rel_type = "HEATED_BY"
    elif attr["action"] == "decrease":
        thermal_rel_type = "COOLED_BY"
    else:
        raise KeyError("Unrecognized event type: {}".format(attr["event"]))

    # fist check if the relationship already exists
    rel_query = []
    rel_query.append(
        "MATCH (source)<-[ex_rel:{}]-(target)".format(thermal_rel_type))
    rel_query.append("RETURN ex_rel")

    with GRAPH_REF.get_session() as session:

        result = session.run("\n".join(query + rel_query))
        rel_exists = result.single()

        # set the thermal relationship & relationship attributes
        s_attr = [
            "pause_at", "rate", "event", "degrees", "jitter", "action", "model"
        ]
        set_stm = qh.get_set_stm(attr, node_name="rel", supported_attr=s_attr)

        query.append(
            "MERGE (source)<-[rel:{}]-(target)".format(thermal_rel_type))
        query.append("SET {}".format(set_stm))

        session.run("\n".join(query))
        return rel_exists is None
Ejemplo n.º 8
0
 def test_set_stm_filter(self):
     """Test if supported attr filters out attr"""
     attr = {"a": 1, "b": 2, "c": 3, "d": 4}
     s_attr = ["a", "b", "c"]
     formatted_stm = qh.get_set_stm(attr, node_name="test", supported_attr=s_attr)
     self.assertEqual("test.a=1,test.b=2,test.c=3", formatted_stm)
Ejemplo n.º 9
0
 def test_set_stm(self):
     """Test statement formatter used for updating node attributes"""
     attr = {"a": 1, "b": 2, "c": 3}
     formatted_stm = qh.get_set_stm(attr, node_name="test")
     self.assertEqual("test.a=1,test.b=2,test.c=3", formatted_stm)
Ejemplo n.º 10
0
def create_server(key, attr, server_variation=ServerVariations.Server):
    """Create a simulated server """

    if not attr["power_consumption"]:
        raise KeyError("Server asset requires power_consumption attribute")
    if not attr["domain_name"]:
        raise KeyError("Must provide VM name (domain name)")

    # Validate server domain name
    try:
        conn = libvirt.open("qemu:///system")
        conn.lookupByName(attr["domain_name"])
    except libvirt.libvirtError:
        raise KeyError("VM does not exist")
    finally:
        conn.close()

    with GRAPH_REF.get_session() as session:

        query = []  # cypher query

        attr["name"] = (attr["name"] if "name" in attr and attr["name"] else
                        attr["domain_name"])
        attr["type"] = server_variation.name.lower()
        attr["key"] = key

        s_attr = [
            "domain_name",
            "power_consumption",
            "power_source",
        ] + CREATE_SHARED_ATTR
        props_stm = qh.get_props_stm(attr, supported_attr=s_attr)

        # create a server
        query.append("CREATE (server:Asset  {{ {} }}) SET server :{}".format(
            props_stm, server_variation.name))
        query.append("CREATE (server)-[:HAS_CPU]->(:CPU)")

        # set BMC-server specific attributes if type is bmc
        if server_variation == ServerVariations.ServerWithBMC:

            bmc_attr = {**IPMI_LAN_DEFAULTS, **attr}  # merge

            set_stm = qh.get_set_stm(bmc_attr,
                                     node_name="server",
                                     supported_attr=IPMI_LAN_DEFAULTS.keys())
            query.append("SET {}".format(set_stm))

        session.run("\n".join(query))

        if server_variation == ServerVariations.ServerWithBMC:

            # if preset is provided -> use the user-defined file
            f_loc = os.path.dirname(__file__)
            s_def_file = (lambda p, j: os.path.expanduser(attr[p])
                          if p in attr and attr[p] else os.path.join(
                              f_loc, "presets/" + j))

            sensor_file = s_def_file("sensor_def", "sensors.json")
            storage_def_file = s_def_file("storage_def", "storage.json")
            storage_state_file = s_def_file("storage_states",
                                            "storage_states.json")

            _add_sensors(key, sensor_file)
            _add_storage(key, storage_def_file, storage_state_file)

        if server_variation == ServerVariations.ServerWithBMC:
            with open(sensor_file) as preset_handler, GRAPH_REF.get_session(
            ) as session:
                data = json.load(preset_handler)
                for psu in data["psu"]:
                    _add_psu(key, psu_index=psu["id"], attr=psu)

        else:
            # add PSUs to the model
            for i in range(attr["psu_num"]):
                psu_attr = {
                    "power_consumption": attr["psu_power_consumption"],
                    "power_source": attr["psu_power_source"],
                    "variation": server_variation.name.lower(),
                    "draw": attr["psu_load"][i] if attr["psu_load"] else 1,
                    "id": i,
                }
                _add_psu(key, psu_index=i + 1, attr=psu_attr)