1e7e9171eSGeorge Keishing#!/usr/bin/env python3
2*f0b9122aSShaheena Begum Mohammedr"""
3*f0b9122aSShaheena Begum MohammedThis is an extended user library to support Robot Selenium code.
4*f0b9122aSShaheena Begum MohammedThe class contains functions which the robot framework will use
5*f0b9122aSShaheena Begum Mohammedand import as a user-defined keyword.
6*f0b9122aSShaheena Begum Mohammed"""
7e635ddc0SGeorge Keishingimport json
8e635ddc0SGeorge Keishingimport ssl
920f38712SPatrick Williams
10*f0b9122aSShaheena Begum Mohammedimport gen_print as gp  # NOQA
11*f0b9122aSShaheena Begum Mohammedimport gen_valid as gv  # NOQA
1220f38712SPatrick Williamsimport requests
1320f38712SPatrick Williamsimport websocket
141cd34b52SAnusha Dathatri
151cd34b52SAnusha Dathatri
16*f0b9122aSShaheena Begum Mohammedclass event_notification:  # NOQA
171cd34b52SAnusha Dathatri    r"""
181cd34b52SAnusha Dathatri    Main class to subscribe and receive event notifications.
191cd34b52SAnusha Dathatri    """
201cd34b52SAnusha Dathatri
211cd34b52SAnusha Dathatri    def __init__(self, host, username, password):
221cd34b52SAnusha Dathatri        r"""
231cd34b52SAnusha Dathatri        Initialize instance variables.
241cd34b52SAnusha Dathatri
251cd34b52SAnusha Dathatri        Description of argument(s):
261cd34b52SAnusha Dathatri        host        The IP or host name of the system to subscribe to.
271cd34b52SAnusha Dathatri        username    The username for the host system.
281cd34b52SAnusha Dathatri        password    The password for the host system.
291cd34b52SAnusha Dathatri        """
301cd34b52SAnusha Dathatri        self.__host = host
311cd34b52SAnusha Dathatri        self.__user = username
321cd34b52SAnusha Dathatri        self.__password = password
33*f0b9122aSShaheena Begum Mohammed        self.__websocket = None
341cd34b52SAnusha Dathatri
351cd34b52SAnusha Dathatri    def __del__(self):
361cd34b52SAnusha Dathatri        try:
371cd34b52SAnusha Dathatri            self.__websocket.close()
381cd34b52SAnusha Dathatri        except AttributeError:
391cd34b52SAnusha Dathatri            pass
401cd34b52SAnusha Dathatri
411cd34b52SAnusha Dathatri    def login(self):
421cd34b52SAnusha Dathatri        r"""
431cd34b52SAnusha Dathatri        Login and return session object.
441cd34b52SAnusha Dathatri        """
4520f38712SPatrick Williams        http_header = {"Content-Type": "application/json"}
461cd34b52SAnusha Dathatri        session = requests.session()
4720f38712SPatrick Williams        response = session.post(
4820f38712SPatrick Williams            "https://" + self.__host + "/login",
491cd34b52SAnusha Dathatri            headers=http_header,
501cd34b52SAnusha Dathatri            json={"data": [self.__user, self.__password]},
5120f38712SPatrick Williams            verify=False,
5220f38712SPatrick Williams            timeout=30,
5320f38712SPatrick Williams        )
541cd34b52SAnusha Dathatri        gv.valid_value(response.status_code, valid_values=[200])
551cd34b52SAnusha Dathatri        login_response = json.loads(response.text)
561cd34b52SAnusha Dathatri        gp.qprint_var(login_response)
5720f38712SPatrick Williams        gv.valid_value(login_response["status"], valid_values=["ok"])
581cd34b52SAnusha Dathatri        return session
591cd34b52SAnusha Dathatri
601cd34b52SAnusha Dathatri    def subscribe(self, dbus_path, enable_trace=False):
611cd34b52SAnusha Dathatri        r"""
621cd34b52SAnusha Dathatri        Subscribe to the given path and return a list of event notifications.
631cd34b52SAnusha Dathatri
641cd34b52SAnusha Dathatri        For more details on "subscribe" and "events" go to
651cd34b52SAnusha Dathatri        https://github.com/openbmc/docs/blob/master/rest-api.md#event-subscription-protocol
661cd34b52SAnusha Dathatri
671cd34b52SAnusha Dathatri        Example robot code:
681cd34b52SAnusha Dathatri        ${event_notifications}=  Subscribe  /xyz/openbmc_project/sensors
691cd34b52SAnusha Dathatri        Rprint Vars  event_notifications
701cd34b52SAnusha Dathatri
711cd34b52SAnusha Dathatri        Example output:
721cd34b52SAnusha Dathatri        event_notifications:
731cd34b52SAnusha Dathatri          [0]:
741cd34b52SAnusha Dathatri            [interface]:             xyz.openbmc_project.Sensor.Value
751cd34b52SAnusha Dathatri            [path]:                  /xyz/openbmc_project/sensors/temperature/ambient
761cd34b52SAnusha Dathatri            [event]:                 PropertiesChanged
771cd34b52SAnusha Dathatri            [properties]:
781cd34b52SAnusha Dathatri              [Value]:               23813
791cd34b52SAnusha Dathatri
801cd34b52SAnusha Dathatri        Description of argument(s):
81cfffea28SGeorge Keishing        dbus_path              The subscribing event's path (e.g.
821cd34b52SAnusha Dathatri                               "/xyz/openbmc_project/sensors").
831cd34b52SAnusha Dathatri        enable_trace           Enable or disable trace.
841cd34b52SAnusha Dathatri        """
851cd34b52SAnusha Dathatri
861cd34b52SAnusha Dathatri        session = self.login()
871cd34b52SAnusha Dathatri        cookies = session.cookies.get_dict()
881cd34b52SAnusha Dathatri        # Convert from dictionary to a string of the following format:
891cd34b52SAnusha Dathatri        # key=value;key=value...
9020f38712SPatrick Williams        cookies = gp.sprint_var(
9120f38712SPatrick Williams            cookies,
9220f38712SPatrick Williams            fmt=gp.no_header() | gp.strip_brackets(),
9320f38712SPatrick Williams            col1_width=0,
9420f38712SPatrick Williams            trailing_char="",
9520f38712SPatrick Williams            delim="=",
9620f38712SPatrick Williams        ).replace("\n", ";")
971cd34b52SAnusha Dathatri
981cd34b52SAnusha Dathatri        websocket.enableTrace(enable_trace)
9920f38712SPatrick Williams        self.__websocket = websocket.create_connection(
100*f0b9122aSShaheena Begum Mohammed            f"wss://{self.__host}/subscribe",
1011cd34b52SAnusha Dathatri            sslopt={"cert_reqs": ssl.CERT_NONE},
10220f38712SPatrick Williams            cookie=cookies,
10320f38712SPatrick Williams        )
10420f38712SPatrick Williams        dbus_path = [path.strip() for path in dbus_path.split(",")]
1051cd34b52SAnusha Dathatri        dbus_path = {"paths": dbus_path}
1061cd34b52SAnusha Dathatri
1071cd34b52SAnusha Dathatri        self.__websocket.send(json.dumps(dbus_path))
1081cd34b52SAnusha Dathatri        event_notifications = json.loads(self.__websocket.recv())
1091cd34b52SAnusha Dathatri        self.__websocket.close()
1101cd34b52SAnusha Dathatri        return event_notifications
111