Преглед на файлове

add and remove db record and reverse record

develop
Robin Thoni преди 8 години
родител
ревизия
e336c656ea
променени са 2 файла, в които са добавени 163 реда и са изтрити 0 реда
  1. 13
    0
      config.example.json
  2. 150
    0
      localhostgen.py

+ 13
- 0
config.example.json Целия файл

@@ -0,0 +1,13 @@
1
+{
2
+  "database": {
3
+    "host": "localhost",
4
+    "port": 5432,
5
+    "database": "powerdns",
6
+    "username": "powerdns",
7
+    "password": "password"
8
+  },
9
+  "domain": "local.example.com",
10
+  "reverseDomain": "1.168.192.in-addr.arpa",
11
+  "dhcpdFile": "/etc/dhcp/dhcpd.conf",
12
+  "recordTTL": 600
13
+}

+ 150
- 0
localhostgen.py Целия файл

@@ -0,0 +1,150 @@
1
+#! /usr/bin/env python3
2
+
3
+import argparse
4
+import json
5
+from time import time
6
+
7
+import psycopg2
8
+import sys
9
+
10
+
11
+class LocalHostGen:
12
+    db_config = None
13
+    db_instance = None
14
+
15
+    def __init__(self, db_config):
16
+        self.db_config = db_config
17
+
18
+    def connect(self):
19
+        self.db_instance = psycopg2.connect("dbname='%s' user='%s' host='%s' password='%s' port='%s'" %
20
+                                            (self.db_config['database'], self.db_config['username'],
21
+                                             self.db_config['host'], self.db_config['password'],
22
+                                             self.db_config['port']))
23
+
24
+    def disconnect(self):
25
+        if self.db_instance is not None:
26
+            self.db_instance.close()
27
+            self.db_instance = None
28
+
29
+    def get_domain_id(self, domain):
30
+        cur = self.db_instance.cursor()
31
+        cur.execute("SELECT id FROM domains WHERE name='%s'" % domain)
32
+        id = cur.fetchone()
33
+        cur.close()
34
+        if id is not None:
35
+            return id[0]
36
+        return None
37
+
38
+    def get_record_id(self, record):
39
+        cur = self.db_instance.cursor()
40
+        cur.execute("SELECT id FROM records WHERE name='%s'" % record)
41
+        id = cur.fetchone()
42
+        cur.close()
43
+        if id is not None:
44
+            return id[0]
45
+        return None
46
+
47
+    def get_record_content(self, record):
48
+        cur = self.db_instance.cursor()
49
+        cur.execute("SELECT content FROM records WHERE name='%s'" % record)
50
+        content = cur.fetchone()
51
+        cur.close()
52
+        if content is not None:
53
+            return content[0]
54
+        return None
55
+
56
+    def get_reversed_ip(self, ip):
57
+        return '.'.join(reversed(ip.split(".")))
58
+
59
+    def get_reverse_domain_record(self, reverse_domain, ip):
60
+        reversed_ip = self.get_reversed_ip(ip)
61
+        reverse_domain_part = reversed_ip
62
+        while not reverse_domain.startswith(reverse_domain_part):
63
+            reverse_domain_part = reverse_domain_part[reverse_domain_part.index('.') + 1:]
64
+        return reversed_ip[0:len(reversed_ip) - len(reverse_domain_part) - 1]
65
+
66
+    def insert_host(self, domain, record, content, ttl, type):
67
+        record_full = "%s.%s" % (record, domain)
68
+
69
+        record_id = self.get_record_id(record_full)
70
+        if record_id is None:
71
+            domain_id = self.get_domain_id(domain)
72
+            cur = self.db_instance.cursor()
73
+            cur.execute("INSERT INTO records (domain_id, name, type, content, ttl, prio, change_date,"
74
+                        "disabled, ordername, auth) VALUES ('%s', '%s', '%s', '%s', '%s', '0', '%s', 'f', NULL, 't')"
75
+                        "RETURNING id" % (domain_id, record_full, type, content, ttl, int(time())))
76
+            record_id = cur.fetchone()[0]
77
+            cur.close()
78
+            self.db_instance.commit()
79
+        return record_id
80
+
81
+    def delete_host(self, record):
82
+        cur = self.db_instance.cursor()
83
+        cur.execute("DELETE FROM records WHERE name='%s' RETURNING id" % record)
84
+        record_id = cur.fetchone()[0]
85
+        cur.close()
86
+        self.db_instance.commit()
87
+        return record_id
88
+
89
+    def create_host(self, domain, reverse_domain, host, ip, mac, ttl):
90
+        if self.db_instance is None:
91
+            self.connect()
92
+        reverse_domain_record = self.get_reverse_domain_record(reverse_domain, ip)
93
+        record_full = "%s.%s" % (host, domain)
94
+
95
+        self.insert_host(domain, host, ip, ttl, 'A')
96
+        self.insert_host(reverse_domain, reverse_domain_record, record_full, ttl, 'PTR')
97
+
98
+    def remove_host(self, domain, reverse_domain, host):
99
+        if self.db_instance is None:
100
+            self.connect()
101
+        record_full = "%s.%s" % (host, domain)
102
+        ip = self.get_record_content(record_full)
103
+        if ip is not None:
104
+            reverse_domain_record = self.get_reverse_domain_record(reverse_domain, ip)
105
+            reverse_domain_record_full = "%s.%s" %(reverse_domain_record, reverse_domain)
106
+            self.delete_host(record_full)
107
+            self.delete_host(reverse_domain_record_full)
108
+
109
+
110
+def eprint(*args, **kwargs):
111
+    print(*args, file=sys.stderr, **kwargs)
112
+
113
+
114
+def main():
115
+    parser = argparse.ArgumentParser(description='Manage local hosts for PowerDNS and isc-dhcp-server')
116
+    parser.add_argument('--host', help='The host to manage', required=True)
117
+    parser.add_argument('--config', dest='config', default='/etc/localhostgen/localhostgen.json',
118
+                        help='Configuration file path')
119
+
120
+    parser.add_argument('--create', help='Create a host', action='store_true')
121
+    parser.add_argument('--remove', help='Remove the host', action='store_true')
122
+
123
+    parser.add_argument('--mac', help='The MAC address of the new host')
124
+    parser.add_argument('--ip', help='The IP address of the new host')
125
+
126
+    args = parser.parse_args()
127
+
128
+    with open(args.config, "r") as f:
129
+        config = json.load(f)
130
+
131
+    host = args.host
132
+    ip = args.ip
133
+    mac = args.mac
134
+    ttl = config['recordTTL']
135
+
136
+    local_host_gen = LocalHostGen(config['database'])
137
+    local_host_gen.connect()
138
+
139
+    if args.create:
140
+        if ip is None or mac is None:
141
+            eprint("IP and MAC are required to create a host")
142
+            exit(1)
143
+        local_host_gen.create_host(config['domain'], config['reverseDomain'], host, ip, mac, ttl)
144
+    elif args.remove:
145
+        local_host_gen.remove_host(config['domain'], config['reverseDomain'], host)
146
+
147
+    local_host_gen.disconnect()
148
+
149
+
150
+main()

Loading…
Отказ
Запис