1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
#!/usr/bin/python3
# Copyright (c) 2017-2019 David Steele <dsteele@gmail.com>
#
# SPDX-License-Identifier: GPL-2.0-or-later
# License-Filename: LICENSE
#
# Copyright 2016-2017 David Steele <steele@debian.org>
# This file is part of comitup
# Available under the terms of the GNU General Public License version 2
# or later
#
import dbus
import socket
import logging
from comitup import nm
import subprocess
log = logging.getLogger('comitup')
# globals
CLASS_IN = 0x01
TYPE_A = 0x01
TTL = 5
DBUS_NAME = 'org.freedesktop.Avahi'
DBUS_PATH_SERVER = '/'
DBUS_INTERFACE_SERVER = 'org.freedesktop.Avahi.Server'
DBUS_INTERFACE_ENTRY_GROUP = 'org.freedesktop.Avahi.EntryGroup'
PROTO_INET = 0
group = None
# functions
def establish_group():
global group
bus = dbus.SystemBus()
server = dbus.Interface(
bus.get_object(DBUS_NAME, DBUS_PATH_SERVER),
DBUS_INTERFACE_SERVER
)
group = dbus.Interface(
bus.get_object(DBUS_NAME, server.EntryGroupNew()),
DBUS_INTERFACE_ENTRY_GROUP
)
def encode_dns(name):
components = [x for x in name.split('.') if len(x) > 0]
fixed_name = '.'.join(components)
return fixed_name.encode('ascii')
def make_a_record(host, devindex, addr):
group.AddRecord(
devindex,
PROTO_INET,
dbus.UInt32(0),
encode_dns(host),
CLASS_IN,
TYPE_A,
TTL,
socket.inet_aton(addr)
)
def string_to_txt_array(strng):
if strng:
return [dbus.Byte(x) for x in strng.encode()]
else:
return strng
def string_array_to_txt_array(txt_array):
return [string_to_txt_array(x) for x in txt_array]
def add_service(host, devindex, addr):
name = host
if '.local' in name:
name = name[:-len('.local')]
group.AddService(
devindex,
PROTO_INET,
dbus.UInt32(0),
name,
"_workstation._tcp",
"",
host,
dbus.UInt16(9),
string_array_to_txt_array([
"hostname=%s" % host.encode(),
"ipaddr=%s" % addr,
"comitup-home=https://davesteele.github.io/comitup/",
])
)
# public functions
def clear_entries():
if group and not group.IsEmpty():
group.Reset()
establish_group()
def get_interface_mapping():
mapping = {}
for line in subprocess.check_output("ip addr".split()).decode().split('\n'):
try:
asc_index, name = line.split(": ")[0:2]
mapping[name] = int(asc_index)
except ValueError:
pass
return mapping
def add_hosts(hosts):
establish_group()
int_mapping = get_interface_mapping()
for device in nm.get_devices():
name = nm.device_name(device)
addr = nm.get_active_ip(device)
if (name in nm.get_phys_dev_names() \
and name in int_mapping \
and addr):
index = int_mapping[name]
for host in hosts:
make_a_record(host, index, addr)
add_service(hosts[0], index, addr)
group.Commit()
if __name__ == '__main__':
add_hosts(['comitup-1111.local', 'comitup.local'])
while True:
pass
|