diff --git a/cli/objects/repo.py b/cli/objects/repo.py index 76760cb..e77f6fa 100644 --- a/cli/objects/repo.py +++ b/cli/objects/repo.py @@ -17,24 +17,67 @@ class OgRepo(): print_json(r.text) @staticmethod - def add_repo(rest, args): - parser = argparse.ArgumentParser(prog='ogcli add repo') - parser.add_argument('--address', - nargs='+', - required=True, - help='IP list separated by spaces') - parser.add_argument('--name', - nargs='?', - required=True, - help='name of the repository') - parsed_args = parser.parse_args(args) + def _add_repo(rest, parsed_args): payload = { 'addr': parsed_args.address, 'name': parsed_args.name, } - rest.post('/repository/add', payload=payload) + @staticmethod + def _add_repo_ip(rest, parsed_args): + for address in parsed_args.address: + if not check_address(address): + print(f'Invalid IP address: {address}') + return + + r = rest.get('/repositories') + target_repo = None + for repo in r.json()['repositories']: + if repo['id'] == parsed_args.id: + target_repo = repo + break + + if not target_repo: + print('Invalid repository id specified') + return + + for address in parsed_args.address: + if address in target_repo['addr']: + print(f'The repository already contains the address {address}') + return + + payload = { + 'id': parsed_args.id, + 'addr': target_repo['addr'] + parsed_args.address, + 'name': target_repo['name'], + } + rest.post('/repository/update', payload=payload) + + @staticmethod + def add_repo(rest, args): + parser = argparse.ArgumentParser(prog='ogcli add repo') + + # Mutually exclusive group for adding new repo or adding address to existing repo + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('--name', + nargs='?', + help='name of the repository') + group.add_argument('--id', + type=int, + help='repo id (list repos using "ogcli list repos")') + parser.add_argument('--address', + nargs='+', + required=True, + help='IP list separated by spaces') + + parsed_args = parser.parse_args(args) + + if parsed_args.name: + OgRepo._add_repo(rest, parsed_args) + elif parsed_args.id: + OgRepo._add_repo_ip(rest, parsed_args) + @staticmethod def update_repo(rest, args): parser = argparse.ArgumentParser(prog='ogcli update repo') @@ -61,17 +104,64 @@ class OgRepo(): rest.post('/repository/update', payload=payload) @staticmethod - def delete_repo(rest, args): - parser = argparse.ArgumentParser(prog='ogcli delete repo') - parser.add_argument('--id', - type=int, - nargs='?', - required=True, - help='repo id (list repos using "ogcli list repos")') - parsed_args = parser.parse_args(args) + def _delete_repo_ip(rest, parsed_args): + for address in parsed_args.address: + if not check_address(address): + print(f'Invalid IP address: {address}') + return + + r = rest.get('/repositories') + target_repo = None + for repo in r.json()['repositories']: + if repo['id'] == parsed_args.id: + target_repo = repo + break + + if not target_repo: + print('Invalid repository id specified') + return + + for address in parsed_args.address: + if address not in target_repo['addr']: + print(f'Invalid address {address}: The repository has the following IPs: {target_repo["addr"]}') + return + + target_repo['addr'].remove(address) + + payload = { + 'id': parsed_args.id, + 'addr': target_repo['addr'], + 'name': target_repo['name'], + } + rest.post('/repository/update', payload=payload) + + @staticmethod + def _delete_repo(rest, parsed_args): payload = {'id': parsed_args.id} rest.post('/repository/delete', payload=payload) + @staticmethod + def delete_repo(rest, args): + parser = argparse.ArgumentParser(prog='ogcli delete repo') + + parser.add_argument('--id', + type=int, + required=True, + help='repo id (list repos using "ogcli list repos")') + + # --address is optional; if provided, the IP will be removed, otherwise, + # the repo will be deleted + parser.add_argument('--address', + nargs='+', + help='IP address to remove from the repository') + + parsed_args = parser.parse_args(args) + + if parsed_args.address: + OgRepo._delete_repo_ip(rest, parsed_args) + else: + OgRepo._delete_repo(rest, parsed_args) + @staticmethod def set_repo(rest, args): parser = argparse.ArgumentParser(prog='ogcli set repo')