Ejemplo n.º 1
0
Archivo: pc.py Proyecto: intel/tcf
    def power_get_do(self, target):
        """Get the power status for the outlet

        The unit returns the power state when querying the
        ``/index.htm`` path...as a comment inside the HTML body of the
        respose. *Chuckle*

        So we look for::

          <!-- state=XY lock=ANY -->

        *XY* is the hex bitmap of states against the outlet
        number. *ANY* is the hex lock bitmap (outlets that can't
        change).

        """
        r = requests.get(self.url + "/index.htm")
        commonl.request_response_maybe_raise(r)
        m = self.state_regex.search(r.content)
        if not m:
            raise Exception("Cannot find '%s' in power switch response"
                            % self.state_regex.pattern)
        state = int(m.group('state'), base = 16)
        # Note outlet numbers are base-1...
        if state & (1 << self.outlet - 1) == 0:
            return False
        else:
            return True
Ejemplo n.º 2
0
Archivo: pc.py Proyecto: inakypg/tcf
    def get(self, target, component):
        """Get the power status for the outlet

        The unit returns the power state when querying the
        ``/index.htm`` path...as a comment inside the HTML body of the
        respose. *Chuckle*

        So we look for::

          <!-- state=XY lock=ANY -->

        *XY* is the hex bitmap of states against the outlet
        number. *ANY* is the hex lock bitmap (outlets that can't
        change).

        """
        r = requests.get(self.url + "/index.htm")
        commonl.request_response_maybe_raise(r)
        m = self.state_regex.search(r.content)
        if not m:
            raise Exception("Cannot find '%s' in power switch response" %
                            self.state_regex.pattern)
        state = int(m.group('state'), base=16)
        # Note outlet numbers are base-1...
        if state & (1 << self.outlet - 1) == 0:
            return False
        else:
            return True
Ejemplo n.º 3
0
 def power_cycle_do(self, target, wait=0):
     if self.power_get_do(target):
         r = requests.get(self.url + "/outlet?%d=OFF" % self.outlet)
         commonl.request_response_maybe_raise(r)
         if self.reboot_wait_s > 0 or wait > 0:
             time.sleep(max(self.reboot_wait_s, wait))
     r = requests.get(self.url + "/outlet?%d=ON" % self.outlet)
     commonl.request_response_maybe_raise(r)
     # Give it time to settle
     time.sleep(self.reboot_wait_s)
     self.power_get_do(target)
Ejemplo n.º 4
0
Archivo: pc.py Proyecto: intel/tcf
 def power_cycle_do(self, target, wait = 0):
     if self.power_get_do(target):
         r = requests.get(self.url + "/outlet?%d=OFF" % self.outlet)
         commonl.request_response_maybe_raise(r)
         if self.reboot_wait_s > 0 or wait > 0:
             time.sleep(max(self.reboot_wait_s, wait))
     r = requests.get(self.url + "/outlet?%d=ON" % self.outlet)
     commonl.request_response_maybe_raise(r)
     # Give it time to settle
     time.sleep(self.reboot_wait_s)
     self.power_get_do(target)
Ejemplo n.º 5
0
    def send_request(self,
                     method,
                     url,
                     data=None,
                     json=None,
                     files=None,
                     stream=False,
                     raw=False,
                     timeout=160):
        """
        Send request to server using url and data, save the cookies
        generated from request, search for issues on connection and
        raise and exception or return the response object.

        :param str url: url to request
        :param dict data: args to send in the request. default None
        :param str method: method used to request GET, POST and
          PUT. Defaults to PUT.
        :param bool raise_error: if true, raise an error if something goes
           wrong in the request. default True
        :returns requests.Response: response object

        """
        assert not (data and json), \
            "can't specify data and json at the same time"
        # create the url to send request based on API version
        if not self._base_url:
            self._base_url = urlparse.urljoin(self._url,
                                              rest_target_broker.API_PREFIX)
        if url.startswith("/"):
            url = url[1:]
        url_request = urlparse.urljoin(self._base_url, url)
        logger.debug("send_request: %s %s", method, url_request)
        with self.lock:
            cookies = self.cookies
        session = tls_var("session", requests.Session)
        if method == 'GET':
            r = session.get(url_request,
                            cookies=cookies,
                            json=json,
                            data=data,
                            verify=self.verify_ssl,
                            stream=stream,
                            timeout=(timeout, timeout))
        elif method == 'PATCH':
            r = session.patch(url_request,
                              cookies=cookies,
                              json=json,
                              data=data,
                              verify=self.verify_ssl,
                              stream=stream,
                              timeout=(timeout, timeout))
        elif method == 'POST':
            r = session.post(url_request,
                             cookies=cookies,
                             json=json,
                             data=data,
                             files=files,
                             verify=self.verify_ssl,
                             stream=stream,
                             timeout=(timeout, timeout))
        elif method == 'PUT':
            r = session.put(url_request,
                            cookies=cookies,
                            json=json,
                            data=data,
                            verify=self.verify_ssl,
                            stream=stream,
                            timeout=(timeout, timeout))
        elif method == 'DELETE':
            r = session.delete(url_request,
                               cookies=cookies,
                               json=json,
                               data=data,
                               verify=self.verify_ssl,
                               stream=stream,
                               timeout=(timeout, timeout))
        else:
            raise Exception("Unknown method '%s'" % method)

        #update cookies
        if len(r.cookies) > 0:
            with self.lock:
                # Need to update like this because r.cookies is not
                # really a dict, but supports iteritems() -- overwrite
                # existing cookies (session cookie) and keep old, as
                # it will have the stuff we need to auth with the
                # server (like the remember_token)
                # FIXME: maybe filter to those two only?
                for cookie, value in r.cookies.iteritems():
                    self.cookies[cookie] = value
        commonl.request_response_maybe_raise(r)
        if raw:
            return r
        rdata = r.json(object_pairs_hook=collections.OrderedDict)
        if '_diagnostics' in rdata:
            diagnostics = rdata.pop('_diagnostics').encode("utf-8", 'replace')
            # this is not very...memory efficient
            for line in diagnostics.split("\n"):
                logger.warning("diagnostics: " + line)
        return rdata
Ejemplo n.º 6
0
Archivo: pc.py Proyecto: inakypg/tcf
 def off(self, target, _component):
     r = requests.get(self.url + "/outlet?%d=OFF" % self.outlet)
     commonl.request_response_maybe_raise(r)
Ejemplo n.º 7
0
 def power_off_do(self, target):
     r = requests.get(self.url + "/outlet?%d=OFF" % self.outlet)
     commonl.request_response_maybe_raise(r)
     self.power_get_do(target)
Ejemplo n.º 8
0
 def power_on_do(self, target):
     r = requests.get(self.url + "/outlet?%d=ON" % self.outlet)
     commonl.request_response_maybe_raise(r)
     self.power_get_do(target)
     time.sleep(self.reboot_wait_s)
Ejemplo n.º 9
0
    def send_request(self,
                     method,
                     url,
                     data=None,
                     json=None,
                     files=None,
                     stream=False,
                     raw=False,
                     timeout=160,
                     retry_timeout=0,
                     retry_backoff=0.5,
                     skip_prefix=False):
        """
        Send request to server using url and data, save the cookies
        generated from request, search for issues on connection and
        raise and exception or return the response object.

        :param str url: url to request
        :param dict data: args to send in the request. default None
        :param str method: method used to request GET, POST and
          PUT. Defaults to PUT.
        :param bool raise_error: if true, raise an error if something goes
           wrong in the request. default True

        :param float retry_timeout: (optional, default 0--disabled)
          how long (in seconds) to retry connections in case of failure
          (:class:`requests.exceptions.ConnectionError`,
          :class:`requests.exceptions.ReadTimeout`)

          Note a retry can have side effects if the request is not
          idempotent (eg: writing to a console); retries shall only be
          enabled for GET calls. Support for non-idempotent calls has
          to be added to the protocol.

          See also :meth:`tcfl.tc.target_c.ttbd_iface_call`

        :returns requests.Response: response object

        """
        assert not (data and json), \
            "can't specify data and json at the same time"
        assert isinstance(retry_timeout, (int, float)) and retry_timeout >= 0, \
            f"retry_timeout: {retry_timeout} has to be an int/float >= 0"
        assert isinstance(retry_backoff, (int, float)) and retry_backoff > 0
        if retry_timeout > 0:
            assert retry_backoff < retry_timeout, \
                f"retry_backoff {retry_backoff} has to be" \
                f" smaller than retry_timeout {retry_timeout}"

        # create the url to send request based on API version
        if url.startswith("/"):
            url = url[1:]
        if not self._base_url:
            self._base_url = urllib.parse.urljoin(
                self._url, rest_target_broker.API_PREFIX)
        if skip_prefix:
            url_request = urllib.parse.urljoin(self.parsed_url.geturl(), url)
        else:
            url_request = urllib.parse.urljoin(self._base_url, url)
        logger.debug("send_request: %s %s", method, url_request)
        with self.lock:
            cookies = self.cookies
        session = tls_var("session", requests.Session)
        retry_count = -1
        retry_ts = None
        r = None
        while True:
            retry_count += 1
            try:
                if method == 'GET':
                    r = session.get(url_request,
                                    cookies=cookies,
                                    json=json,
                                    data=data,
                                    verify=self.verify_ssl,
                                    stream=stream,
                                    timeout=(timeout, timeout))
                elif method == 'PATCH':
                    r = session.patch(url_request,
                                      cookies=cookies,
                                      json=json,
                                      data=data,
                                      verify=self.verify_ssl,
                                      stream=stream,
                                      timeout=(timeout, timeout))
                elif method == 'POST':
                    r = session.post(url_request,
                                     cookies=cookies,
                                     json=json,
                                     data=data,
                                     files=files,
                                     verify=self.verify_ssl,
                                     stream=stream,
                                     timeout=(timeout, timeout))
                elif method == 'PUT':
                    r = session.put(url_request,
                                    cookies=cookies,
                                    json=json,
                                    data=data,
                                    verify=self.verify_ssl,
                                    stream=stream,
                                    timeout=(timeout, timeout))
                elif method == 'DELETE':
                    r = session.delete(url_request,
                                       cookies=cookies,
                                       json=json,
                                       data=data,
                                       verify=self.verify_ssl,
                                       stream=stream,
                                       timeout=(timeout, timeout))
                else:
                    raise AssertionError("{method}: unknown HTTP method")
                break
            except (
                    requests.exceptions.ConnectionError,
                    requests.exceptions.ReadTimeout,
            ) as e:
                # Retry only these; note these cannot report
                # Report how many retries we have done, wait a backoff
                # and then loop it.
                if retry_timeout == 0:
                    raise
                ts = time.time()
                if retry_ts == None:
                    retry_ts = ts  # first one
                else:
                    if ts - retry_ts > retry_timeout:
                        raise RuntimeError(
                            f"{url_request}: giving up after {retry_timeout}s"
                            f" retrying {retry_count} connection errors"
                        ) from e
                time.sleep(retry_backoff)
                # increase the backoff to avoid pestering too much,
                # but make sure it doesn't get too big so we at least
                # get 10 tries in the timeout period
                if retry_backoff < retry_timeout / 10:
                    retry_backoff *= 1.2
                continue

        #update cookies
        if len(r.cookies) > 0:
            with self.lock:
                # Need to update like this because r.cookies is not
                # really a dict, but supports items() -- overwrite
                # existing cookies (session cookie) and keep old, as
                # it will have the stuff we need to auth with the
                # server (like the remember_token)
                # FIXME: maybe filter to those two only?
                for cookie, value in r.cookies.items():
                    self.cookies[cookie] = value
        commonl.request_response_maybe_raise(r)
        if raw:
            return r
        rdata = r.json(object_pairs_hook=collections.OrderedDict)
        if '_diagnostics' in rdata:
            diagnostics = rdata.pop('_diagnostics')
            # this is not very...memory efficient
            for line in diagnostics.split("\n"):
                logger.warning("diagnostics: " + line)
        return rdata
Ejemplo n.º 10
0
Archivo: pc.py Proyecto: intel/tcf
 def power_off_do(self, target):
     r = requests.get(self.url + "/outlet?%d=OFF" % self.outlet)
     commonl.request_response_maybe_raise(r)
     self.power_get_do(target)
Ejemplo n.º 11
0
Archivo: pc.py Proyecto: intel/tcf
 def power_on_do(self, target):
     r = requests.get(self.url + "/outlet?%d=ON" % self.outlet)
     commonl.request_response_maybe_raise(r)
     self.power_get_do(target)
     time.sleep(self.reboot_wait_s)
Ejemplo n.º 12
0
    def send_request(self,
                     method,
                     url,
                     data=None,
                     files=None,
                     stream=False,
                     raw=False,
                     timeout=480):
        """
        Send request to server using url and data, save the cookies
        generated from request, search for issues on connection and
        raise and exception or return the response object.

        :param url: url to request
        :type url: str
        :param data: args to send in the request. default None
        :type data: dict
        :param method: method used to request GET, POST and PUT. default PUT
        :type method: str
        :param raise_error: if true, raise an error if something goes
            wrong in the request. default True
        :type raise_error: bool
        :returns: response object
        :rtype: requests.Response

        """
        # create the url to send request based on API version
        if not self._base_url:
            self._base_url = urlparse.urljoin(self._url,
                                              rest_target_broker.API_PREFIX)
        if url.startswith("/"):
            url = url[1:]
        url_request = urlparse.urljoin(self._base_url, url)
        logger.debug("send_request: %s %s", method, url_request)
        with self.lock:
            cookies = self.cookies
        session = tls_var("session", requests.Session)
        if method == 'GET':
            r = session.get(url_request,
                            cookies=cookies,
                            data=data,
                            verify=self.verify_ssl,
                            stream=stream,
                            timeout=timeout)
        elif method == 'POST':
            r = session.post(url_request,
                             cookies=cookies,
                             data=data,
                             files=files,
                             verify=self.verify_ssl,
                             stream=stream,
                             timeout=timeout)
        elif method == 'PUT':
            r = session.put(url_request,
                            cookies=cookies,
                            data=data,
                            verify=self.verify_ssl,
                            stream=stream,
                            timeout=timeout)
        elif method == 'DELETE':
            r = session.delete(url_request,
                               cookies=cookies,
                               data=data,
                               verify=self.verify_ssl,
                               stream=stream,
                               timeout=timeout)
        else:
            raise Exception("Unknown method '%s'" % method)

        #update cookies
        if len(r.cookies) > 0:
            with self.lock:
                # Need to update like this because r.cookies is not
                # really a dict, but supports iteritems() -- overwrite
                # existing cookies (session cookie) and keep old, as
                # it will have the stuff we need to auth with the
                # server (like the remember_token)
                # FIXME: maybe filter to those two only?
                for cookie, value in r.cookies.iteritems():
                    self.cookies[cookie] = value
        commonl.request_response_maybe_raise(r)
        if raw:
            return r
        rdata = r.json()
        diagnostics = rdata.get('diagnostics', "").encode("utf-8", 'replace')
        if diagnostics != "":
            for line in diagnostics.split("\n"):
                logger.warning("diagnostics: " + line)
        return rdata