Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 1 | import logging |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 2 | |
Jakub Josef | 7d9fce3 | 2017-03-24 16:46:56 +0100 | [diff] [blame] | 3 | from json import dumps |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 4 | |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 5 | logger = logging.getLogger(__name__) |
| 6 | |
| 7 | add_view_groovy = """\ |
Jakub Josef | e74e7a6 | 2017-04-06 11:50:55 +0200 | [diff] [blame] | 8 | import java.util.stream.Collectors |
| 9 | import org.jenkinsci.plugins.categorizedview.CategorizedJobsView |
| 10 | import org.jenkinsci.plugins.categorizedview.GroupingRule |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 11 | view = Jenkins.instance.getView("${view_name}") |
| 12 | if(view){ |
| 13 | if(view.getClass().getName().equals("hudson.model.ListView")){ |
| 14 | include_regex="${include_regex}" |
| 15 | if(include_regex != "" && !view.getIncludeRegex().equals(include_regex)){ |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 16 | view.setIncludeRegex(include_regex) |
| 17 | print("ADDED/CHANGED") |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 18 | }else{ |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 19 | print("EXISTS") |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 20 | } |
| 21 | }else if(view.getClass().getName().equals("org.jenkinsci.plugins.categorizedview.CategorizedJobsView")){ |
Jakub Josef | 7d9fce3 | 2017-03-24 16:46:56 +0100 | [diff] [blame] | 22 | def jsonSlurper = new groovy.json.JsonSlurper() |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 23 | def inputCategories = jsonSlurper.parseText('${categories_string}') |
| 24 | def groupRegexes = inputCategories.stream().map{e -> e["group_regex"]}.collect(Collectors.toList()) |
| 25 | def namingRules = inputCategories.stream().map{e -> e["naming_rule"]}.collect(Collectors.toList()) |
Jakub Josef | 7d9fce3 | 2017-03-24 16:46:56 +0100 | [diff] [blame] | 26 | def actualCategories = view.categorizationCriteria |
| 27 | def equals = !actualCategories.isEmpty() |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 28 | def include_regex="${include_regex}" |
| 29 | if(include_regex != "" && !view.getIncludeRegex().equals(include_regex)){ |
Jakub Josef | 7d9fce3 | 2017-03-24 16:46:56 +0100 | [diff] [blame] | 30 | view.setIncludeRegex(include_regex) |
| 31 | equals = false |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 32 | } |
| 33 | for(int i=0;i<actualCategories.size();i++){ |
| 34 | if(!groupRegexes.contains(actualCategories[i].groupRegex) || !namingRules.contains(actualCategories[i].namingRule)){ |
Jakub Josef | 7d9fce3 | 2017-03-24 16:46:56 +0100 | [diff] [blame] | 35 | equals = false |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 36 | } |
| 37 | } |
| 38 | if(!equals){ |
Jakub Josef | 7d9fce3 | 2017-03-24 16:46:56 +0100 | [diff] [blame] | 39 | view.categorizationCriteria.clear() |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 40 | for(int i=0;i<inputCategories.size();i++){ |
Jakub Josef | 7d9fce3 | 2017-03-24 16:46:56 +0100 | [diff] [blame] | 41 | view.categorizationCriteria.add(new GroupingRule(inputCategories[i].group_regex,inputCategories[i].naming_rule)) |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 42 | } |
Jakub Josef | 7d9fce3 | 2017-03-24 16:46:56 +0100 | [diff] [blame] | 43 | print("ADDED/CHANGED") |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 44 | }else{ |
Jakub Josef | 7d9fce3 | 2017-03-24 16:46:56 +0100 | [diff] [blame] | 45 | print("EXISTS") |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 46 | } |
| 47 | }else{ |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 48 | print("EXISTS") |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 49 | } |
| 50 | }else{ |
| 51 | try{ |
| 52 | ${view_def} |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 53 | Jenkins.instance.addView(view) |
| 54 | print("ADDED/CHANGED") |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 55 | }catch(Exception e){ |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 56 | print("FAILED") |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 57 | } |
| 58 | } |
Jakub Josef | 7d9fce3 | 2017-03-24 16:46:56 +0100 | [diff] [blame] | 59 | """ # noqa |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 60 | |
| 61 | remove_view_groovy = """\ |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 62 | view = Jenkins.instance.getView("${view_name}") |
| 63 | if(view){ |
| 64 | try{ |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 65 | Jenkins.instance.deleteView(view) |
| 66 | print("REMOVED") |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 67 | }catch(Exception e){ |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 68 | print("FAILED") |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 69 | } |
| 70 | }else{ |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 71 | print("NOT PRESENT") |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 72 | } |
Jakub Josef | 7d9fce3 | 2017-03-24 16:46:56 +0100 | [diff] [blame] | 73 | """ # noqa |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 74 | |
| 75 | |
Ilya Kharin | 3d8bffe | 2017-06-22 17:40:31 +0400 | [diff] [blame] | 76 | def __virtual__(): |
| 77 | ''' |
| 78 | Only load if jenkins_common module exist. |
| 79 | ''' |
| 80 | if 'jenkins_common.call_groovy_script' not in __salt__: |
| 81 | return ( |
| 82 | False, |
| 83 | 'The jenkins_view state module cannot be loaded: ' |
| 84 | 'jenkins_common not found') |
| 85 | return True |
| 86 | |
| 87 | |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 88 | def present(name, type="ListView", **kwargs): |
| 89 | """ |
| 90 | Jenkins view present state method |
| 91 | |
| 92 | :param name: view name |
| 93 | :param type: view type (default ListView) |
| 94 | :returns: salt-specified state dict |
| 95 | """ |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 96 | return _plugin_call(name, type, add_view_groovy, [ |
| 97 | "ADDED/CHANGED", "EXISTS"], **kwargs) |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 98 | |
| 99 | |
| 100 | def absent(name, **kwargs): |
| 101 | """ |
| 102 | Jenkins view absent state method |
| 103 | |
| 104 | :param name: view name |
| 105 | :returns: salt-specified state dict |
| 106 | """ |
Adam Tengler | 70763e0 | 2017-08-21 16:50:32 +0000 | [diff] [blame] | 107 | return _plugin_call(name, None, remove_view_groovy, [ |
| 108 | "REMOVED", "NOT PRESENT"], **kwargs) |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 109 | |
| 110 | |
| 111 | def _plugin_call(name, type, template, success_msgs, **kwargs): |
| 112 | test = __opts__['test'] # noqa |
| 113 | ret = { |
| 114 | 'name': name, |
| 115 | 'changes': {}, |
| 116 | 'result': False, |
| 117 | 'comment': '', |
| 118 | } |
| 119 | result = False |
| 120 | if test: |
| 121 | status = success_msgs[0] |
| 122 | ret['changes'][name] = status |
| 123 | ret['comment'] = 'Jenkins view %s %s' % (name, status.lower()) |
| 124 | else: |
| 125 | view_def = "view = new {}(\"{}\")".format(type, name) |
| 126 | # handle view specific params |
| 127 | include_regex = kwargs.get('include_regex') |
Jakub Josef | 7d9fce3 | 2017-03-24 16:46:56 +0100 | [diff] [blame] | 128 | categories_string = "" |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 129 | if type == "ListView": |
| 130 | if include_regex: |
Jakub Josef | 7d9fce3 | 2017-03-24 16:46:56 +0100 | [diff] [blame] | 131 | view_def += "\nview.setIncludeRegex(\"{}\")".format( |
| 132 | include_regex) |
| 133 | if type == "CategorizedJobsView": |
| 134 | # add imports for categorized views |
Jakub Josef | 7d9fce3 | 2017-03-24 16:46:56 +0100 | [diff] [blame] | 135 | if include_regex: |
| 136 | view_def += "\nview.setIncludeRegex(\"{}\")".format( |
| 137 | include_regex) |
| 138 | categories = kwargs.get('categories', []) |
| 139 | for category in categories: |
| 140 | view_def += "\nview.categorizationCriteria.add(new GroupingRule(\"{}\", \"{}\"))".format( |
| 141 | category["group_regex"], category["naming_rule"]) |
| 142 | # create catogories string readable in groovy |
| 143 | categories_string = dumps(categories) |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 144 | |
| 145 | call_result = __salt__['jenkins_common.call_groovy_script']( |
Jakub Josef | 7d9fce3 | 2017-03-24 16:46:56 +0100 | [diff] [blame] | 146 | template, {"view_def": view_def, "view_name": name, "type": type if type else "", "include_regex": include_regex if include_regex else "", "categories_string": categories_string if categories_string else ""}) |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 147 | if call_result["code"] == 200 and call_result["msg"] in success_msgs: |
| 148 | status = call_result["msg"] |
| 149 | if status == success_msgs[0]: |
| 150 | ret['changes'][name] = status |
| 151 | ret['comment'] = 'Jenkins view %s %s' % (name, status.lower()) |
| 152 | result = True |
| 153 | else: |
| 154 | status = 'FAILED' |
| 155 | logger.error( |
| 156 | "Jenkins view API call failure: %s", call_result["msg"]) |
| 157 | ret['comment'] = 'Jenkins view API call failure: %s' % (call_result[ |
Jakub Josef | 7d9fce3 | 2017-03-24 16:46:56 +0100 | [diff] [blame] | 158 | "msg"]) |
Jakub Josef | 7bb17ab | 2017-01-12 14:52:53 +0100 | [diff] [blame] | 159 | ret['result'] = None if test else result |
| 160 | return ret |