from jenkinsapi.view import View
from jenkinsapi.node import Node
from jenkinsapi.exceptions import UnknownJob, NotAuthorized
-from utils.urlopener import mkurlopener, mkopener, NoAuto302Handler
+from utils.urlopener import mkurlopener, mkkrbopener, mkopener, NoAuto302Handler
import logging
import time
import urllib2
"""
Represents a jenkins environment.
"""
- def __init__(self, baseurl, username=None, password=None, proxyhost=None, proxyport=None, proxyuser=None, proxypass=None, formauth=False):
+ def __init__(self, baseurl, username=None, password=None, proxyhost=None, proxyport=None, proxyuser=None, proxypass=None, formauth=False, krbauth=False):
"""
:param baseurl: baseurl for jenkins instance including port, str
self.proxyport = proxyport
self.proxyuser = proxyuser
self.proxypass = proxypass
- JenkinsBase.__init__(self, baseurl, formauth=formauth)
+ JenkinsBase.__init__(self, baseurl, formauth=formauth, krbauth=krbauth)
def _clone(self):
return Jenkins(self.baseurl, username=self.username,
password=self.password, proxyhost=self.proxyhost,
proxyport=self.proxyport, proxyuser=self.proxyuser,
- proxypass=self.proxypass, formauth=self.formauth)
+ proxypass=self.proxypass, formauth=self.formauth, krbauth=self.krbauth)
def get_proxy_auth(self):
return self.proxyhost, self.proxyport, self.proxyuser, self.proxypass
def get_opener(self):
if self.formauth:
return self.get_login_opener()
+ if self.krbauth:
+ return self.get_krb_opener()
return mkurlopener(*self.get_auth())
def get_login_opener(self):
hdrs.append(urllib2.HTTPCookieProcessor(mcj))
return mkopener(*hdrs)
+ def get_krb_opener(self):
+ return mkkrbopener(self.baseurl)
+
def login(self):
formdata = dict(j_username=self.username, j_password=self.password,
remember_me=True, form='/')
def __str__(self):
raise NotImplemented
- def __init__(self, baseurl, poll=True, formauth=False):
+ def __init__(self, baseurl, poll=True, formauth=False, krbauth=False):
"""
Initialize a jenkins connection
"""
self.baseurl = baseurl
self.formauth = formauth
+ self.krbauth = krbauth
if poll and not self.formauth:
try:
self.poll()
import urllib2
import base64
+import kerberos as krb
+from urlparse import urlparse
import logging
def https_request(self,req):
return self.http_request(req)
+class KerberosAuthHandler(urllib2.BaseHandler):
+ """
+ A BaseHandler class that will add Kerberos Auth headers to a request
+ """
+ def __init__(self,tgt):
+ self.tgt = tgt
+
+ def http_request(self,req):
+ req.add_unredirected_header('Authorization', 'Negotiate %s' % self.tgt)
+ return req
+
+ def https_request(self,req):
+ return self.http_request(req)
+
+
def mkurlopener( jenkinsuser, jenkinspass, jenkinsurl, proxyhost, proxyport, proxyuser, proxypass ):
"""
Creates an url opener that works with both jenkins auth and proxy auth
opener = urllib2.build_opener(*handlers)
return opener.open
+def mkkrbopener( jenkinsurl ):
+ """
+ Creates an url opener that works with kerberos auth
+
+ :param jenkinsurl: jenkins url, str
+ :return: urllib2.opener configured for kerberos auth
+ """
+ handlers = []
+ for handler in get_kerberos_auth_handler(jenkinsurl=jenkinsurl):
+ handlers.append(handler)
+ opener = urllib2.build_opener(*handlers)
+ return opener.open
+
+
def mkopener(*handlers):
opener = urllib2.build_opener(*handlers)
return opener.open
return [proxy_handler, proxy_auth_handler]
+def get_kerberos_auth_handler(jenkinsurl):
+ """
+ Get a handler which enabled authentication over GSSAPI
+
+ :param jenkinsurl: jenkins base url, str
+ :return: a list of handlers
+ """
+ jenkinsnetloc = urlparse(jenkinsurl).netloc
+ assert type( jenkinsnetloc ) == str, "Jenkins network location should be a string, got %s" % repr( jenkinsnetloc )
+
+ _ignore, ctx = krb.authGSSClientInit('HTTP@%s' % jenkinsnetloc, gssflags=krb.GSS_C_DELEG_FLAG|krb.GSS_C_MUTUAL_FLAG|krb.GSS_C_SEQUENCE_FLAG)
+ rc = krb.authGSSClientStep(ctx,'')
+ if rc != krb.AUTH_GSS_CONTINUE:
+ return []
+ tgt = krb.authGSSClientResponse(ctx)
+ if not tgt:
+ return []
+
+ krb_handler = KerberosAuthHandler(tgt)
+ return [ krb_handler ]
+
class NoAuto302Handler(urllib2.HTTPRedirectHandler):
def http_error_302(self, req, fp, code, msg, hdrs):
return fp