blob: 98e8a707ff05133f3a5b00b9bdf5ada2c24b6ccb [file] [log] [blame]
Jakub Josef063a7532017-01-11 15:48:01 +01001import logging
Adam Tengler70763e02017-08-21 16:50:32 +00002
Jakub Josef063a7532017-01-11 15:48:01 +01003logger = logging.getLogger(__name__)
4
5set_ldap_groovy = """\
6import jenkins.model.*
7import hudson.security.*
8import org.jenkinsci.plugins.*
9
Adam Tengler70763e02017-08-21 16:50:32 +000010def server = '${server}'
11def rootDN = '${rootDN}'
12def userSearchBase = '${userSearchBase}'
13def userSearch = '${userSearch}'
14def groupSearchBase = '${groupSearchBase}'
15def managerDN = '${managerDN}'
16def managerPassword = '${managerPassword}'
Jakub Josef063a7532017-01-11 15:48:01 +010017boolean inhibitInferRootDN = {inhibitInferRootDN}
18
Adam Tengler70763e02017-08-21 16:50:32 +000019try{
Jakub Josef063a7532017-01-11 15:48:01 +010020ldapRealm = Class.forName("hudson.security.LDAPSecurityRealm").getConstructor(String.class, String.class, String.class, String.class, String.class, String.class, String.class, Boolean.TYPE)
21.newInstance(server, rootDN, userSearchBase, userSearch, groupSearchBase, managerDN, managerPassword, inhibitInferRootDN)
22Jenkins.instance.setSecurityRealm(ldapRealm)
23Jenkins.instance.save()
24print("SUCCESS")
Adam Tengler70763e02017-08-21 16:50:32 +000025}catch(ClassNotFoundException e){
Jakub Josef063a7532017-01-11 15:48:01 +010026 print("Cannot instantiate LDAPSecurityRealm, maybe ldap plugin not installed")
Adam Tengler70763e02017-08-21 16:50:32 +000027}
Jakub Josef063a7532017-01-11 15:48:01 +010028""" # noqa
29
30set_matrix_groovy = """\
31import jenkins.model.*
32import hudson.security.*
33import com.cloudbees.plugins.credentials.*
34
35def instance = Jenkins.getInstance()
Adam Tengler70763e02017-08-21 16:50:32 +000036try{
37def strategy = Class.forName("hudson.security.${matrix_class}").newInstance()
38${strategies}
Jakub Josef063a7532017-01-11 15:48:01 +010039instance.setAuthorizationStrategy(strategy)
40instance.save()
41print("SUCCESS")
Adam Tengler70763e02017-08-21 16:50:32 +000042}catch(ClassNotFoundException e){
43 print("Cannot instantiate ${matrix_class}, maybe auth-matrix plugin not installed")
44}
Jakub Josef0ee470e2017-01-17 11:46:58 +010045""" # noqa
Jakub Josef063a7532017-01-11 15:48:01 +010046
47
Ilya Kharin3d8bffe2017-06-22 17:40:31 +040048def __virtual__():
49 '''
50 Only load if jenkins_common module exist.
51 '''
52 if 'jenkins_common.call_groovy_script' not in __salt__:
53 return (
54 False,
55 'The jenkins_security state module cannot be loaded: '
56 'jenkins_common not found')
57 return True
58
59
Adam Tengler70763e02017-08-21 16:50:32 +000060def ldap(name, server, root_dn, user_search_base, manager_dn, manager_password,
61 user_search="", group_search_base="", inhibit_infer_root_dn=False):
Jakub Josef063a7532017-01-11 15:48:01 +010062 """
63 Jenkins ldap state method
64
65 :param name: ldap state name
Andrey6606be02017-08-02 17:09:42 -050066 :param server: ldap server host
Jakub Josef063a7532017-01-11 15:48:01 +010067 :param root_dn: root domain names
68 :param user_search_base:
69 :param manager_dn:
70 :param manager_password:
71 :param user_search: optional, default empty string
72 :param group_search_base: optional, default empty string
73 :param inhibit_infer_root_dn: optional, default false
74 :returns: salt-specified state dict
75 """
76 test = __opts__['test'] # noqa
77 ret = {
78 'name': name,
79 'changes': {},
80 'result': False,
81 'comment': '',
82 }
83 result = False
Andrey6606be02017-08-02 17:09:42 -050084 if not server.startswith("ldap:") and not server.startswith("ldaps:"):
85 server = "ldap://{server}".format(server=server)
86
Jakub Josef063a7532017-01-11 15:48:01 +010087 if test:
88 status = 'CREATED'
89 ret['changes'][name] = status
90 ret['comment'] = 'LDAP setup %s %s' % (name, status.lower())
91 else:
92 call_result = __salt__['jenkins_common.call_groovy_script'](
93 set_ldap_groovy, {"name": name, "server": server, "rootDN": root_dn,
Jakub Josef95ad9802017-01-17 15:59:00 +010094 "userSearchBase": user_search_base if user_search_base else "",
95 "managerDN": manager_dn if manager_dn else "",
96 "managerPassword": manager_password if manager_password else "",
97 "userSearch": user_search if user_search else "",
Adam Tengler70763e02017-08-21 16:50:32 +000098 "groupSearchBase": group_search_base if group_search_base else "",
Jakub Josef95ad9802017-01-17 15:59:00 +010099 "inhibitInferRootDN": "true" if inhibit_infer_root_dn else "false"})
Jakub Josef063a7532017-01-11 15:48:01 +0100100 if call_result["code"] == 200 and call_result["msg"] == "SUCCESS":
101 status = call_result["msg"]
102 ret['changes'][name] = status
Jakub Josef0ee470e2017-01-17 11:46:58 +0100103 ret['comment'] = 'Jenkins LDAP setting %s %s' % (
104 name, status.lower())
Jakub Josef063a7532017-01-11 15:48:01 +0100105 result = True
106 else:
107 status = 'FAILED'
108 logger.error(
109 "Jenkins security API call failure: %s", call_result["msg"])
110 ret['comment'] = 'Jenkins security API call failure: %s' % (call_result[
Jakub Josef0ee470e2017-01-17 11:46:58 +0100111 "msg"])
Jakub Josef063a7532017-01-11 15:48:01 +0100112 ret['result'] = None if test else result
113 return ret
114
Jakub Josef0ee470e2017-01-17 11:46:58 +0100115
116def matrix(name, strategies, project_based=False):
Jakub Josef063a7532017-01-11 15:48:01 +0100117 """
118 Jenkins matrix security state method
119
120 :param name: ldap state name
Jakub Josef0ee470e2017-01-17 11:46:58 +0100121 :param strategies: dict with matrix strategies
122 :param procect_based: flag if we configuring
123 GlobalMatrix security or ProjectMatrix security
Jakub Josef063a7532017-01-11 15:48:01 +0100124 :returns: salt-specified state dict
125 """
126 test = __opts__['test'] # noqa
127 ret = {
128 'name': name,
129 'changes': {},
130 'result': False,
131 'comment': '',
132 }
133 result = False
134 if test:
135 status = 'CREATED'
136 ret['changes'][name] = status
137 ret['comment'] = 'LDAP setup %s %s' % (name, status.lower())
138 else:
139 call_result = __salt__['jenkins_common.call_groovy_script'](
Jakub Josef0ee470e2017-01-17 11:46:58 +0100140 set_matrix_groovy, {"strategies": _build_strategies(strategies),
141 "matrix_class": "ProjectMatrixAuthorizationStrategy" if project_based else "GlobalMatrixAuthorizationStrategy"})
Jakub Josef063a7532017-01-11 15:48:01 +0100142 if call_result["code"] == 200 and call_result["msg"] == "SUCCESS":
143 status = call_result["msg"]
144 ret['changes'][name] = status
Jakub Josef0ee470e2017-01-17 11:46:58 +0100145 ret['comment'] = 'Jenkins Matrix security setting %s %s' % (
146 name, status.lower())
Jakub Josef063a7532017-01-11 15:48:01 +0100147 result = True
148 else:
149 status = 'FAILED'
150 logger.error(
151 "Jenkins security API call failure: %s", call_result["msg"])
152 ret['comment'] = 'Jenkins security API call failure: %s' % (call_result[
Jakub Josef0ee470e2017-01-17 11:46:58 +0100153 "msg"])
Jakub Josef063a7532017-01-11 15:48:01 +0100154 ret['result'] = None if test else result
155 return ret
156
157
158def _build_strategies(permissions):
159 strategies_str = ""
Adam Tengler70763e02017-08-21 16:50:32 +0000160 for strategy in _to_strategies_list(
161 "strategy.add({},\"{}\")", _to_one_dict(permissions, "")):
Jakub Josef063a7532017-01-11 15:48:01 +0100162 strategies_str += "{}\n".format(strategy)
163 return strategies_str
164
165
166def _to_strategies_list(strategy_format, strategy_dict):
167 res = []
168 for key, value in strategy_dict.items():
169 if isinstance(value, list):
170 for user in value:
171 res.append(strategy_format.format(key, user))
172 else:
173 res.append(strategy_format.format(key, value))
174 return res
175
176
177def _to_one_dict(input_dict, input_key):
178 res = {}
179 for key, value in input_dict.items():
180 new_key = key if input_key == "" else "{}.{}".format(input_key, key)
181 if isinstance(value, dict):
182 res.update(_to_one_dict(value, new_key))
183 else:
184 res[new_key] = value
185 return res