Support Kerberos authentication in mbs-build

This commit is contained in:
mprahl
2017-09-19 16:30:07 -04:00
parent 5d9a16e8f0
commit 97ac3de347
2 changed files with 55 additions and 20 deletions

View File

@@ -14,6 +14,8 @@ from tabulate import tabulate
from multiprocessing.dummy import Pool as ThreadPool
from copy import copy
import urllib3
import json
import requests_kerberos
try:
from urllib.parse import urljoin
@@ -22,7 +24,8 @@ except ImportError:
DEFAULT_ID_PROVIDER = "https://id.fedoraproject.org/openidc/"
DEFAULT_MBS_SERVER = "https://mbs.fedoraproject.org"
DEFAULT_MBS_REST_API = "/module-build-service/1/module-builds/"
DEFAULT_MBS_REST_PREFIX = "/module-build-service/1/"
DEFAULT_MBS_REST_API = "{0}module-builds/".format(DEFAULT_MBS_REST_PREFIX)
DEFAULT_KOJI_TASK_URL = "https://koji.fedoraproject.org/koji/taskinfo"
openidc_client.WEB_PORTS = [13747]
@@ -39,6 +42,17 @@ BUILD_STATES = {
INVERSE_BUILD_STATES = {v: k for k, v in BUILD_STATES.items()}
def get_auth_method(server, verify=True):
config_url = '{0}{1}about/'.format(server.rstrip('/'), DEFAULT_MBS_REST_PREFIX)
rv = requests.get(config_url, timeout=30, verify=verify)
# Assume that if the connection fails, it's because the config API doesn't
# exist on the server yet
if not rv.ok:
return 'oidc'
rv_json = rv.json()
return rv_json['auth_method']
def fetch_module_info(server, build_id):
if not server:
server = DEFAULT_MBS_SERVER
@@ -176,29 +190,50 @@ def _send_oidc_request(oidc, verb, *args, **kwargs):
return resp
def send_authorized_request(verb, server, id_provider, url, body, **kwargs):
def send_authorized_request(verb, server, url, body, id_provider=None, **kwargs):
"""
Sends authorized request to server.
"""
if not server:
server = DEFAULT_MBS_SERVER
if not id_provider:
id_provider = DEFAULT_ID_PROVIDER
logging.info("Trying to get the token from %s", id_provider)
full_url = urljoin(server, url)
verify = kwargs.get('verify', True)
auth_method = get_auth_method(server, verify=verify)
# Get the auth token using the OpenID client.
oidc = openidc_client.OpenIDCClient(
"mbs_build", id_provider,
{'Token': 'Token', 'Authorization': 'Authorization'},
'mbs-authorizer', "notsecret")
if auth_method == 'oidc':
if not id_provider:
id_provider = DEFAULT_ID_PROVIDER
scopes = ['openid', 'https://id.fedoraproject.org/scope/groups',
'https://mbs.fedoraproject.org/oidc/submit-build']
logging.info("Trying to get the token from %s", id_provider)
logging.debug("Sending body: %s", body)
resp = _send_oidc_request(oidc, verb, urljoin(server, url), json=body,
scopes=scopes, **kwargs)
# Get the auth token using the OpenID client.
oidc = openidc_client.OpenIDCClient(
"mbs_build", id_provider,
{'Token': 'Token', 'Authorization': 'Authorization'},
'mbs-authorizer', "notsecret")
scopes = ['openid', 'https://id.fedoraproject.org/scope/groups',
'https://mbs.fedoraproject.org/oidc/submit-build']
logging.debug("Sending body: %s", body)
resp = _send_oidc_request(oidc, verb, full_url, json=body,
scopes=scopes, **kwargs)
elif auth_method == 'kerberos':
if type(body) is dict:
data = json.dumps(body)
else:
data = body
auth = requests_kerberos.HTTPKerberosAuth(mutual_authentication=requests_kerberos.OPTIONAL)
resp = requests.request(verb, full_url, data=data, auth=auth, verify=verify)
if resp.status_code == 401:
logging.error('Authentication using Kerberos failed. Make sure you have a valid '
'Kerberos ticket.')
sys.exit(1)
else:
logging.exception('The MBS server requires an unsupported authentication method of '
'"{0}"'.format(auth_method))
sys.exit(1)
return resp
@@ -271,8 +306,7 @@ def submit_module_build(scm_url, branch, server, id_provider, pyrpkg, verify=Tru
return -5, "Optional arguments are not in a proper arg=value format."
body.update(optional_dict)
resp = send_authorized_request(
"POST", server, id_provider, DEFAULT_MBS_REST_API,
body, verify=verify)
"POST", server, DEFAULT_MBS_REST_API, body, id_provider=id_provider, verify=verify)
logging.info(resp.text)
data = resp.json()
@@ -320,9 +354,8 @@ def cancel_module_build(server, id_provider, build_id, verify=True):
"""
logging.info("Cancelling module build %s", build_id)
resp = send_authorized_request(
"PATCH", server, id_provider,
"%s/%s" % (DEFAULT_MBS_REST_API, build_id),
{'state': 'failed'}, verify=verify)
"PATCH", server, "%s/%s" % (DEFAULT_MBS_REST_API, build_id),
{'state': 'failed'}, id_provider=id_provider, verify=verify)
logging.info(resp.text)

View File

@@ -21,6 +21,8 @@ psutil
pyOpenSSL
python-fedora
qpid-python
requests # Client only
requests_kerberos # Client only
six
sqlalchemy
tabulate