Add support for API authentication in the client

This adds support for authentication to the offline and http clients
as well as the plumbing for the callback and the ara_record module to
support it.

This works but is missing a lot of tests. New issues have been created
to make sure we don't forget about adding tests.

Fixes: https://github.com/ansible-community/ara/issues/16
Change-Id: I62937dac1eb349baf6dea386dbd22b59d52319cd
Co-Authored-By: David Moreau-Simard <dmsimard@redhat.com>
Co-Authored-By: Florian Apolloner <florian@apolloner.eu>
This commit is contained in:
David Moreau Simard 2019-04-10 10:49:54 -04:00
parent 8645a48bfe
commit 9ff1630b04
No known key found for this signature in database
GPG Key ID: CBEB466764A9E621
5 changed files with 42 additions and 10 deletions

View File

@ -28,7 +28,7 @@ CLIENT_VERSION = pbr.version.VersionInfo("ara").release_string()
class HttpClient(object):
def __init__(self, endpoint="http://127.0.0.1:8000", timeout=30):
def __init__(self, endpoint="http://127.0.0.1:8000", timeout=30, auth=None):
self.log = logging.getLogger(__name__)
self.endpoint = endpoint
@ -40,6 +40,8 @@ class HttpClient(object):
}
self.http = requests.Session()
self.http.headers.update(self.headers)
if auth is not None:
self.http.auth = auth
def _request(self, method, url, **payload):
# Use requests.Session to do the query
@ -68,9 +70,9 @@ class HttpClient(object):
class AraHttpClient(object):
def __init__(self, endpoint="http://127.0.0.1:8000", timeout=30):
def __init__(self, endpoint="http://127.0.0.1:8000", timeout=30, auth=None):
self.log = logging.getLogger(__name__)
self.client = HttpClient(endpoint, timeout)
self.client = HttpClient(endpoint, timeout, auth=auth)
def _request(self, method, url, **kwargs):
func = getattr(self.client, method)

View File

@ -29,7 +29,7 @@ from ara.clients.http import AraHttpClient
class AraOfflineClient(AraHttpClient):
def __init__(self):
def __init__(self, auth=None):
self.log = logging.getLogger(__name__)
from django import setup as django_setup
@ -44,7 +44,7 @@ class AraOfflineClient(AraHttpClient):
django_setup()
self._start_server()
super().__init__(endpoint="http://localhost:%d" % self.server_thread.port)
super().__init__(endpoint="http://localhost:%d" % self.server_thread.port, auth=auth)
def _start_server(self):
self.server_thread = ServerThread("localhost")

View File

@ -15,17 +15,23 @@
# You should have received a copy of the GNU General Public License
# along with ARA. If not, see <http://www.gnu.org/licenses/>.
from requests.auth import HTTPBasicAuth
from ara.clients.http import AraHttpClient
from ara.clients.offline import AraOfflineClient
def get_client(client="offline", endpoint="http://127.0.0.1:8000", timeout=30):
def get_client(client="offline", endpoint="http://127.0.0.1:8000", timeout=30, username=None, password=None):
"""
Returns a specified client configuration or one with sane defaults.
"""
auth = None
if username is not None and password is not None:
auth = HTTPBasicAuth(username, password)
if client == "offline":
return AraOfflineClient()
return AraOfflineClient(auth=auth)
elif client == "http":
return AraHttpClient(endpoint=endpoint, timeout=timeout)
return AraHttpClient(endpoint=endpoint, timeout=timeout, auth=auth)
else:
raise ValueError(f"Unsupported API client: {client} (use 'http' or 'offline')")

View File

@ -147,7 +147,11 @@ class ActionModule(ActionBase):
client = options["api_client"]
endpoint = options["api_server"]
timeout = options["api_timeout"]
self.client = client_utils.get_client(client=client, endpoint=endpoint, timeout=timeout)
username = options["api_username"]
password = options["api_password"]
self.client = client_utils.get_client(
client=client, endpoint=endpoint, timeout=timeout, username=username, password=password
)
def create_or_update_key(self, playbook, key, value, type):
changed = False

View File

@ -71,6 +71,22 @@ options:
ini:
- section: ara
key: api_server
api_username:
description: If authentication is required, the username to authenticate with
default: null
env:
- name: ARA_API_USERNAME
ini:
- section: ara
key: api_username
api_password:
description: If authentication is required, the password to authenticate with
default: null
env:
- name: ARA_API_PASSWORD
ini:
- section: ara
key: api_password
api_timeout:
description: Timeout, in seconds, before giving up on HTTP requests
default: 30
@ -132,7 +148,11 @@ class CallbackModule(CallbackBase):
client = self.get_option("api_client")
endpoint = self.get_option("api_server")
timeout = self.get_option("api_timeout")
self.client = client_utils.get_client(client=client, endpoint=endpoint, timeout=timeout)
username = self.get_option("api_username")
password = self.get_option("api_password")
self.client = client_utils.get_client(
client=client, endpoint=endpoint, timeout=timeout, username=username, password=password
)
def v2_playbook_on_start(self, playbook):
self.log.debug("v2_playbook_on_start")