From baa99b00138210aef8df155c13cf74a6b4d43e2f Mon Sep 17 00:00:00 2001 From: Alberto Garcia Fernandez Date: Thu, 3 Aug 2017 13:17:28 +0200 Subject: [PATCH 1/3] add_basic_auth --- aptly_cli/api/api.py | 108 +++++++++++++++++++++++------------------ aptly_cli/cli/cli.py | 9 ++++ aptly_cli/util/util.py | 6 ++- etc/aptly-cli.conf | 4 ++ 4 files changed, 79 insertions(+), 48 deletions(-) diff --git a/aptly_cli/api/api.py b/aptly_cli/api/api.py index f745081..70a7b40 100644 --- a/aptly_cli/api/api.py +++ b/aptly_cli/api/api.py @@ -8,6 +8,7 @@ import json import requests +import getpass import os from ConfigParser import ConfigParser @@ -30,15 +31,23 @@ def __init__(self): if cfg_file is not None: basic_url = cfg_file['basic_url'] port = cfg_file['port'] + user = cfg_file['user'] + password = cfg_file['password'] else: basic_url = 'http://localhost' port = ':9003' + user = '' + password = '' print "No Config file found, take default values" - self.headers = {'content-type': 'application/json'} - url = basic_url + port + self.session = requests.Session() + self.session.headers = {'content-type': 'application/json'} + + if password != '' and user != '': + self.session.auth = (user, password) + # self values self.cfg = { # Routes @@ -56,6 +65,18 @@ def __init__(self): # Number of snapshots to have left # 'save_last_snap': 3 } + self.user = user + self.password = password + + def update_auth(self, user): + if user == None: + if self.password == '' and self.user != '': + password = getpass.getpass() + self.session.auth = (self.user, password) + else: + password = getpass.getpass() + self.session.auth = (user, password) + @staticmethod def _out(arg_list): @@ -88,7 +109,10 @@ def get_config_from_file(): 'package_prefixes': config_file.get('general', 'package_prefixes'), # 3rd party 'repos': config_file.get('3rd_party', 'repos'), - 'staging_snap_pre_post': config_file.get('3rd_party', 'staging_snap_pre_post') + 'staging_snap_pre_post': config_file.get('3rd_party', 'staging_snap_pre_post'), + # auth + 'user': config_file.get('auth', 'user'), + 'password': config_file.get('auth', 'password'), } return cfg_file @@ -124,9 +148,8 @@ def repo_create(self, repo_name, data=None): 'DefaultComponent': data.default_component } - r = requests.post(self.cfg['route_repo'][:-1], - data=json.dumps(post_data), - headers=self.headers) + r = self.session.post(self.cfg['route_repo'][:-1], + data=json.dumps(post_data)) # r.raise_for_status() resp_data = json.loads(r.content) # print resp_data @@ -151,7 +174,7 @@ def repo_show(self, repo_name): Example: $ curl http://localhost:8080/api/repos/aptly-repo """ - r = requests.get(self.cfg['route_repo'] + repo_name, headers=self.headers) + r = self.session.get(self.cfg['route_repo'] + repo_name) resp_data = json.loads(r.content) # print resp_data return resp_data @@ -184,7 +207,7 @@ def repo_show_packages(self, repo_name, pkg_to_search=None, with_deps=0, detail= } url = str(self.cfg['route_repo']) + str(repo_name) + '/packages' - r = requests.get(url, params=param, headers=self.headers) + r = self.session.get(url, params=param) # raise_for_status() resp_data = json.loads(r.content) # print json.dumps(resp_data) @@ -221,9 +244,8 @@ def repo_edit(self, repo_name, data=None): 'DefaultComponent': data.default_component } - r = requests.put(self.cfg['route_repo'] + repo_name, - data=json.dumps(data), - headers=self.headers) + r = self.session.put(self.cfg['route_repo'] + repo_name, + data=json.dumps(data)) # r.raise_for_status() resp_data = json.loads(r.content) # print resp_data @@ -238,8 +260,8 @@ def repo_list(self): Example: $ curl http://localhost:8080/api/repos """ - r = requests.get(self.cfg['route_repo'], headers=self.headers) -# r.raise_for_status() + r = self.session.get(self.cfg['route_repo']) + # r.raise_for_status() resp_data = json.loads(r.content) # print json.dumps(resp_data) return resp_data @@ -260,9 +282,8 @@ def repo_delete(self, repo_name): 404 repository with such name doesn’t exist 409 repository can’t be dropped ( self, reason in the message) """ - r = requests.delete(self.cfg['route_repo'] + repo_name, - headers=self.headers) -# r.raise_for_status() + r = self.session.delete(self.cfg['route_repo'] + repo_name) + # r.raise_for_status() resp_data = json.loads(r.content) # print json.dumps(resp_data) return resp_data @@ -314,9 +335,7 @@ def repo_add_package_from_upload(self, repo_name, dir_name, file_name=None, para 'forceReplace': 0 } - r = requests.post(url, - params=query_param, - headers=self.headers) + r = self.session.post(url, params=query_param) # r.raise_for_status() resp_data = json.loads(r.content) # print resp_data @@ -355,7 +374,7 @@ def repo_add_packages_by_key(self, repo_name, package_key_list): param = { 'PackageRefs': package_key_list } - r = requests.post(url, data=json.dumps(param), headers=self.headers) + r = self.session.post(url, data=json.dumps(param)) resp_data = json.loads(r.content) # print resp_data return resp_data @@ -384,7 +403,7 @@ def repo_delete_packages_by_key(self, repo_name, package_key_list): data = { 'PackageRefs': package_key_list } - r = requests.delete(url, data=json.dumps(data), headers=self.headers) + r = self.session.delete(url, data=json.dumps(data)) resp_data = json.loads(r.content) # print resp_data return resp_data @@ -403,7 +422,7 @@ def file_list_directories(self): Example: $ curl http://localhost:8080/api/files """ - r = requests.get(self.cfg['route_file'], headers=self.headers) + r = self.session.get(self.cfg['route_file']) # r.raise_for_status() resp_data = json.loads(r.content) # print json.dumps(resp_data) @@ -426,7 +445,7 @@ def file_upload(self, dir_name, file_path): 'file': open(file_path, 'rb') } - r = requests.post(self.cfg['route_file'] + dir_name, + r = self.session.post(self.cfg['route_file'] + dir_name, files=f) # r.raise_for_status() @@ -450,8 +469,7 @@ def file_list(self, dir_name=None): if dir_name is None: dir_name = '' - r = requests.get(self.cfg['route_file'] + - dir_name, headers=self.headers) + r = self.session.get(self.cfg['route_file'] + dir_name) # r.raise_for_status() resp_data = json.loads(r.content) # print json.dumps(resp_data) @@ -466,8 +484,7 @@ def file_delete_directory(self, dir_name): Example: $ curl -X DELETE http://localhost:8080/api/files/aptly-0.9 """ - r = requests.delete( - self.cfg['route_file'] + dir_name, headers=self.headers) + r = self.session.delete(self.cfg['route_file'] + dir_name) # r.raise_for_status() resp_data = json.loads(r.content) # print json.dumps(resp_data) @@ -482,8 +499,8 @@ def file_delete(self, dir_name, file_name): Example: $ curl -X DELETE http://localhost:8080/api/files/aptly-0.9/aptly_0.9~dev+217+ge5d646c_i386.deb """ - r = requests.delete( - self.cfg['route_file'] + dir_name + '/' + file_name, headers=self.headers) + r = self.session.delete( + self.cfg['route_file'] + dir_name + '/' + file_name) # r.raise_for_status() resp_data = json.loads(r.content) # print json.dumps(resp_data) @@ -508,9 +525,8 @@ def snapshot_list(self, sort='time'): params = { 'sort': sort } - r = requests.get(self.cfg['route_snap'], - headers=self.headers, params=params) -# r.raise_for_status() + r = self.session.get(self.cfg['route_snap'], params=params) + # r.raise_for_status() resp_data = json.loads(r.content) # self._out(resp_data) return resp_data @@ -543,7 +559,7 @@ def snapshot_create_from_local_repo(self, snapshot_name, repo_name, description= 'Description': description } - r = requests.post(url, data=json.dumps(data), headers=self.headers) + r = self.session.post(url, data=json.dumps(data)) # r.raise_for_status() resp_data = json.loads(r.content) # print resp_data @@ -584,7 +600,7 @@ def snapshot_create_from_package_refs(self, snapshot_name, source_snapshot_list, 'PackageRefs': package_refs_list } - r = requests.post(url, data=json.dumps(data), headers=self.headers) + r = self.session.post(url, data=json.dumps(data)) resp_data = json.loads(r.content) # print resp_data return resp_data @@ -616,7 +632,7 @@ def snapshot_update(self, old_snapshot_name, new_snapshot_name, description=None 'Description': description } - r = requests.put(url, data=json.dumps(data), headers=self.headers) + r = self.session.put(url, data=json.dumps(data)) resp_data = json.loads(r.content) # print resp_data return resp_data @@ -635,7 +651,7 @@ def snapshot_show(self, snapshot_name): $ curl http://localhost:8080/api/snapshots/snap1 """ url = self.cfg['route_snap'] + snapshot_name - r = requests.get(url, headers=self.headers) + r = self.session.get(url) resp_data = json.loads(r.content) # print resp_data return resp_data @@ -666,7 +682,7 @@ def snapshot_delete(self, snapshot_name, force='0'): 'force': force } - r = requests.delete(url, params=param, headers=self.headers) + r = self.session.delete(url, params=param) print r.url resp_data = json.loads(r.content) # print resp_data @@ -702,7 +718,7 @@ def snapshot_show_packages(self, snapshot_name, package_to_search=None, with_dep 'format': detail } - r = requests.get(url, params=param, headers=self.headers) + r = self.session.get(url, params=param) resp_data = json.loads(r.content) # print resp_data return resp_data @@ -727,7 +743,7 @@ def snapshot_diff(self, snapshot_left, snapshot_right): """ url = self.cfg['route_snap'] + \ snapshot_left + '/diff/' + snapshot_right - r = requests.get(url, headers=self.headers) + r = self.session.get(url) resp = json.loads(r.content) # print resp return resp @@ -746,7 +762,7 @@ def publish_list(self): $ curl http://localhost:8080/api/publish """ url = self.cfg['route_pub'] - r = requests.get(url, headers=self.headers) + r = self.session.get(url) resp = json.loads(r.content) # print resp return resp @@ -836,7 +852,7 @@ def publish(self, prefix, src_kind, src_list, dist, comp_list, label=None, orig= } # print dat - r = requests.post(url, data=json.dumps(dat), headers=self.headers) + r = self.session.post(url, data=json.dumps(dat)) # print r.url resp = json.loads(r.content) # print resp @@ -892,7 +908,7 @@ def publish_switch(self, prefix, snapshot_list, dist, component=None, force_over 'Snapshots': snap_list_obj, 'ForceOverwrite': fo } - r = requests.put(url, data=json.dumps(data), headers=self.headers) + r = self.session.put(url, data=json.dumps(data)) resp = json.loads(r.content) # print resp return resp @@ -919,7 +935,7 @@ def publish_drop(self, prefix, distribution, force=0): 'force': force } - r = requests.delete(url, params=param, headers=self.headers) + r = self.session.delete(url, params=param) resp = json.loads(r.content) # print resp return resp @@ -951,7 +967,7 @@ def package_show_by_key(self, package_key): Hint: %20 is url-encoded space. """ url = self.cfg['route_pack'] + package_key - r = requests.get(url, headers=self.headers) + r = self.session.get(url) resp = json.loads(r.content) # print resp return resp @@ -971,7 +987,7 @@ def graph(self, file_ext='.png'): """ url = self.cfg['route_graph'][:-1] + file_ext print url - r = requests.get(url, headers=self.headers) + r = self.session.get(url) resp = json.loads(r.content) # print resp return resp @@ -989,7 +1005,7 @@ def get_version(self): $ curl http://localhost:8080/api/version """ url = self.cfg['route_vers'] - r = requests.get(url, headers=self.headers) + r = self.session.get(url) resp = json.loads(r.content) # print resp return resp diff --git a/aptly_cli/cli/cli.py b/aptly_cli/cli/cli.py index 5bf071b..9613782 100644 --- a/aptly_cli/cli/cli.py +++ b/aptly_cli/cli/cli.py @@ -36,6 +36,12 @@ def _get_parser_opts(): """ parser = OptionParser() + parser.add_option('--username', + nargs=1, + default=None, + help='Username to auth on aptly', + metavar='USERNAME') + parser.add_option('--repo_list', action='store_true', help='List all local repos') @@ -228,9 +234,12 @@ class Data(object): """ def __init__(self): pass + # # Basic API functionalities # + util.api.update_auth(opts.username) + if opts.repo_list: resp = util.api.repo_list() print json.dumps(resp, indent=2) diff --git a/aptly_cli/util/util.py b/aptly_cli/util/util.py index fb2f2c9..be6440b 100644 --- a/aptly_cli/util/util.py +++ b/aptly_cli/util/util.py @@ -44,8 +44,10 @@ def create_init_file(): try: conf = open(name, 'a') conf.write( - '[general]\nbasic_url=http://localhost\nport=:9003\nsave_last_snap=3\nsave_last_pkg=10\n \ -prefixes_mirrors=\npackage_prefixes=\nrepos_to_clean=\n[general]\nrepos=\nstaging_snap_pre_post=') + '[general]\nbasic_url=http://localhost\nport=:9003\n \ + save_last_snap=3\nsave_last_pkg=10\nprefixes_mirrors=\n \ + package_prefixes=\nrepos_to_clean=\n[3rd_party]\nrepos=\n \ + staging_snap_pre_post=\n[auth]\user=\npassword=\n') conf.close() except: diff --git a/etc/aptly-cli.conf b/etc/aptly-cli.conf index 4389471..8a60c75 100644 --- a/etc/aptly-cli.conf +++ b/etc/aptly-cli.conf @@ -13,3 +13,7 @@ save_last_snap=3 repos=3rdparty-eu-west-1, 3rdparty-us-east-1 # Pre and postfix of the staging snapshots staging_snap_pre_post=3rdparty-s3-repo, 3rdparty-staging_snapshot + +[auth] +username=jenkins +password= From 8fa2c7dadd636b33a0d4ea0074a40f1ee6c9b3ce Mon Sep 17 00:00:00 2001 From: Alberto Garcia Fernandez Date: Thu, 3 Aug 2017 13:32:17 +0200 Subject: [PATCH 2/3] modify README --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index d005197..2e173a5 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,10 @@ Please Note: You can configure the following keys: - package_prefixes: package-prefixes, which should be searched for to be cleaned out - save_last_pkg: Number of package-versions for each prefix, that should be kept - save_last_snap: Number of snapshot-versions for each prefix, that should be kept +- repos: 3rd party s3 buckets to publish switch to +- staging_snap_pre_post: Pre and postfix of the staging snapshots +- auth: user to authenticate using basic auth +- password: password to authenticate using basic auth See an working example (aptly-cli.conf): @@ -118,6 +122,10 @@ save_last_snap=3 repos=3rdparty-eu-west-1, 3rdparty-us-east-1 # Pre and postfix of the staging snapshots staging_snap_pre_post=3rdparty-s3-repo, 3rdparty-staging_snapshot + +[auth] +user=jenkins +password= ``` From 2765ecc582eb9db2cba0792626ea155231e35bde Mon Sep 17 00:00:00 2001 From: Alberto Garcia Fernandez Date: Thu, 24 Aug 2017 12:48:08 +0200 Subject: [PATCH 3/3] New version --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index 8c044fd..f42893e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +aptly-cli (0.1.9) UNRELEASED; urgency=medium + + * Add basic auth + + -- Jenkins Wed, 09 Aug 2017 20:20:18 +0200 + aptly-cli (0.1.8-c4efef0ac0263ac3c8b55357f684aa01cf71e727-unstable) UNRELEASED; urgency=low * Initial release. (Closes: #XXXXXX)