Jakub Josef | e380798 | 2016-12-15 11:54:51 +0100 | [diff] [blame] | 1 | # -*- coding: utf-8 -*- |
| 2 | |
| 3 | # Import Python libs |
| 4 | from __future__ import absolute_import |
| 5 | import difflib |
| 6 | import logging |
| 7 | |
| 8 | # Import Salt libs |
| 9 | import salt.ext.six as six |
| 10 | import salt.utils |
| 11 | |
| 12 | # Import XML parser |
| 13 | import xml.etree.ElementTree as ET |
| 14 | |
| 15 | log = logging.getLogger(__name__) |
| 16 | |
| 17 | |
| 18 | def _elements_equal(e1, e2): |
| 19 | if e1.tag != e2.tag: |
| 20 | return False |
| 21 | if e1.text != e2.text: |
| 22 | return False |
| 23 | if e1.tail != e2.tail: |
| 24 | return False |
| 25 | if e1.attrib != e2.attrib: |
| 26 | return False |
| 27 | if len(e1) != len(e2): |
| 28 | return False |
| 29 | return all(_elements_equal(c1, c2) for c1, c2 in zip(e1, e2)) |
| 30 | |
| 31 | |
| 32 | def present(name, |
| 33 | config=None, |
| 34 | **kwargs): |
| 35 | ''' |
| 36 | Ensure the job is present in the Jenkins |
| 37 | configured jobs |
| 38 | name |
| 39 | The unique name for the Jenkins job |
| 40 | config |
| 41 | The Salt URL for the file to use for |
| 42 | configuring the job. |
| 43 | ''' |
| 44 | |
| 45 | ret = {'name': name, |
| 46 | 'result': True, |
| 47 | 'changes': {}, |
| 48 | 'comment': ['Job {0} is up to date.'.format(name)]} |
| 49 | |
| 50 | _job_exists = __salt__['jenkins.job_exists'](name) |
| 51 | |
| 52 | if _job_exists: |
| 53 | _current_job_config = __salt__['jenkins.get_job_config'](name) |
| 54 | buf = six.moves.StringIO(_current_job_config) |
| 55 | oldXML = ET.fromstring(buf.read()) |
| 56 | |
| 57 | cached_source_path = __salt__['cp.cache_file'](config, __env__) |
| 58 | with salt.utils.fopen(cached_source_path) as _fp: |
| 59 | newXML = ET.fromstring(_fp.read()) |
| 60 | if not _elements_equal(oldXML, newXML): |
| 61 | diff = difflib.unified_diff( |
Jakub Josef | 929312c | 2016-12-20 11:48:56 +0100 | [diff] [blame^] | 62 | ET.tostringlist(oldXML, encoding='utf8', method='xml'), |
| 63 | ET.tostringlist(newXML, encoding='utf8', method='xml'), lineterm='') |
Jakub Josef | e380798 | 2016-12-15 11:54:51 +0100 | [diff] [blame] | 64 | __salt__['jenkins.update_job'](name, config, __env__) |
| 65 | ret['changes'] = ''.join(diff) |
| 66 | ret['comment'].append('Job {0} updated.'.format(name)) |
| 67 | |
| 68 | else: |
| 69 | cached_source_path = __salt__['cp.cache_file'](config, __env__) |
| 70 | with salt.utils.fopen(cached_source_path) as _fp: |
| 71 | new_config_xml = _fp.read() |
| 72 | |
| 73 | __salt__['jenkins.create_job'](name, config, __env__) |
| 74 | |
| 75 | buf = six.moves.StringIO(new_config_xml) |
| 76 | _current_job_config = buf.readlines() |
| 77 | |
| 78 | diff = difflib.unified_diff('', buf, lineterm='') |
| 79 | ret['changes'] = ''.join(diff) |
| 80 | ret['comment'].append('Job {0} added.'.format(name)) |
| 81 | |
| 82 | ret['comment'] = '\n'.join(ret['comment']) |
| 83 | return ret |
| 84 | |
| 85 | |
| 86 | def absent(name, |
| 87 | **kwargs): |
| 88 | ''' |
| 89 | Ensure the job is present in the Jenkins |
| 90 | configured jobs |
| 91 | |
| 92 | name |
| 93 | The name of the Jenkins job to remove. |
| 94 | |
| 95 | ''' |
| 96 | |
| 97 | ret = {'name': name, |
| 98 | 'result': True, |
| 99 | 'changes': {}, |
| 100 | 'comment': []} |
| 101 | |
| 102 | _job_exists = __salt__['jenkins.job_exists'](name) |
| 103 | |
| 104 | if _job_exists: |
| 105 | __salt__['jenkins.delete_job'](name) |
| 106 | ret['comment'] = 'Job {0} deleted.'.format(name) |
| 107 | else: |
| 108 | ret['comment'] = 'Job {0} already absent.'.format(name) |
| 109 | return ret |