def process(self, device, results, log):
        # call self.relMap() helper method that initializes relname and compname for me
        # 
        rm = self.relMap()
        lines = results.split('\n')
        if lines[0] != "yes":
            # we are not in a container or on a host
            return []   
        pos = 1
        try:
            page_size = int(lines[pos])
        except ValueError:
            page_size = 4096
        pos += 1
        arch = lines[pos]
        pos += 1
        hw_map = ObjectMap({"page_size" : page_size, "arch" : arch }, compname="hw")
        infolines = []
        while lines[pos] != "#veinfo-stop":
                infolines.append(lines[pos])
                pos += 1
        vzinfo = VZInfoParser.parse(infolines)
        # if we find VE 0, we are on a host...
        foundZero = False
        # blank line:
        pos += 2
        while pos < len(lines):
            # helper method - will set compname, modname, and classname for me:
            # it gets these settings from relname, modname, and classname = modname
            om = self.objectMap() 
            if lines[pos] == "0":
                foundZero = True
                om.title = "CT0"
                om.id = "0"
                om.description = "Hardware Node"
                om.onboot = False
                om.ve_root = "N/A"
                om.ve_private = "N/A"
                om.container_status = "running"
                om.ostemplate = "N/A"
                om.ipaddrs=[]
                om.macaddrs=[]
            else:    
                om.id = self.prepId(lines[pos])
                # NAME
                if lines[pos+1]:
                    om.title = lines[pos+1]
                om.hostname = lines[pos+2]
                om.ostemplate = lines[pos+3]
                # veth macaddr info on lines[pos+5]
                om.description = lines[pos+6]
                om.ve_root = lines[pos+7]
                om.ve_private = lines[pos+8]
                om.onboot = False
                if lines[pos] in vzinfo:
                    om.container_status = vzinfo[lines[pos]]
                    if om.container_status == "running":
                        om.ipaddrs = []
                        # only update IPs if running so the IPs stick around if the container is stopped during remodel,
                        # so we still have IPs for container component <-> managed device correlation :)
                        for ip in lines[pos+4].split():
                            om.ipaddrs.append(ip)
                        # again, only update MAC addresses from veth when we are in a running state, so we cache old
                        # ones for correlation if a container happens to be stopped...
                        om.macaddrs = []
                        for netif in lines[pos+5].split(";"):
                            keypairs = netif.split(",")
                            for kp in keypairs:
                                kv = kp.split("=")
                                if len(kv) != 2:
                                    continue
                                if kv[0] == "mac":
                                    om.macaddrs.append(kv[1].lower())
                if lines[pos+9] == "yes":
                    om.onboot = True
            pos += 11 
            rm.append(om)
        if not foundZero:
            return []
    # a relMap() is just a container to store objectMaps
    # in relmap and objectmap, there is a compname and modname
    # any 
    #
    #
    # objectmaps and relmaps are temporary objects that the modeler plugin sends to zenhub, which then determines
    # if the model needs to be updated. 
    # device/containers/106
    # om ^    relmap ^   om^
    # we are allowd to return:
        # a relmap - will be filled with object maps that are related to "device"
        # an objectmap - 
        # a list of relmaps, objectmaps

        # If we get here, we've identified this as an OpenVZ host. Create a new
        # ObjectMap that will be applied to the device. Use it to call our
        # setOpenVZHostTemplate method on the device to bind the host-level
        # monitoring template.
        device_map = ObjectMap()
        device_map.setOpenVZHostTemplate = True

        return [device_map, hw_map, rm]
Beispiel #2
0
    def processResults(self, cmd, result):

        # We have defined an openvz datasource for our container. It has a
        # datapoint called "container_status" that really isn't used for
        # recording RRD data. But having this datapoint allows us to create a
        # data pipeline for throwing events related to container status
        # changes. We just don't write any RRD data into the point at the very
        # end.

        for p in cmd.points:
            if p.id == "container_status":

                # grab container status info we provided in dataForParser():

                existing_veids = p.data
                break
        else:
            return

        lines = cmd.result.output.split('\n')
        current_veids = VZInfoParser.parse(lines)
        event_count = 0
        for veid in current_veids:
            if veid == "0":
                # do not generate any events for VEID 0
                continue
            if veid not in existing_veids:
                event_count += 1

                # We are not explicitly setting an event class here, so it will default to
                # /Unknown. This means that the event will not be immutably locked into an
                # event class and we can then use a mapping to control everything about it.
                # This allows us to place it in the event class that we want and and attach
                # a transform to this specific type of event, based on eventClassKey. The
                # transform allows us to execute python code to perform actions based on
                # information in the event.

                # We create event mappings in the UI, by selecting the Event and clicking on
                # the little "tree" icon, or this can be done without selecting an Event by
                # going to "Event Classes" , "Status" (for example), and at bottom of screen
                # "Event Class Mappings", you can add one here. Make sure "eventClassKey"
                # matches the "eventClassKey" set below in the code. This will place that
                # event into the /Status event class.

                # Also make sure to add the Event Mapping to the ZenPack by selecting its
                # link and going to "Add to ZenPack".

                # We can map Events based on eventClassKey. Then, there is a rule and regex
                # that can be used to make our event mapping even more specific.

                # The "rule" is a python expression. True = match; False = no match
                # The "regex" will be matched against the event's message field, which is
                # usually a copy of "summary" that hasn't been truncated. Match = match.

                # The "transform" is literal python code.
                # globals in the context of the code that executes in "transform" are:
                #
                # evt (Event Object)
                # device & dev (Device Object - may be None)
                # txnCommit (method to commit changes to the model)
                # log (logger that will output into zeneventd.log)
                # dmd (DataRoot Object)
                # component (Component Object - may be None)
                # getFacade (method to gain access to API facades)
                # IInfo (Info adapter interface - for convenience)
                #
                # Example code:
                #
                # if component:
                #     # modify properties of the object directly...
                #     component.container_status = evt.new_status
                #     txnCommit()
                #
                # This will update the status of the component with which the event is
                # associated, and commit the new status information to the model.
                #
                # In this code, we are making direct changes to the model, which give us
                # the ability to update the model direct without using DeviceProxy().
                #
                # To test: zensendevent -d 10.0.1.2 -p 106 -s Info -k openvz_container_status_change -o "new_status=weird" "container status change"
                #
                # An overview of event severity:
                #
                # 0 = clear (green) - can clear existing events -
                # a clear will happen if the following match in the method: fingerprint device|component|eventClass|eventKey
                #                                                                             (optional)           (optional)
                # 1 = debug (grey)
                # 2 = info (blue)
                # 3 = warning (yellow)
                # 4 = error (orange)
                # 5 = critical (red)

                result.events.append(
                    dict(summary="OpenVZ container created",
                         severity="2",
                         eventClassKey="openvz_container_created",
                         component=veid,
                         old_status=None,
                         new_status=current_veids[veid]))
            elif existing_veids[veid] != current_veids[veid]:
                event_count += 1
                if current_veids[veid] == "running":
                    summary = "OpenVZ container started"
                else:
                    summary = "OpenVZ container " + current_veids[veid]
                result.events.append(
                    dict(
                        # limited to 128 characters:
                        summary=summary,
                        severity="2",
                        eventClassKey="openvz_container_status_change",
                        component=veid,
                        old_status=existing_veids[veid],
                        new_status=current_veids[veid]))
        e_set = set(existing_veids.keys())
        e_set.discard("0")
        c_set = set(current_veids.keys())
        c_set.discard("0")

        for veid in e_set - c_set:
            # in existing set, not in current - VEID disappeared
            event_count += 1
            result.events.append(
                dict(summary="OpenVZ container destroyed",
                     severity="2",
                     eventClassKey="openvz_container_destroyed",
                     component=veid,
                     old_status=existing_veids[veid],
                     new_status="destroyed"))
Beispiel #3
0
    def processResults(self, cmd, result):

        # We have defined an openvz datasource for our container. It has a
        # datapoint called "container_status" that really isn't used for
        # recording RRD data. But having this datapoint allows us to create a
        # data pipeline for throwing events related to container status
        # changes. We just don't write any RRD data into the point at the very
        # end.

        for p in cmd.points:
            if p.id == "container_status":

                # grab container status info we provided in dataForParser():

                existing_veids = p.data
                break
        else:
            return

        lines = cmd.result.output.split("\n")
        current_veids = VZInfoParser.parse(lines)
        event_count = 0
        for veid in current_veids:
            if veid == "0":
                # do not generate any events for VEID 0
                continue
            if veid not in existing_veids:
                event_count += 1

                # We are not explicitly setting an event class here, so it will default to
                # /Unknown. This means that the event will not be immutably locked into an
                # event class and we can then use a mapping to control everything about it.
                # This allows us to place it in the event class that we want and and attach
                # a transform to this specific type of event, based on eventClassKey. The
                # transform allows us to execute python code to perform actions based on
                # information in the event.

                # We create event mappings in the UI, by selecting the Event and clicking on
                # the little "tree" icon, or this can be done without selecting an Event by
                # going to "Event Classes" , "Status" (for example), and at bottom of screen
                # "Event Class Mappings", you can add one here. Make sure "eventClassKey"
                # matches the "eventClassKey" set below in the code. This will place that
                # event into the /Status event class.

                # Also make sure to add the Event Mapping to the ZenPack by selecting its
                # link and going to "Add to ZenPack".

                # We can map Events based on eventClassKey. Then, there is a rule and regex
                # that can be used to make our event mapping even more specific.

                # The "rule" is a python expression. True = match; False = no match
                # The "regex" will be matched against the event's message field, which is
                # usually a copy of "summary" that hasn't been truncated. Match = match.

                # The "transform" is literal python code.
                # globals in the context of the code that executes in "transform" are:
                #
                # evt (Event Object)
                # device & dev (Device Object - may be None)
                # txnCommit (method to commit changes to the model)
                # log (logger that will output into zeneventd.log)
                # dmd (DataRoot Object)
                # component (Component Object - may be None)
                # getFacade (method to gain access to API facades)
                # IInfo (Info adapter interface - for convenience)
                #
                # Example code:
                #
                # if component:
                #     # modify properties of the object directly...
                #     component.container_status = evt.new_status
                #     txnCommit()
                #
                # This will update the status of the component with which the event is
                # associated, and commit the new status information to the model.
                #
                # In this code, we are making direct changes to the model, which give us
                # the ability to update the model direct without using DeviceProxy().
                #
                # To test: zensendevent -d 10.0.1.2 -p 106 -s Info -k openvz_container_status_change -o "new_status=weird" "container status change"
                #
                # An overview of event severity:
                #
                # 0 = clear (green) - can clear existing events -
                # a clear will happen if the following match in the method: fingerprint device|component|eventClass|eventKey
                #                                                                             (optional)           (optional)
                # 1 = debug (grey)
                # 2 = info (blue)
                # 3 = warning (yellow)
                # 4 = error (orange)
                # 5 = critical (red)

                result.events.append(
                    dict(
                        summary="OpenVZ container created",
                        severity="2",
                        eventClassKey="openvz_container_created",
                        component=veid,
                        old_status=None,
                        new_status=current_veids[veid],
                    )
                )
            elif existing_veids[veid] != current_veids[veid]:
                event_count += 1
                if current_veids[veid] == "running":
                    summary = "OpenVZ container started"
                else:
                    summary = "OpenVZ container " + current_veids[veid]
                result.events.append(
                    dict(
                        # limited to 128 characters:
                        summary=summary,
                        severity="2",
                        eventClassKey="openvz_container_status_change",
                        component=veid,
                        old_status=existing_veids[veid],
                        new_status=current_veids[veid],
                    )
                )
        e_set = set(existing_veids.keys())
        e_set.discard("0")
        c_set = set(current_veids.keys())
        c_set.discard("0")

        for veid in e_set - c_set:
            # in existing set, not in current - VEID disappeared
            event_count += 1
            result.events.append(
                dict(
                    summary="OpenVZ container destroyed",
                    severity="2",
                    eventClassKey="openvz_container_destroyed",
                    component=veid,
                    old_status=existing_veids[veid],
                    new_status="destroyed",
                )
            )