blob: aa54efd84b566bea1dfb3b9f9448240a41b864e1 [file] [log] [blame]
Jakub Josef123be7a2016-12-12 16:02:36 +01001import logging
2logger = logging.getLogger(__name__)
3
4
5create_node_groovy = u"""\
6import jenkins.model.*
7import hudson.model.*
8import hudson.slaves.*
9import hudson.plugins.sshslaves.*
Jakub Josef123be7a2016-12-12 16:02:36 +010010
Jakub Josef98123ab2016-12-14 14:05:01 +010011def result=Jenkins.instance.slaves.find{{
Jakub Josef1bb7f442017-05-26 17:02:56 +020012 it.name == '{name}' &&
Jakub Josef98123ab2016-12-14 14:05:01 +010013 it.numExecutors == {num_executors} &&
Jakub Josef1bb7f442017-05-26 17:02:56 +020014 it.nodeDescription == "{desc}" &&
15 it.remoteFS == "{remote_home}" &&
16 it.labelString == "{label}" &&
17 it.mode == Node.Mode.{node_mode} &&
Jakub Josef98123ab2016-12-14 14:05:01 +010018 it.launcher.getClass().getName().equals({launcher}.getClass().getName()) &&
19 it.retentionStrategy.getClass().getName().equals(new hudson.slaves.RetentionStrategy.{ret_strategy}().getClass().getName())}}
20if(result){{
21 print("EXISTS")
22}}else{{
Jakub Josef123be7a2016-12-12 16:02:36 +010023 Slave slave = new DumbSlave(
24 "{name}",
25 "{desc}",
26 "{remote_home}",
27 "{num_executors}",
28 Node.Mode.{node_mode},
29 "{label}",
30 {launcher},
31 new RetentionStrategy.{ret_strategy}(),
32 new LinkedList())
33 Jenkins.instance.addNode(slave)
Jakub Josef98123ab2016-12-14 14:05:01 +010034 print("CREATED")
35}}
Jakub Josef123be7a2016-12-12 16:02:36 +010036""" # noqa
37
38create_lbl_groovy = u"""\
39hudson = hudson.model.Hudson.instance
40updated = false
41hudson.slaves.find {{ slave -> slave.nodeName.equals("{name}")
42 if({append}){{
43 slave.labelString = slave.labelString + " " + "{lbl_text}"
44 }}else{{
45 slave.labelString = "{lbl_text}"
46 }}
47 updated = true
48 print "{lbl_text}"
49}}
50if(!updated){{
51 print "FAILED"
52}}
53hudson.save()
54""" # noqa
55
Jakub Josef1bb7f442017-05-26 17:02:56 +020056configure_master_groovy = u"""\
57def instance = Jenkins.instance
58def changed = false
59
60if(Jenkins.instance.numExecutors != {num_executors}){{
61 Jenkins.instance.setNumExecutors({num_executors})
62 changed = true
63}}
64
65if(!Jenkins.instance.mode.name.equals(new String("{node_mode}").toUpperCase())){{
66 Jenkins.instance.setMode(Node.Mode.{node_mode})
67 changed = true
68}}
69
70if(!Jenkins.instance.labelString.equals("{labels}")){{
71 Jenkins.instance.setLabelString("{labels}")
72 changed = true
73}}
74if(changed){{
75 Jenkins.instance.save()
Jakub Josef7339a002017-06-09 11:33:02 +020076 print("CREATED")
Jakub Josef1bb7f442017-05-26 17:02:56 +020077}}else{{
Jakub Josef58787542017-06-08 16:59:47 +020078 print("EXISTS")
Jakub Josef1bb7f442017-05-26 17:02:56 +020079}}
80"""
Jakub Josef123be7a2016-12-12 16:02:36 +010081
Ilya Kharin3d8bffe2017-06-22 17:40:31 +040082
83def __virtual__():
84 '''
85 Only load if jenkins_common module exist.
86 '''
87 if 'jenkins_common.call_groovy_script' not in __salt__:
88 return (
89 False,
90 'The jenkins_node state module cannot be loaded: '
91 'jenkins_common not found')
92 return True
93
94
Jakub Josef123be7a2016-12-12 16:02:36 +010095def label(name, lbl_text, append=False):
96 """
97 Jenkins node label state method
98
99 :param name: node name
100 :param lbl_text: label text
101 :returns: salt-specified state dict
102 """
103 test = __opts__['test'] # noqa
104 ret = {
105 'name': name,
106 'changes': {},
107 'result': False,
108 'comment': '',
109 }
110 result = False
111 if test:
112 status = 'CREATED'
113 ret['changes'][name] = status
114 ret['comment'] = 'Label %s %s' % (name, status.lower())
115 else:
116 call_result = __salt__['jenkins_common.call_groovy_script'](
117 create_lbl_groovy, {'name': name, 'lbl_text': lbl_text, 'append': "true" if append else "false"})
118 if call_result["code"] == 200 and call_result["msg"].strip() == lbl_text:
119 status = "CREATED"
120 ret['changes'][name] = status
121 ret['comment'] = 'Label %s %s ' % (name, status.lower())
122 result = True
123 else:
124 status = 'FAILED'
125 logger.error(
126 "Jenkins label API call failure: %s", call_result["msg"])
127 ret['comment'] = 'Jenkins label API call failure: %s' % (
128 call_result["msg"])
129 ret['result'] = None if test else result
130 return ret
131
132
Jakub Josef98123ab2016-12-14 14:05:01 +0100133def present(name, remote_home, launcher, num_executors="1", node_mode="Normal", desc="", labels=[], ret_strategy="Always"):
Jakub Josef123be7a2016-12-12 16:02:36 +0100134 """
135 Jenkins node state method
136
137 :param name: node name
138 :param remote_home: node remote home path
139 :param launcher: launcher dict with type, name, port, username, password
140 :param num_executors: number of node executurs (optional, default 1)
141 :param node_mode: node mode (optional, default Normal)
Jakub Josef98123ab2016-12-14 14:05:01 +0100142 :param desc: node description (optional)
143 :param labels: node labels list (optional)
Jakub Josef123be7a2016-12-12 16:02:36 +0100144 :param ret_strategy: node retention strategy from RetentionStrategy class
145 :returns: salt-specified state dict
146 """
147 test = __opts__['test'] # noqa
148 ret = {
149 'name': name,
150 'changes': {},
151 'result': False,
152 'comment': '',
153 }
154 result = False
155 if test:
156 status = 'CREATED'
157 ret['changes'][name] = status
158 ret['comment'] = 'Node %s %s' % (name, status.lower())
159 else:
Jakub Josef98123ab2016-12-14 14:05:01 +0100160 label_string = " ".join(labels)
161 launcher_string = "new hudson.slaves.JNLPLauncher()"
Jakub Josef123be7a2016-12-12 16:02:36 +0100162 if launcher:
163 if launcher["type"] == "ssh":
Jakub Josef98123ab2016-12-14 14:05:01 +0100164 launcher_string = 'new hudson.plugins.sshslaves.SSHLauncher("{}",{},"{}","{}","","","","","")'.format(
Jakub Josef123be7a2016-12-12 16:02:36 +0100165 launcher["host"], launcher["port"], launcher["username"], launcher["password"])
166 elif launcher["type"] == "jnlp":
Jakub Josef98123ab2016-12-14 14:05:01 +0100167 launcher_string = "new hudson.slaves.JNLPLauncher()"
Jakub Josef123be7a2016-12-12 16:02:36 +0100168
169 call_result = __salt__['jenkins_common.call_groovy_script'](
170 create_node_groovy,
171 {"name": name,
Jakub Josef95ad9802017-01-17 15:59:00 +0100172 "desc": desc if desc else "",
173 "label": label_string if label_string else "",
174 "remote_home": remote_home if remote_home else "",
175 "num_executors": num_executors if num_executors else "1",
Jakub Josef123be7a2016-12-12 16:02:36 +0100176 "launcher": launcher_string,
177 "node_mode": node_mode.upper(),
Jakub Josef95ad9802017-01-17 15:59:00 +0100178 "ret_strategy": ret_strategy if ret_strategy else "Always"})
Jakub Josef98123ab2016-12-14 14:05:01 +0100179 if call_result["code"] == 200 and call_result["msg"] in ["CREATED", "EXISTS"]:
180 status = call_result["msg"]
181 if call_result["msg"] == "CREATED":
182 ret['changes'][name] = status
Jakub Josef123be7a2016-12-12 16:02:36 +0100183 ret['comment'] = 'Node %s %s' % (name, status.lower())
184 result = True
185 else:
186 status = 'FAILED'
187 logger.error(
188 "Jenkins node API call failure: %s", call_result["msg"])
189 ret['comment'] = 'Jenkins node API call failure: %s' % (
190 call_result["msg"])
191 ret['result'] = None if test else result
192 return ret
Jakub Josef1bb7f442017-05-26 17:02:56 +0200193
Jakub Josefd2a62032017-06-06 17:53:21 +0200194
195def setup_master(name, num_executors="1", node_mode="Normal", labels=[]):
Jakub Josef1bb7f442017-05-26 17:02:56 +0200196 """
197 Jenkins setup master state method
198
199 :param name: node name (master)
200 :param num_executors: number of executors (optional, default 1)
201 :param node_mode: Node mode (Normal or Exclusive)
Jakub Josefd2a62032017-06-06 17:53:21 +0200202 :param labels: array of labels
Jakub Josef1bb7f442017-05-26 17:02:56 +0200203 :returns: salt-specified state dict
204 """
205 test = __opts__['test'] # noqa
206 ret = {
207 'name': name,
208 'changes': {},
209 'result': False,
210 'comment': '',
211 }
212 result = False
213 if test:
214 status = 'CREATED'
215 ret['changes'][name] = status
Jakub Josefd2a62032017-06-06 17:53:21 +0200216 ret['comment'] = 'Master node %s' % (status.lower())
Jakub Josef1bb7f442017-05-26 17:02:56 +0200217 else:
218 call_result = __salt__['jenkins_common.call_groovy_script'](
Jakub Josef7339a002017-06-09 11:33:02 +0200219 configure_master_groovy, {'num_executors': num_executors, 'labels': " ".join(labels), 'node_mode': node_mode.upper()})
Jakub Josef1bb7f442017-05-26 17:02:56 +0200220 if call_result["code"] == 200 and call_result["msg"] in ["CREATED", "EXISTS"]:
Jakub Josef58787542017-06-08 16:59:47 +0200221 status = call_result["msg"]
222 if status == "CREATED":
223 ret['changes'][name] = status
224 ret['comment'] = 'Master node configuration %s ' % (status.lower())
Jakub Josef1bb7f442017-05-26 17:02:56 +0200225 result = True
226 else:
227 status = 'FAILED'
228 logger.error(
229 "Jenkins master configure API call failure: %s", call_result["msg"])
230 ret['comment'] = 'Jenkins master configure API call failure: %s' % (
231 call_result["msg"])
232 ret['result'] = None if test else result
Jakub Josefd2a62032017-06-06 17:53:21 +0200233 return ret