Support HTTP authentication
Change-Id: I7648d8a14ac7c0e65758c095fef8faf9094d9c5c
This commit is contained in:
parent
724700c104
commit
31dbf8e3a1
@ -21,6 +21,7 @@ class AgentAPI(object):
|
||||
def __init__(self):
|
||||
self.__httpMethod = "POST"
|
||||
self.__feature = None
|
||||
self.__auth = None
|
||||
self.__host = None
|
||||
self.__port = None
|
||||
self.__payload = None
|
||||
@ -64,7 +65,9 @@ class AgentAPI(object):
|
||||
self.__payload["id"] = AgentAPI.__serial
|
||||
AgentAPI.__serial = AgentAPI.__serial + 1
|
||||
conn = AgentConnection(self.__host, self.__port, self.__feature, timeout)
|
||||
return conn.makeRequest(self)
|
||||
r = conn.makeRequest(self)
|
||||
conn.close()
|
||||
return r
|
||||
|
||||
def getjson(self):
|
||||
x = json.dumps(OrderedDict(self.__payload))
|
||||
|
@ -21,6 +21,15 @@ import sys
|
||||
import urllib
|
||||
from xml.etree import ElementTree
|
||||
import json
|
||||
from sidauth import SIDAuth
|
||||
from broadview_lib.config.broadviewconfig import BroadViewBSTSwitches
|
||||
|
||||
try:
|
||||
from oslo_log import log as logging
|
||||
except:
|
||||
import logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
class RequestObj():
|
||||
pass
|
||||
@ -39,11 +48,19 @@ class RequestFailed(Exception):
|
||||
return repr((self._url, self._http_code, self._open_code, self._open_msg))
|
||||
|
||||
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.logout:
|
||||
self._auth.logout()
|
||||
self._auth = None
|
||||
|
||||
def _is_ok(self, r):
|
||||
return r.status_code == 200
|
||||
@ -71,7 +88,27 @@ class AgentConnection():
|
||||
|
||||
raise RequestFailed(url, j["response_code"], j["error_code"], j["msg"])
|
||||
|
||||
def makeRequest(self, request):
|
||||
def getAuth(self):
|
||||
return self._auth
|
||||
|
||||
def getAuthConf(self):
|
||||
auth = {}
|
||||
auth["auth"] = None
|
||||
auth["username"] = None
|
||||
auth["password"] = None
|
||||
|
||||
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"]
|
||||
|
||||
return auth
|
||||
|
||||
def __makeRequest(self, request):
|
||||
|
||||
headers = {"Content-Type": "application/json"}
|
||||
timeout = False
|
||||
@ -80,32 +117,23 @@ class AgentConnection():
|
||||
if request.getHttpMethod() == "GET":
|
||||
isGet = True
|
||||
|
||||
if False and isGet:
|
||||
payload = request.getjson().encode("utf-8")
|
||||
if self.feature:
|
||||
url = "http://%s:%d/broadview/%s/%s%s%s" % (self.host, self.port, self.feature, request.getMethod(), "?req=", payload)
|
||||
else:
|
||||
url = "http://%s:%d/broadview/%s%s%s" % (self.host, self.port, request.getMethod(), "?req=", payload)
|
||||
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, headers=headers)
|
||||
r = requests.get(url, timeout=self._timeout, data=payload, headers=headers, auth=auth)
|
||||
except requests.exceptions.Timeout:
|
||||
timeout = True
|
||||
else:
|
||||
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)
|
||||
except requests.exceptions.Timeout:
|
||||
timeout = True
|
||||
else:
|
||||
try:
|
||||
r = requests.post(url, timeout=self._timeout, data=payload, headers=headers)
|
||||
except requests.exceptions.Timeout:
|
||||
timeout = True
|
||||
try:
|
||||
r = requests.post(url, timeout=self._timeout, data=payload, headers=headers, auth=auth)
|
||||
except requests.exceptions.Timeout:
|
||||
timeout = True
|
||||
|
||||
json_data = {}
|
||||
if timeout:
|
||||
@ -122,6 +150,39 @@ class AgentConnection():
|
||||
except:
|
||||
pass
|
||||
|
||||
self._raise_fail_if(url, r, timeout)
|
||||
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:
|
||||
auth_method = None
|
||||
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[self.host] = requests.HTTPDigestAuth(conf["username"], conf["password"])
|
||||
elif auth_method == "sidauth":
|
||||
self._auth[self.host] = SIDAuth(self.host, self.port, conf["username"], conf["password"])
|
||||
else:
|
||||
LOG.info("unknown auth {}".format(auth_method))
|
||||
return
|
||||
else:
|
||||
# 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")
|
||||
if conf["auth"] and conf["auth"].lower() == "sidauth":
|
||||
self._auth = SIDAuth(self.host, self.port, conf["username"], conf["password"])
|
||||
|
||||
# try again
|
||||
|
||||
r, json_data = self.__makeRequest(request)
|
||||
|
||||
return (r.status_code, json_data)
|
||||
|
||||
|
@ -35,6 +35,14 @@ class BroadViewBSTSwitches():
|
||||
else:
|
||||
return 0
|
||||
|
||||
def getByIP(self, ip):
|
||||
ret = None
|
||||
for x in range(self.__len__()):
|
||||
if BroadViewBSTSwitches.bst_switches[x]["ip"] == ip:
|
||||
ret = BroadViewBSTSwitches.bst_switches[x]
|
||||
break
|
||||
return ret
|
||||
|
||||
def get(self, i):
|
||||
ret = None
|
||||
if i >= 0 and i < len(BroadViewBSTSwitches.bst_switches):
|
||||
|
54
broadview_lib/config/sidauth.py
Normal file
54
broadview_lib/config/sidauth.py
Normal file
@ -0,0 +1,54 @@
|
||||
#
|
||||
# (C) Copyright Broadcom Corporation 2016
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
#
|
||||
# You may obtain a copy of the License at
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import requests
|
||||
|
||||
class SIDAuth(requests.auth.AuthBase):
|
||||
def __init__(self, host, port, username, password):
|
||||
super(SIDAuth, self).__init__()
|
||||
self._SID = None
|
||||
self._host = host
|
||||
self._port = port
|
||||
self._username = username
|
||||
self._password = password
|
||||
self._login()
|
||||
|
||||
def _getCookie(self):
|
||||
cookie = {}
|
||||
if self._SID:
|
||||
x = self._SID.split("=")
|
||||
cookie[x[0]] = x[1]
|
||||
return cookie
|
||||
|
||||
def _login(self):
|
||||
url = "http://{}:{}/broadview/login?username={}&password={}".format(self._host, self._port, self._username, self._password)
|
||||
r = requests.put(url)
|
||||
code = r.status_code
|
||||
if code == 200:
|
||||
try:
|
||||
self._SID = r.headers["Set-Cookie"]
|
||||
except:
|
||||
self._SID = None
|
||||
|
||||
def logout(self):
|
||||
url = "http://{}:{}/broadview/logout".format(self._host, self._port)
|
||||
r = requests.put(url, cookies=self._getCookie())
|
||||
self._SID = None
|
||||
|
||||
def __call__(self, r):
|
||||
if self._SID:
|
||||
r.headers['Cookie'] = self._SID
|
||||
return r
|
Loading…
x
Reference in New Issue
Block a user