Skip to content

Commit

Permalink
Add command line options to manage IPv4
Browse files Browse the repository at this point in the history
This patch adds `get`, `set` and `delete` commands for IP addresses.
Only IPv4 addresses are handles so far.
  • Loading branch information
lkiesow committed Sep 27, 2023
1 parent 58ba518 commit 87099de
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 8 deletions.
80 changes: 76 additions & 4 deletions proteuscmd/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from proteuscmd.config import proteus_from_config

__views = click.Choice(('intern', 'extern', 'all'), case_sensitive=False)
__ip_states = click.Choice(('STATIC', 'DHCP_RESERVED'), case_sensitive=False)


def with_proteus(f):
Expand Down Expand Up @@ -35,17 +36,15 @@ def dns():
@cli.group()
def ip():
'''Register IP addresses.
Not implemented yet.
'''
pass


@dns.command()
@click.option('--view', default='all', type=__views)
@click.argument('domain')
@with_proteus
def get(proteus, view, domain):
'''Get information about a DNS entry.
'''Get information about a DNS recotd.
'''
views = proteus.get_requested_views(view)
return {name: proteus.get_record(view, domain) for name, view in views}
Expand All @@ -57,7 +56,7 @@ def get(proteus, view, domain):
@click.argument('target')
@with_proteus
def set(proteus, view, domain, target):
'''Set DNS entry in Proteus
'''Set DNS record in Proteus
'''
views = proteus.get_requested_views(view)
result = {}
Expand All @@ -79,5 +78,78 @@ def delete(proteus, view, domain):
proteus.delete_record(view, domain)


@ip.command
@click.argument('ip')
@with_proteus
def get(proteus, ip):
'''Get information about IPv4 address
'''
data = proteus.get_entities_by_name('default', 0, 'Configuration')
conf_id = data[0]['id']

data = proteus.get_ip_range_by_ip(ip, conf_id)
range_id = data["id"]

return proteus.get_ip4_address(ip, range_id)


@ip.command
@click.option('--admin-email', '-e', required=True)
@click.option('--admin-name', '-n', required=True)
@click.option('--admin-phone', '-p', required=True)
@click.option('--comment', '-c')
@click.option('--state', '-s', default='DHCP_RESERVED', type=__ip_states)
@click.option('--hostname', '-h')
@click.option('--view', default='all', type=__views)
@click.option('--prop', default=[], multiple=True)
@click.option('--force/--no-force', default=False, type=bool)
@click.argument('ip')
@click.argument('mac')
@with_proteus
def set(proteus, admin_email, admin_name, admin_phone, comment, state,
hostname, view, prop, force, ip, mac):
'''Assign IPv4 address
'''
# get notwork information
data = proteus.get_entities_by_name('default', 0, 'Configuration')
conf_id = data[0]['id']
range_id = proteus.get_ip_range_by_ip(ip, conf_id)['id']

# check if ip is already reserved
existing_address = proteus.get_ip4_address(ip, range_id)
if existing_address['id']:
if force:
proteus.delete_ip4_address(ip, range_id)
else:
raise ValueError('IP already reserved')

# prepare properties
props = {'admin_email': admin_email,
'admin_name': admin_name,
'admin_phone': admin_phone,
'comment': comment}
for extra_prop in prop:
k, v = extra_prop.split('=', 1)
props[k] = v
props = {k: v for k, v in props.items() if v}

proteus.assign_ip_address(conf_id, state, ip, mac, props, hostname, view)
return proteus.get_ip4_address(ip, range_id)


@ip.command
@click.argument('ip')
@with_proteus
def delete(proteus, ip):
'''Delete assigned IPv4 address
'''
# get notwork information
data = proteus.get_entities_by_name('default', 0, 'Configuration')
conf_id = data[0]['id']
range_id = proteus.get_ip_range_by_ip(ip, conf_id)['id']

proteus.delete_ip4_address(ip, range_id)


if __name__ == '__main__':
cli()
22 changes: 18 additions & 4 deletions proteuscmd/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ def __record_type_from_target(self, target):
except ValueError:
return 'AliasRecord'

def __parse_properties(self, properties):
'''Take the property string returned by Proteus and turn it into a
dictionary containing the key-value pairs.
'''
properties = properties.split('|')
properties = [prop.split('=', 1) for prop in properties if prop]
return {prop[0]: prop[1] for prop in properties}

def login(self):
'''Logging in at Proteus.
'''
Expand Down Expand Up @@ -128,7 +136,15 @@ def get_ip_range_by_ip(self, ip, conf_id):

def get_ip4_address(self, ip, range_id):
params = {'address': ip, 'containerId': range_id}
return self.__get('getIP4Address', params=params)
data = self.__get('getIP4Address', params=params)
if data.get('properties'):
data['properties'] = self.__parse_properties(data['properties'])
return data

def delete_ip4_address(self, ip, range_id):
object_id = self.get_ip4_address(ip, range_id)['id']
payload = {'objectId': object_id}
return self.__delete('delete', payload)

def get_requested_views(self, view_arg):
'''Get requested views.
Expand Down Expand Up @@ -170,9 +186,7 @@ def get_record(self, view, domain):
data = self.get_entities_by_name(host, parent, 'HostRecord') \
+ self.get_entities_by_name(host, parent, 'AliasRecord')
for record in data:
properties = record['properties'].split('|')
properties = [prop.split('=', 1) for prop in properties if prop]
return {prop[0]: prop[1] for prop in properties}
return self.__parse_properties(record['properties'])
return {}

def set_record(self, view, domain, target):
Expand Down

0 comments on commit 87099de

Please sign in to comment.