Пример #1
0
class AgentConnection():

  def __init__(self, host, port, feature, timeout):
    self.host = host
    self.port = port
    self.feature = feature  # e.g., "bst"
    self._timeout = timeout
    self._swconfig = BroadViewBSTSwitches()
    self._auth = None

  def close(self):
    if self._auth and self._auth.logout:
        self._auth.logout()
    self._auth = None

  def _is_ok(self, r):
    return r.status_code == 200

  def _raise_fail_if(self, url, r, timeout):
    if not self._is_ok(r):
      if timeout:
        j = {"response_code": r.status_code,
             "error_code": 0,
             "msg": "Connection timeout"}
      else:
        try:
          j = r.json()["status"]
        except:
          try:
            t = ElementTree.fromstring(r)
            j = {"response_code": r.status_code,
                 "error_code": 0,
                 "msg": "XML failure response from web server"}

          except:
            j = {"response_code": r.status_code,
                 "error_code": 0,
                 "msg": "Unparsable response from web server"}

      raise RequestFailed(url, j["response_code"], j["error_code"], j["msg"])

  def getAuth(self):
    return self._auth

  def getAuthConf(self):
    auth = {}
    auth["auth"] = None
    auth["username"] = None
    auth["password"] = None

    try:
        conf = self._swconfig.getByIP(self.host)
        if conf:
            if "username" in conf:
                auth["username"] = conf["username"]
            if "password" in conf:
                auth["password"] = conf["password"]
            if "auth" in conf:
                auth["auth"] = conf["auth"]
    except:
        pass

    if auth["auth"] == None:
        auth["auth"] = os.getenv("BV_AUTH")
    if auth["username"] == None:
        auth["username"] = os.getenv("BV_USERNAME")
    if auth["password"] == None:
        auth["password"] = os.getenv("BV_PASSWORD", "")

    return auth

  def __makeRequest(self, request):

    headers = {"Content-Type": "application/json"}
    timeout = False

    isGet = False
    if request.getHttpMethod() == "GET":
      isGet = True

    auth = self.getAuth()

    payload = request.getjson().encode("utf-8")
    if self.feature:
      url = "http://%s:%d/broadview/%s/%s" % (self.host, self.port, self.feature, request.getMethod())
    else:
      url = "http://%s:%d/broadview/%s" % (self.host, self.port, request.getMethod())
    if isGet:
      try:
        r = requests.get(url, timeout=self._timeout, data=payload, headers=headers, auth=auth)
      except requests.exceptions.Timeout:
        timeout = True
    else:
      try:
        r = requests.post(url, timeout=self._timeout, data=payload, headers=headers, auth=auth)
      except requests.exceptions.Timeout:
        timeout = True

    json_data = {}
    if timeout:
        r = RequestObj() 
        r.status_code = 500

    if r.status_code == 200:
        try:
            # Data can come back with leading.trailing spaces, which trips 
            # up requests' json parser. So get as test, string, and let
            # Python json do the parsing

            json_data = json.loads(r.text.strip())
        except:
            pass

    return (r, json_data)
       
  def makeRequest(self, request):
    r, json_data = self.__makeRequest(request)

    if r.status_code == 401:
        conf = self.getAuthConf()
        try:
            auth_method = r.headers["WWW-Authenticate"]
        except:
            # RFC 2616 requires a WWW-Authenticate header in 401 responses. If
            # we get here, it was missing. Check if there is configuration that
            # declares an auth method and use that.
            LOG.info("makeRequest: 401 but no WWW-Authenticate")
            auth_method = conf["auth"]
        if auth_method:
            auth_method = auth_method.lower()
            if auth_method == "basic":
                self._auth = requests.HTTPBasicAuth(conf["username"], conf["password"])
            elif auth_method == "digest":
                self._auth = requests.HTTPDigestAuth(conf["username"], conf["password"])
            elif auth_method == "sidauth":
                self._auth = SIDAuth(self.host, self.port, conf["username"], conf["password"])
            else:
                LOG.info("unknown auth {}".format(auth_method))
                # return the 401 here
                return (r.status_code, json_data)
        
            # try again

            r, json_data = self.__makeRequest(request)

    return (r.status_code, json_data)
class AgentConnection():
    def __init__(self, host, port, feature, timeout):
        self.host = host
        self.port = port
        self.feature = feature  # e.g., "bst"
        self._timeout = timeout
        self._swconfig = BroadViewBSTSwitches()
        self._auth = None

    def close(self):
        if self._auth and self._auth.logout:
            self._auth.logout()
        self._auth = None

    def _is_ok(self, r):
        return r.status_code == 200

    def _raise_fail_if(self, url, r, timeout):
        if not self._is_ok(r):
            if timeout:
                j = {
                    "response_code": r.status_code,
                    "error_code": 0,
                    "msg": "Connection timeout"
                }
            else:
                try:
                    j = r.json()["status"]
                except:
                    try:
                        t = ElementTree.fromstring(r)
                        j = {
                            "response_code": r.status_code,
                            "error_code": 0,
                            "msg": "XML failure response from web server"
                        }

                    except:
                        j = {
                            "response_code": r.status_code,
                            "error_code": 0,
                            "msg": "Unparsable response from web server"
                        }

            raise RequestFailed(url, j["response_code"], j["error_code"],
                                j["msg"])

    def getAuth(self):
        return self._auth

    def getAuthConf(self):
        auth = {}
        auth["auth"] = None
        auth["username"] = None
        auth["password"] = None

        try:
            conf = self._swconfig.getByIP(self.host)
            if conf:
                if "username" in conf:
                    auth["username"] = conf["username"]
                if "password" in conf:
                    auth["password"] = conf["password"]
                if "auth" in conf:
                    auth["auth"] = conf["auth"]
        except:
            pass

        if auth["auth"] == None:
            auth["auth"] = os.getenv("BV_AUTH")
        if auth["username"] == None:
            auth["username"] = os.getenv("BV_USERNAME")
        if auth["password"] == None:
            auth["password"] = os.getenv("BV_PASSWORD", "")

        return auth

    def __makeRequest(self, request):

        headers = {"Content-Type": "application/json"}
        timeout = False

        isGet = False
        if request.getHttpMethod() == "GET":
            isGet = True

        auth = self.getAuth()

        payload = request.getjson().encode("utf-8")
        if self.feature:
            url = "http://%s:%d/broadview/%s/%s" % (
                self.host, self.port, self.feature, request.getMethod())
        else:
            url = "http://%s:%d/broadview/%s" % (self.host, self.port,
                                                 request.getMethod())
        if isGet:
            try:
                r = requests.get(url,
                                 timeout=self._timeout,
                                 data=payload,
                                 headers=headers,
                                 auth=auth)
            except requests.exceptions.Timeout:
                timeout = True
        else:
            try:
                r = requests.post(url,
                                  timeout=self._timeout,
                                  data=payload,
                                  headers=headers,
                                  auth=auth)
            except requests.exceptions.Timeout:
                timeout = True

        json_data = {}
        if timeout:
            r = RequestObj()
            r.status_code = 500

        if r.status_code == 200:
            try:
                # Data can come back with leading.trailing spaces, which trips
                # up requests' json parser. So get as test, string, and let
                # Python json do the parsing

                json_data = json.loads(r.text.strip())
            except:
                pass

        return (r, json_data)

    def makeRequest(self, request):
        r, json_data = self.__makeRequest(request)

        if r.status_code == 401:
            conf = self.getAuthConf()
            try:
                auth_method = r.headers["WWW-Authenticate"]
            except:
                # RFC 2616 requires a WWW-Authenticate header in 401 responses. If
                # we get here, it was missing. Check if there is configuration that
                # declares an auth method and use that.
                LOG.info("makeRequest: 401 but no WWW-Authenticate")
                auth_method = conf["auth"]
            if auth_method:
                auth_method = auth_method.lower()
                if auth_method == "basic":
                    self._auth = requests.HTTPBasicAuth(
                        conf["username"], conf["password"])
                elif auth_method == "digest":
                    self._auth = requests.HTTPDigestAuth(
                        conf["username"], conf["password"])
                elif auth_method == "sidauth":
                    self._auth = SIDAuth(self.host, self.port,
                                         conf["username"], conf["password"])
                else:
                    LOG.info("unknown auth {}".format(auth_method))
                    # return the 401 here
                    return (r.status_code, json_data)

                # try again

                r, json_data = self.__makeRequest(request)

        return (r.status_code, json_data)