diff --git a/proteuscmd/__main__.py b/proteuscmd/__main__.py index 78db6b6..8404351 100644 --- a/proteuscmd/__main__.py +++ b/proteuscmd/__main__.py @@ -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): @@ -35,9 +36,7 @@ def dns(): @cli.group() def ip(): '''Register IP addresses. - Not implemented yet. ''' - pass @dns.command() @@ -45,7 +44,7 @@ def ip(): @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} @@ -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 = {} @@ -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() diff --git a/proteuscmd/api.py b/proteuscmd/api.py index 6edfdfe..5a34217 100644 --- a/proteuscmd/api.py +++ b/proteuscmd/api.py @@ -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. ''' @@ -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. @@ -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):