blob: fcb8984dd1ada87dc00feaeecb9ea38eefa18427 [file] [log] [blame]
Jakub Josef8e7385e2016-12-07 21:20:34 +01001import bcrypt
2import logging
3import requests
4from salt.exceptions import SaltInvocationError
5
6logger = logging.getLogger(__name__)
7
8
9def call_groovy_script(script, props):
10 """
11 Common method for call Jenkins groovy script API
12
13 :param script groovy script template
14 :param props groovy script properties
15 :returns: HTTP dict {status,code,msg}
16 """
17 ret = {
18 "status": "FAILED",
19 "code": 999,
20 "msg": ""
21 }
22 jenkins_url, jenkins_user, jenkins_password = get_jenkins_auth()
23 if not jenkins_url:
24 raise SaltInvocationError('No Jenkins URL found.')
Jakub Josefe13e2e72016-12-08 13:41:19 +010025
26 token_obj = get_api_crumb(jenkins_url, jenkins_user, jenkins_password)
27 req_data = {"script": render_groovy_script(script, props)}
28 if token_obj:
29 req_data[token_obj["crumbRequestField"]] = token_obj["crumb"]
30
31 logger.debug("Calling Jenkins script API with URL: %s", jenkins_url)
32 req = requests.post('%s/scriptText' % jenkins_url,
33 auth=(jenkins_user, jenkins_password),
34 data=req_data)
35 ret["code"] = req.status_code
36 if req.status_code == 200:
37 ret["status"] = "SUCCESS"
38 ret["msg"] = req.text
39 logger.debug("Jenkins script API call success: %s", ret)
Jakub Josef8e7385e2016-12-07 21:20:34 +010040 else:
Jakub Josefe13e2e72016-12-08 13:41:19 +010041 logger.error("Jenkins script API call failed. \
42 Return code %s. Text: %s", req.status_code, req.text)
Jakub Josef8e7385e2016-12-07 21:20:34 +010043 return ret
44
45
46def render_groovy_script(script, props):
47 """
48 Helper method for rendering groovy script with props
49
50 :param name: groovy script tempalte
51 :param scope: groovy script properties
52 :returns: generated groovy script
53 """
54 return script.format(**props)
55
56
57def get_api_crumb(jenkins_url=None, jenkins_user=None, jenkins_password=None):
58 """
59 Obtains Jenkins API crumb, if CSRF protection is enabled.
60 Jenkins params can be given by params or not, if not,
61 params will be get from salt.
62
63 :param jenkins_url: Jenkins URL (optional)
64 :param jenkins_user: Jenkins admin username (optional)
65 :param jenkins_password: Jenkins admin password (optional)
66 :returns: salt-specified state dict
67 """
68 if not jenkins_url:
69 jenkins_url, jenkins_user, jenkins_password = get_jenkins_auth()
70 logger.debug("Obtaining Jenkins API crumb for URL: %s", jenkins_url)
71 tokenReq = requests.get("%s/crumbIssuer/api/json" % jenkins_url,
Jakub Josefe13e2e72016-12-08 13:41:19 +010072 auth=(jenkins_user, jenkins_password) if jenkins_user else None)
Jakub Josef8e7385e2016-12-07 21:20:34 +010073 if tokenReq.status_code == 200:
74 return tokenReq.json()
Jakub Josefe13e2e72016-12-08 13:41:19 +010075 elif tokenReq.status_code == 404:
76 # 404 means CSRF security is disabled, so api crumb is not necessary
77 return None
Jakub Josef8e7385e2016-12-07 21:20:34 +010078 else:
Jakub Josefe13e2e72016-12-08 13:41:19 +010079 raise Exception("Cannot obtain Jenkins API crumb. Status code: %s. Text: %s" %
80 tokenReq.status_code, tokenReq.text)
Jakub Josef8e7385e2016-12-07 21:20:34 +010081
82
83
84def get_jenkins_auth():
85 """
86 Get jenkins params from salt
87 """
88 jenkins_url = __salt__['config.get']('jenkins.url') or \
89 __salt__['config.get']('jenkins:url') or \
90 __salt__['pillar.get']('jenkins.url')
91
92 jenkins_user = __salt__['config.get']('jenkins.user') or \
93 __salt__['config.get']('jenkins:user') or \
94 __salt__['pillar.get']('jenkins.user')
95
96 jenkins_password = __salt__['config.get']('jenkins.password') or \
97 __salt__['config.get']('jenkins:password') or \
98 __salt__['pillar.get']('jenkins.password')
99
100 return (jenkins_url, jenkins_user, jenkins_password)
101
102
103def encode_password(password):
104 """
105 Hash plaintext password by jenkins bcrypt algorithm
106 :param password: plain-text password
107 :returns: bcrypt hashed password
108 """
109 if isinstance(password, str):
110 return bcrypt.hashpw(password, bcrypt.gensalt(prefix=b"2a"))