Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 1 | import logging |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 2 | |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 3 | logger = logging.getLogger(__name__) |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 4 | |
| 5 | create_node_groovy = u"""\ |
| 6 | import jenkins.model.* |
| 7 | import hudson.model.* |
| 8 | import hudson.slaves.* |
| 9 | import hudson.plugins.sshslaves.* |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 10 | |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 11 | def result=Jenkins.instance.slaves.find{ |
Jakub Josef | 1bb7f44 | 2017-05-26 17:02:56 +0200 | [diff] [blame] | 12 | it.name == '{name}' && |
Jakub Josef | 98123ab | 2016-12-14 14:05:01 +0100 | [diff] [blame] | 13 | it.numExecutors == {num_executors} && |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 14 | it.nodeDescription == "${desc}" && |
| 15 | it.remoteFS == "${remote_home}" && |
| 16 | it.labelString == "${label}" && |
Jakub Josef | 1bb7f44 | 2017-05-26 17:02:56 +0200 | [diff] [blame] | 17 | it.mode == Node.Mode.{node_mode} && |
Jakub Josef | 98123ab | 2016-12-14 14:05:01 +0100 | [diff] [blame] | 18 | it.launcher.getClass().getName().equals({launcher}.getClass().getName()) && |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 19 | it.retentionStrategy.getClass().getName().equals(new hudson.slaves.RetentionStrategy.${ret_strategy}().getClass().getName())} |
| 20 | if(result){ |
Jakub Josef | 98123ab | 2016-12-14 14:05:01 +0100 | [diff] [blame] | 21 | print("EXISTS") |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 22 | }else{ |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 23 | Slave slave = new DumbSlave( |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 24 | "${name}", |
| 25 | "${desc}", |
| 26 | "${remote_home}", |
| 27 | "${num_executors}", |
| 28 | Node.Mode.${node_mode}, |
| 29 | "${label}", |
| 30 | ${launcher}, |
| 31 | new RetentionStrategy.${ret_strategy}(), |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 32 | new LinkedList()) |
| 33 | Jenkins.instance.addNode(slave) |
Jakub Josef | 98123ab | 2016-12-14 14:05:01 +0100 | [diff] [blame] | 34 | print("CREATED") |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 35 | } |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 36 | """ # noqa |
| 37 | |
| 38 | create_lbl_groovy = u"""\ |
| 39 | hudson = hudson.model.Hudson.instance |
| 40 | updated = false |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 41 | hudson.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 | } |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 47 | updated = true |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 48 | print "${lbl_text}" |
| 49 | } |
| 50 | if(!updated){ |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 51 | print "FAILED" |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 52 | } |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 53 | hudson.save() |
| 54 | """ # noqa |
| 55 | |
Jakub Josef | 1bb7f44 | 2017-05-26 17:02:56 +0200 | [diff] [blame] | 56 | configure_master_groovy = u"""\ |
| 57 | def instance = Jenkins.instance |
| 58 | def changed = false |
| 59 | |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 60 | if(Jenkins.instance.numExecutors != ${num_executors}){ |
| 61 | Jenkins.instance.setNumExecutors(${num_executors}) |
Jakub Josef | 1bb7f44 | 2017-05-26 17:02:56 +0200 | [diff] [blame] | 62 | changed = true |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 63 | } |
Jakub Josef | 1bb7f44 | 2017-05-26 17:02:56 +0200 | [diff] [blame] | 64 | |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 65 | if(!Jenkins.instance.mode.name.equals(new String("${node_mode}").toUpperCase())){ |
| 66 | Jenkins.instance.setMode(Node.Mode.${node_mode}) |
Jakub Josef | 1bb7f44 | 2017-05-26 17:02:56 +0200 | [diff] [blame] | 67 | changed = true |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 68 | } |
Jakub Josef | 1bb7f44 | 2017-05-26 17:02:56 +0200 | [diff] [blame] | 69 | |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 70 | if(!Jenkins.instance.labelString.equals("${labels}")){ |
| 71 | Jenkins.instance.setLabelString("${labels}") |
Jakub Josef | 1bb7f44 | 2017-05-26 17:02:56 +0200 | [diff] [blame] | 72 | changed = true |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 73 | } |
| 74 | if(changed){ |
Jakub Josef | 1bb7f44 | 2017-05-26 17:02:56 +0200 | [diff] [blame] | 75 | Jenkins.instance.save() |
Jakub Josef | 7339a00 | 2017-06-09 11:33:02 +0200 | [diff] [blame] | 76 | print("CREATED") |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 77 | }else{ |
Jakub Josef | 5878754 | 2017-06-08 16:59:47 +0200 | [diff] [blame] | 78 | print("EXISTS") |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 79 | } |
Jakub Josef | 1bb7f44 | 2017-05-26 17:02:56 +0200 | [diff] [blame] | 80 | """ |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 81 | |
Ilya Kharin | 3d8bffe | 2017-06-22 17:40:31 +0400 | [diff] [blame] | 82 | |
| 83 | def __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 Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 95 | def 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"}) |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 118 | if call_result["code"] == 200 and call_result["msg"].strip( |
| 119 | ) == lbl_text: |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 120 | status = "CREATED" |
| 121 | ret['changes'][name] = status |
| 122 | ret['comment'] = 'Label %s %s ' % (name, status.lower()) |
| 123 | result = True |
| 124 | else: |
| 125 | status = 'FAILED' |
| 126 | logger.error( |
| 127 | "Jenkins label API call failure: %s", call_result["msg"]) |
| 128 | ret['comment'] = 'Jenkins label API call failure: %s' % ( |
| 129 | call_result["msg"]) |
| 130 | ret['result'] = None if test else result |
| 131 | return ret |
| 132 | |
| 133 | |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 134 | def present(name, remote_home, launcher, num_executors="1", |
| 135 | node_mode="Normal", desc="", labels=[], ret_strategy="Always"): |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 136 | """ |
| 137 | Jenkins node state method |
| 138 | |
| 139 | :param name: node name |
| 140 | :param remote_home: node remote home path |
| 141 | :param launcher: launcher dict with type, name, port, username, password |
| 142 | :param num_executors: number of node executurs (optional, default 1) |
| 143 | :param node_mode: node mode (optional, default Normal) |
Jakub Josef | 98123ab | 2016-12-14 14:05:01 +0100 | [diff] [blame] | 144 | :param desc: node description (optional) |
| 145 | :param labels: node labels list (optional) |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 146 | :param ret_strategy: node retention strategy from RetentionStrategy class |
| 147 | :returns: salt-specified state dict |
| 148 | """ |
| 149 | test = __opts__['test'] # noqa |
| 150 | ret = { |
| 151 | 'name': name, |
| 152 | 'changes': {}, |
| 153 | 'result': False, |
| 154 | 'comment': '', |
| 155 | } |
| 156 | result = False |
| 157 | if test: |
| 158 | status = 'CREATED' |
| 159 | ret['changes'][name] = status |
| 160 | ret['comment'] = 'Node %s %s' % (name, status.lower()) |
| 161 | else: |
Jakub Josef | 98123ab | 2016-12-14 14:05:01 +0100 | [diff] [blame] | 162 | label_string = " ".join(labels) |
| 163 | launcher_string = "new hudson.slaves.JNLPLauncher()" |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 164 | if launcher: |
| 165 | if launcher["type"] == "ssh": |
Jakub Josef | 98123ab | 2016-12-14 14:05:01 +0100 | [diff] [blame] | 166 | launcher_string = 'new hudson.plugins.sshslaves.SSHLauncher("{}",{},"{}","{}","","","","","")'.format( |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 167 | launcher["host"], launcher["port"], launcher["username"], launcher["password"]) |
| 168 | elif launcher["type"] == "jnlp": |
Jakub Josef | 98123ab | 2016-12-14 14:05:01 +0100 | [diff] [blame] | 169 | launcher_string = "new hudson.slaves.JNLPLauncher()" |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 170 | |
| 171 | call_result = __salt__['jenkins_common.call_groovy_script']( |
| 172 | create_node_groovy, |
| 173 | {"name": name, |
Jakub Josef | 95ad980 | 2017-01-17 15:59:00 +0100 | [diff] [blame] | 174 | "desc": desc if desc else "", |
| 175 | "label": label_string if label_string else "", |
| 176 | "remote_home": remote_home if remote_home else "", |
| 177 | "num_executors": num_executors if num_executors else "1", |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 178 | "launcher": launcher_string, |
| 179 | "node_mode": node_mode.upper(), |
Jakub Josef | 95ad980 | 2017-01-17 15:59:00 +0100 | [diff] [blame] | 180 | "ret_strategy": ret_strategy if ret_strategy else "Always"}) |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 181 | if call_result["code"] == 200 and call_result["msg"] in [ |
| 182 | "CREATED", "EXISTS"]: |
Jakub Josef | 98123ab | 2016-12-14 14:05:01 +0100 | [diff] [blame] | 183 | status = call_result["msg"] |
| 184 | if call_result["msg"] == "CREATED": |
| 185 | ret['changes'][name] = status |
Jakub Josef | 123be7a | 2016-12-12 16:02:36 +0100 | [diff] [blame] | 186 | ret['comment'] = 'Node %s %s' % (name, status.lower()) |
| 187 | result = True |
| 188 | else: |
| 189 | status = 'FAILED' |
| 190 | logger.error( |
| 191 | "Jenkins node API call failure: %s", call_result["msg"]) |
| 192 | ret['comment'] = 'Jenkins node API call failure: %s' % ( |
| 193 | call_result["msg"]) |
| 194 | ret['result'] = None if test else result |
| 195 | return ret |
Jakub Josef | 1bb7f44 | 2017-05-26 17:02:56 +0200 | [diff] [blame] | 196 | |
Jakub Josef | d2a6203 | 2017-06-06 17:53:21 +0200 | [diff] [blame] | 197 | |
| 198 | def setup_master(name, num_executors="1", node_mode="Normal", labels=[]): |
Jakub Josef | 1bb7f44 | 2017-05-26 17:02:56 +0200 | [diff] [blame] | 199 | """ |
| 200 | Jenkins setup master state method |
| 201 | |
| 202 | :param name: node name (master) |
| 203 | :param num_executors: number of executors (optional, default 1) |
| 204 | :param node_mode: Node mode (Normal or Exclusive) |
Jakub Josef | d2a6203 | 2017-06-06 17:53:21 +0200 | [diff] [blame] | 205 | :param labels: array of labels |
Jakub Josef | 1bb7f44 | 2017-05-26 17:02:56 +0200 | [diff] [blame] | 206 | :returns: salt-specified state dict |
| 207 | """ |
| 208 | test = __opts__['test'] # noqa |
| 209 | ret = { |
| 210 | 'name': name, |
| 211 | 'changes': {}, |
| 212 | 'result': False, |
| 213 | 'comment': '', |
| 214 | } |
| 215 | result = False |
| 216 | if test: |
| 217 | status = 'CREATED' |
| 218 | ret['changes'][name] = status |
Jakub Josef | d2a6203 | 2017-06-06 17:53:21 +0200 | [diff] [blame] | 219 | ret['comment'] = 'Master node %s' % (status.lower()) |
Jakub Josef | 1bb7f44 | 2017-05-26 17:02:56 +0200 | [diff] [blame] | 220 | else: |
| 221 | call_result = __salt__['jenkins_common.call_groovy_script']( |
Jakub Josef | 7339a00 | 2017-06-09 11:33:02 +0200 | [diff] [blame] | 222 | configure_master_groovy, {'num_executors': num_executors, 'labels': " ".join(labels), 'node_mode': node_mode.upper()}) |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame^] | 223 | if call_result["code"] == 200 and call_result["msg"] in [ |
| 224 | "CREATED", "EXISTS"]: |
Jakub Josef | 5878754 | 2017-06-08 16:59:47 +0200 | [diff] [blame] | 225 | status = call_result["msg"] |
| 226 | if status == "CREATED": |
| 227 | ret['changes'][name] = status |
| 228 | ret['comment'] = 'Master node configuration %s ' % (status.lower()) |
Jakub Josef | 1bb7f44 | 2017-05-26 17:02:56 +0200 | [diff] [blame] | 229 | result = True |
| 230 | else: |
| 231 | status = 'FAILED' |
| 232 | logger.error( |
| 233 | "Jenkins master configure API call failure: %s", call_result["msg"]) |
| 234 | ret['comment'] = 'Jenkins master configure API call failure: %s' % ( |
| 235 | call_result["msg"]) |
| 236 | ret['result'] = None if test else result |
Jakub Josef | d2a6203 | 2017-06-06 17:53:21 +0200 | [diff] [blame] | 237 | return ret |