1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import base64
19 import httplib
20 import locale
21 import sys
22 import os
23
24 from gettext import gettext as _
25
26 try:
27 import json
28 except ImportError:
29 import simplejson as json
30
31 from M2Crypto import SSL, httpslib
32
33 from pulp.client.logutil import getLogger
34
35
36 log = getLogger(__name__)
37
38 consumer_deferred_fields = ['package_profile', 'repoids']
39 package_deferred_fields = []
40 repository_deferred_fields = ['packages', 'packagegroups', 'packagegroupcategories']
41
42
44 if os.path.exists(path):
45 return path
46 else:
47 return None
48
49
52 self.code = code
53 self.msg = msg
54
56 return '%s: %s' % (str(self.code), self.msg)
57
59 """
60 A wrapper around httplib to make rest calls easier
61 """
62 - def __init__(self, host, port, apihandler, cert_file=None, key_file=None,
63 username=None, password=None):
64 self.host = host
65
66
67 self.port = int(port)
68 self.apihandler = apihandler
69 self.username = username
70 self.password = password
71 if (self.username != None):
72 raw = "%s:%s" % (self.username, self.password)
73 base64string = base64.encodestring(raw)[:-1]
74 auth = "Basic %s" % base64string
75 else:
76 auth = None
77 default_locale = locale.getdefaultlocale()[0]
78 if default_locale:
79 default_locale = default_locale.lower().replace('_', '-')
80 self.headers = {"Content-type":"application/json",
81 "Authorization": auth,
82 "Accept": "application/json",
83 "Accept-Language": default_locale}
84 self.cert_file = cert_file
85 self.key_file = key_file
86
87 - def _request(self, request_type, method, info=None):
88 handler = method
89 if not handler.startswith(self.apihandler):
90
91 handler = '/'.join((self.apihandler, handler))
92 log.debug("_request calling: %s to host:port : %s:%s" %
93 (handler, self.host, self.port))
94 if self.cert_file:
95 log.info("Using SSLv3 context")
96 context = SSL.Context("sslv3")
97 context.load_cert(self.cert_file, keyfile=self.key_file)
98 conn = httpslib.HTTPSConnection(self.host, self.port, ssl_context=context)
99 else:
100 conn = httplib.HTTPSConnection(self.host, self.port)
101 log.debug("Request_type: %s" % request_type)
102 log.debug("info: %s" % info)
103 log.debug("headers: %s" % self.headers)
104 conn.request(request_type, handler, body=json.dumps(info),
105 headers=self.headers)
106 response = conn.getresponse()
107 if response.status == 404:
108 return None
109 self.validateResponse(response)
110 rinfo = response.read()
111 if not len(rinfo):
112 return None
113 return json.loads(rinfo)
114
118
119
122
123 - def request_post(self, method, params=""):
124 return self._request("POST", method, params)
125
127 return self._request("HEAD", method)
128
131
133 return self._request("DELETE", method)
134
136 """
137 Proxy connection to Pulp Server
138 """
139
140 CERT_PATH = "/etc/pki/consumer/cert.pem"
141 KEY_PATH = "/etc/pki/consumer/key.pem"
142
146 self.host = host
147 self.port = port
148 self.handler = handler
149 self.conn = None
150 self.cert_file = cert_file
151 self.key_file = key_file
152 self.username = username
153 self.password = password
154
155 self.setUp()
156
158 self.conn = Restlib(self.host, self.port, self.handler, self.cert_file,
159 self.key_file, self.username, self.password)
160 log.info("Connection Established for cli: Host: %s, Port: %s, handler: %s" %
161 (self.host, self.port, self.handler))
162 log.info("Using cert_file: %s and key_file: %s" %
163 (self.cert_file, self.key_file))
164
166 self.conn.close()
167 log.info("remote connection closed")
168
169
171 """
172 Connection class to access repo specific calls
173 """
174 - def create(self, id, name, arch, feed=None, symlinks=False,
175 sync_schedule=None, cert_data=None):
176 method = "/repositories/"
177 repodata = {"id" : id,
178 "name" : name,
179 "arch" : arch,
180 "feed" : feed,
181 "use_symlinks" : symlinks,
182 "sync_schedule" : sync_schedule,
183 "cert_data" : cert_data}
184 return self.conn.request_put(method, params=repodata)
185
194
196 method = "/repositories/"
197 return self.conn.request_get(method)
198
202
204 method = "/repositories/%s/" % id
205 return self.conn.request_delete(method)
206
208 method = "/repositories/"
209 return self.conn.request_delete(method)
210
211 - def sync(self, repoid, timeout=None):
214
216 method = "/repositories/%s/sync/%s" % (repoid, taskid)
217 return self.conn.request_delete(method)
218
220 addinfo = {'repoid' : repoid,
221 'packageid' : packageid}
222 method = "/repositories/%s/add_package/" % repoid
223 return self.conn.request_post(method, params=addinfo)
224
226 method = "/repositories/%s/get_package/" % repoid
227 return self.conn.request_post(method, params=pkg_name)
228
230 method = "/repositories/%s/packages/" % repoid
231 return self.conn.request_get(method)
232
234 method = "/repositories/%s/packagegroups/" % repoid
235 return self.conn.request_get(method)
236
238 method = "/repositories/%s/create_packagegroup/" % repoid
239 return self.conn.request_post(method, params={"groupid":groupid,
240 "groupname":groupname, "description":description})
241
243 method = "/repositories/%s/delete_packagegroup/" % repoid
244 return self.conn.request_post(method, params={"groupid":groupid})
245
247 method = "/repositories/%s/add_packages_to_group/" % repoid
248 return self.conn.request_post(method,
249 params={"groupid":groupid, "packagenames":packagenames, "type":gtype})
250
252 method = "/repositories/%s/delete_package_from_group/" % repoid
253 return self.conn.request_post(method,
254 params={"groupid":groupid, "name":pkgname, "type":gtype})
255
256 - def upload(self, id, pkginfo, pkgstream):
257 uploadinfo = {'repo' : id,
258 'pkginfo' : pkginfo,
259 'pkgstream' : pkgstream}
260 method = "/repositories/%s/upload/" % id
261 return self.conn.request_post(method, params=uploadinfo)
262
264 method = "/repositories/schedules/"
265 return self.conn.request_get(method)
266
269
271 erratainfo = {'repoid' : id,
272 'errataid' : errataids}
273 method = "/repositories/%s/add_errata/" % id
274 return self.conn.request_post(method, params=erratainfo)
275
277 erratainfo = {'repoid' : id,
278 'errataid' : errataids}
279 method = "/repositories/%s/delete_errata/" % id
280 return self.conn.request_post(method, params=erratainfo)
281
282 - def errata(self, id, types=[]):
283 erratainfo = {'repoid' : id,
284 'types' : types}
285 method = "/repositories/%s/list_errata/" % id
286 return self.conn.request_post(method, params=erratainfo)
287
288
290 """
291 Connection class to access repo specific calls
292 """
293 - def create(self, id, description):
294 consumerdata = {"id" : id, "description" : description}
295 method = "/consumers/"
296 return self.conn.request_put(method, params=consumerdata)
297
301
305
309
311 method = "/consumers/"
312 return self.conn.request_delete(method)
313
320
322 method = "/consumers/%s/packages/" % str(id)
323 return self.conn.request_get(method)
324
326 method = "/consumers/%s/certificate/" % str(id)
327 cert_dict = self.conn.request_get(method)
328 return cert_dict
329
331 method = "/consumers/"
332 return self.conn.request_get(method)
333
335 method = '/consumers/?package_name=%s' % name
336 return self.conn.request_get(method)
337
338 - def bind(self, id, repoid):
341
342 - def unbind(self, id, repoid):
345
349
351 method = "/consumers/%s/installpackages/" % id
352 body = dict(packagenames=packagenames)
353 return self.conn.request_post(method, params=body)
354
356 method = "/consumers/%s/installpackagegroups/" % id
357 body = dict(packageids=packageids)
358 return self.conn.request_post(method, params=body)
359
360 - def errata(self, id, types=None):
361 method = "/consumers/%s/listerrata/" % id
362 body = dict(types=types)
363 return self.conn.request_post(method, params=body)
364
366 erratainfo = {'consumerid' : id,
367 'errataids' : errataids,
368 'types' : types}
369 method = "/consumers/%s/installerrata/" % id
370 return self.conn.request_post(method, params=erratainfo)
371
372 - def history(self, id, query_params):
373 method = "/consumers/%s/history/" % id
374 return self.conn.request_post(method, params=query_params)
375
376
378 """
379 Connection class to access consumer group related calls
380 """
381 - def create(self, id, description, consumerids=[]):
382 consumergroup_data = {"id" : id, "description" : description,
383 "consumerids" : consumerids}
384 method = "/consumergroups/"
385 return self.conn.request_put(method, params=consumergroup_data)
386
387 - def update(self, consumergroup):
390
392 method = "/consumergroups/%s/" % id
393 return self.conn.request_delete(method)
394
396 method = "/consumergroups/"
397 return self.conn.request_delete(method)
398
400 method = "/consumergroups/"
401 return self.conn.request_get(method)
402
404 method = "/consumergroups/%s/" % str(id)
405 return self.conn.request_get(method)
406
408 method = "/consumergroups/%s/add_consumer/" % id
409 return self.conn.request_post(method, params=consumerid)
410
412 method = "/consumers/%s/delete_consumer/" % id
413 return self.conn.request_post(method, params=consumerid)
414
415 - def bind(self, id, repoid):
416 method = "/consumergroups/%s/bind/" % id
417 return self.conn.request_post(method, params=repoid)
418
419 - def unbind(self, id, repoid):
420 method = "/consumergroups/%s/unbind/" % id
421 return self.conn.request_post(method, params=repoid)
422
424 method = "/consumergroups/%s/installpackages/" % id
425 body = dict(packagenames=packagenames)
426 return self.conn.request_post(method, params=body)
427
429 erratainfo = {'consumerid' : id,
430 'errataids' : errataids,
431 'types' : types}
432 method = "/consumergroups/%s/installerrata/" % id
433 return self.conn.request_post(method, params=erratainfo)
434
436
440
441 - def create(self, name, epoch, version, release, arch, description,
442 checksum_type, checksum, filename):
443 method = "/packages/"
444 repodata = {"name" : name,
445 "epoch" : epoch,
446 "version" : version,
447 "release" : release,
448 "arch" : arch,
449 "description" : description,
450 "checksum_type" : checksum_type,
451 "checksum": checksum,
452 "filename": filename, }
453 return self.conn.request_put(method, params=repodata)
454
456 method = "/packages/"
457 return self.conn.request_get(method)
458
459 - def package(self, id, filter=None):
460 method = "/packages/%s/" % id
461 return self.conn.request_get(method)
462
464 method = "/packages/%s/" % packageid
465 return self.conn.request_delete(method)
466
470
475
476
481
482
484 """
485 Connection class to access consumer group related calls
486 """
487 - def create(self, login, password=None, name=None):
488 user_data = {"login" : login, "password" : password,
489 "name" : name}
490 method = "/users/"
491 return self.conn.request_put(method, params=user_data)
492
496
498 login = kwargs['login']
499 method = "/users/%s/" % login
500 return self.conn.request_delete(method)
501
505
507 method = "/users/"
508 return self.conn.request_get(method)
509
510 - def user(self, login):
511 method = "/users/%s/" % str(login)
512 return self.conn.request_get(method)
513
515 method = '/users/admin_certificate/'
516 return self.conn.request_get(method)
517
519 """
520 Connection class to access errata related calls
521 """
524
525 - def create(self, id, title, description, version, release, type,
526 status="", updated="", issued="", pushcount="", update_id="",
527 from_str="", reboot_suggested="", references=[],
528 pkglist=[]):
530
532 method = "/errata/%s/" % id
533 return self.conn.request_get(method)
534
535 - def errata(self, id=None, title=None, description=None, version=None,
536 release=None, type=None, status=None, updated=None, issued=None,
537 pushcount=None, from_str=None, reboot_suggested=None):
539
540 if __name__ == '__main__':
541 rconn = RepoConnection()
542 print "+--------------------------------+"
543 print " Repo API Tests "
544 print "+--------------------------------+"
545
546 repo = rconn.create('test-f12', 'f12', 'i386', 'yum:http://mmccune.fedorapeople.org/pulp/')
547 print "create Repos", repo['id']
548 print "list repos:", rconn.repositories()
549 print "Get repo By Id: ", rconn.repository(repo['id'])
550 newdata = {'id' : 'test-f12',
551 'name' : 'f12',
552 'arch' : 'noarch',
553 'feed' : 'yum:http://mmccune.fedorapeople.org/pulp/'}
554
555 print "Sync Repos:", rconn.sync(repo['id'])
556 print "list Repo Packages: ", rconn.packages(repo['id'])
557 print "delete Repo:", rconn.delete(repo['id'])
558 print "+--------------------------------+"
559 print " Consumer API Tests "
560 print "+--------------------------------+"
561 cconn = ConsumerConnection()
562 print "Create Consumer", cconn.create("test", 'prad.rdu.redhat.com')
563 print "List Consumers", cconn.consumers()
564