1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
|
"""
Module for jenkinsapi views
"""
try:
from urllib import urlencode
except ImportError:
# Python3
from urllib.parse import urlencode
import logging
from jenkinsapi.jenkinsbase import JenkinsBase
from jenkinsapi.job import Job
from jenkinsapi.custom_exceptions import NotFound
log = logging.getLogger(__name__)
class View(JenkinsBase):
"""
View class
"""
def __init__(self, url, name, jenkins_obj):
self.name = name
self.jenkins_obj = jenkins_obj
JenkinsBase.__init__(self, url)
self.deleted = False
def __str__(self):
return self.name
def __getitem__(self, job_name):
assert isinstance(job_name, str)
api_url = self.python_api_url(self.get_job_url(job_name))
return Job(api_url, job_name, self.jenkins_obj)
def __contains__(self, job_name):
"""
True if view_name is the name of a defined view
"""
return job_name in self.keys()
def delete(self):
"""
Remove this view object
"""
url = "%s/doDelete" % self.baseurl
self.jenkins_obj.requester.post_and_confirm_status(url, data='')
self.jenkins_obj.poll()
self.deleted = True
def keys(self):
return self.get_job_dict().keys()
def iteritems(self):
try:
it = self.get_job_dict().iteritems()
except AttributeError:
# Python3
it = self.get_job_dict().items()
for name, url in it:
api_url = self.python_api_url(url)
yield name, Job(api_url, name, self.jenkins_obj)
def values(self):
return [a[1] for a in self.iteritems()]
def items(self):
return [a for a in self.iteritems()]
def _get_jobs(self):
if 'jobs' in self._data:
for viewdict in self._data["jobs"]:
yield viewdict["name"], viewdict["url"]
def get_job_dict(self):
return dict(self._get_jobs())
def __len__(self):
return len(self.get_job_dict().keys())
def get_job_url(self, str_job_name):
if str_job_name in self:
return self.get_job_dict()[str_job_name]
else:
# noinspection PyUnboundLocalVariable
views_jobs = ", ".join(self.get_job_dict().keys())
raise NotFound("Job %s is not known, available jobs"
" in view are: %s" % (str_job_name, views_jobs))
def get_jenkins_obj(self):
return self.jenkins_obj
def add_job(self, str_job_name, job=None):
"""
Add job to a view
:param str_job_name: name of the job to be added
:param job: Job object to be added
:return: True if job has been added, False if job already exists or
job not known to Jenkins
"""
if not job:
if str_job_name in self.get_job_dict():
log.warn(msg='Job %s is already in the view %s' %
(str_job_name, self.name))
return False
else:
# Since this call can be made from nested view,
# which doesn't have any jobs, we can miss existing job
# Thus let's create top level Jenkins and ask him
# http://jenkins:8080/view/CRT/view/CRT-FB/view/CRT-SCRT-1301/
top_jenkins = self.get_jenkins_obj().get_jenkins_obj_from_url(
self.baseurl.split('view/')[0])
if not top_jenkins.has_job(str_job_name):
log.error(msg='Job "%s" is not known to Jenkins' % str_job_name)
return False
else:
job = top_jenkins.get_job(str_job_name)
log.info(msg='Creating job %s in view %s' % (str_job_name, self.name))
data = {
"description": "",
"statusFilter": "",
"useincluderegex": "on",
"includeRegex": "",
"columns": [{"stapler-class": "hudson.views.StatusColumn",
"kind": "hudson.views.StatusColumn"},
{"stapler-class": "hudson.views.WeatherColumn",
"kind": "hudson.views.WeatherColumn"},
{"stapler-class": "hudson.views.JobColumn",
"kind": "hudson.views.JobColumn"},
{"stapler-class": "hudson.views.LastSuccessColumn",
"kind": "hudson.views.LastSuccessColumn"},
{"stapler-class": "hudson.views.LastFailureColumn",
"kind": "hudson.views.LastFailureColumn"},
{"stapler-class": "hudson.views.LastDurationColumn",
"kind": "hudson.views.LastDurationColumn"},
{"stapler-class": "hudson.views.BuildButtonColumn",
"kind": "hudson.views.BuildButtonColumn"}],
"Submit": "OK",
}
data["name"] = self.name
# Add existing jobs (if any)
for job_name in self.get_job_dict().keys():
data[job_name] = 'on'
# Add new job
data[job.name] = 'on'
data['json'] = data.copy()
data = urlencode(data)
self.get_jenkins_obj().requester.post_and_confirm_status(
'%s/configSubmit' % self.baseurl, data=data)
self.poll()
log.debug(msg='Job "%s" has been added to a view "%s"' %
(job.name, self.name))
return True
def _get_nested_views(self):
for viewdict in self._data.get("views", []):
yield viewdict["name"], viewdict["url"]
def get_nested_view_dict(self):
return dict(self._get_nested_views())
def get_config_xml_url(self):
return '%s/config.xml' % self.baseurl
def get_config(self):
"""
Return the config.xml from the view
"""
url = self.get_config_xml_url()
response = self.get_jenkins_obj().requester.get_and_confirm_status(url)
return response.text
def update_config(self, config):
"""
Update the config.xml to the view
"""
url = self.get_config_xml_url()
try:
if isinstance(config, unicode): # pylint: disable=undefined-variable
config = str(config)
except NameError:
# Python3 already a str
pass
response = self.get_jenkins_obj().requester.post_url(
url, params={}, data=config)
return response.text
@property
def views(self):
return self.get_jenkins_obj().get_jenkins_obj_from_url(self.baseurl).views
|