123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- #!/usr/bin/env python3
- import requests
- import json
- import yaml
- import sys
- import argparse
- import tempfile
- import os
- import hashlib
- from subprocess import call
- config = os.path.join(os.path.dirname(os.path.realpath(__file__)),"config.yml")
- # Read configuration
- with open(config, 'r') as ymlfile:
- cfg = yaml.load(ymlfile, Loader=yaml.FullLoader)
- # Functions
- def call_api(method, url, object_data=None):
- headers = { 'Content-Type': 'application/json',
- 'Accept': 'application/json' }
- response = requests.request(method, url, json=object_data, headers=headers,
- params=cfg['params'])
- if not response.text:
- print("No response received (error %i)" % response.status_code)
- sys.exit(1)
- json_response=json.loads(response.text)
- if "errormessages" in json_response:
- for err in json_response['errormessages']['errormessage']:
- if 'args' in err:
- print(err['text'].replace('\n', ' ').replace('\r', '') \
- % tuple([d['value'] for d in err['args']]))
- else:
- print(err['text'])
- return json_response
- # Print formatted output from JSON
- def print_output(json, object_file):
- if "objects" in json:
- for attr in json['objects']['object'][0]['attributes']['attribute']:
- object_file.write("%-20s %s\n" % (attr['name']+':',
- attr['value']))
- if object_file:
- object_file.close()
- def read_input(object_file):
- attr = []
- for line in object_file.readlines():
- if not line: continue
- attr.append({'name':line.split(':', 1)[0].strip(),
- 'value':line.split(':', 1)[1].strip() })
- object_data = {
- "objects": {
- "object": [
- {
- "attributes": {
- "attribute": attr
- }
- }
- ]
- }
- }
- return object_data
- # Get record
- def get(args):
- print("Getting %s object %s" % (args.type, args.key))
- url = '/'.join((cfg['base_url'],args.type,args.key))
- json_response=call_api("GET", url)
- print_output(json_response, args.file)
- return
- # Delete record
- def delete(args):
- print("Deleting %s object %s" % (args.type, args.key))
- url = '/'.join((cfg['base_url'],args.type,args.key))
- json_response=call_api("DELETE", url)
- return
- # Create record
- def create(args):
- print("Creating %s object" % (args.type))
- url = '/'.join((cfg['base_url'],args.type))
- object_data = read_input(args.file)
- json_response=call_api("POST", url, object_data)
- print_output(json_response, sys.stdout)
- return
- # Update record
- def update(args):
- print("Updating %s object %s" % (args.type, args.key))
- url = '/'.join((cfg['base_url'],args.type,args.key))
- object_data = read_input(args.file)
- json_response=call_api("PUT", url, object_data)
- print_output(json_response, sys.stdout)
- return
- # Edit record
- def edit(args):
- tmp_fd, tmp_name = tempfile.mkstemp()
- get(parser.parse_args(["get", args.type, args.key, tmp_name]))
- EDITOR = os.environ.get('EDITOR','vim')
- # Memory inefficient, but who cares?
- hash1 = hashlib.md5(open(tmp_name).read().encode('utf-8')).hexdigest()
- call([EDITOR, tmp_name])
- hash2 = hashlib.md5(open(tmp_name).read().encode('utf-8')).hexdigest()
- if hash1 != hash2:
- update(parser.parse_args(["update", args.type, args.key, tmp_name]))
- else:
- print("Object unchanged, not updating")
- os.unlink(tmp_name)
- return
- if __name__ == '__main__':
- # Arguments parsing
- # USAGE : ./ripe-api.py delete <TYPE> <KEY>
- # ./ripe-api.py create <TYPE> <FILE>
- # ./ripe-api.py update <TYPE> <KEY> <FILE>
- # ./ripe-api.py get <TYPE> <KEY> <FILE>
- # ./ripe-api.py edit <TYPE> <KEY>
- parser = argparse.ArgumentParser(description='RIPE API client')
- subparsers = parser.add_subparsers(help='Action to perform',dest='action',required=True)
- parser_get = subparsers.add_parser('get', help='Get an object')
- parser_get.add_argument('type', type=str, help='Object type')
- parser_get.add_argument('key', type=str, help='Object identifier')
- parser_get.add_argument('file', type=argparse.FileType('w'), help='Output file')
- parser_delete = subparsers.add_parser('delete', help='Delete an object')
- parser_delete.add_argument('type', type=str, help='Object type')
- parser_delete.add_argument('key', type=str, help='Object identifier')
- parser_post = subparsers.add_parser('create', help='Create an object')
- parser_post.add_argument('type', type=str, help='Object type')
- parser_post.add_argument('file', type=argparse.FileType('r'), help='Input file')
- parser_put = subparsers.add_parser('update', help='Update an object')
- parser_put.add_argument('type', type=str, help='Object type')
- parser_put.add_argument('key', type=str, help='Object identifier')
- parser_put.add_argument('file', type=argparse.FileType('r'), help='Input file')
- parser_edit = subparsers.add_parser('edit', help='Edit an object')
- parser_edit.add_argument('type', type=str, help='Object type')
- parser_edit.add_argument('key', type=str, help='Object identifier')
- args = parser.parse_args()
- globals()[args.action](args)
|