-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathzone2sql
More file actions
executable file
·359 lines (304 loc) · 12.8 KB
/
zone2sql
File metadata and controls
executable file
·359 lines (304 loc) · 12.8 KB
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
#!/usr/bin/python
from lib.bind import *
import subprocess
import csv
import tempfile
axfr = tempfile.NamedTemporaryFile(delete=False)
zone_axfr = axfr.name
# +----------------------------------------------------------------------+
def createSQLsoa(zone, type, f):
with open(zone_axfr) as file:
try:
for line in file:
if re.findall( "\\b"+type+"\\b", line ):
fields = line.strip().split()
name = fields[0].strip('.')
ttl = fields[1]
type = fields[3]
content = fields[4].strip('.')
admin = fields[5].strip('.')
serial = fields[6]
refresh = fields[7]
retry = fields[8]
expire = fields[9]
minimum = fields[10]
sql = """ insert into domains (name,type,content,admin,serial,refresh,retry,expire,minimum,ttl) values ('%s','%s','%s','%s','%s',%s,%s,%s,%s,%s); """ % (name,type,content,admin,serial,refresh,retry,expire,minimum,ttl)
print >> f, (sql)
break
except Exception, ex:
print "Error while write SOA data"
sys.exit(1)
# +----------------------------------------------------------------------+
def createSQLns(zone, type, f):
with open(zone_axfr) as file:
try:
for line in file:
if re.findall( "\\b"+type+"\\b", line ):
fields = line.strip().split()
name = fields[0].strip('.')
ttl = fields[1]
type = fields[3]
content = fields[4].strip('.')
prio = '0'
sql = """ insert into supermasters (domain_id, name,type,content,ttl,prio) select id ,'%s', '%s', '%s', %s, %s from domains where name='%s'; """ % (zone,type,content,ttl,prio,zone)
print >> f, (sql)
except Exception, ex:
print "Error while write data 'all'"
sys.exit(1)
f.close
# +----------------------------------------------------------------------+
def createSQLall(zone, type, f):
with open(zone_axfr) as file:
try:
for line in file:
if re.findall( "\\b"+type+"\\b", line ):
fields = line.strip().split()
name = fields[0].strip('.')
ttl = fields[1]
type = fields[3]
if type == 'MX':
prio = fields[4]
content = fields[5].strip('.')
else:
prio = '0'
content = fields[4].strip('.')
sql = """ insert into records (domain_id, name,type,content,ttl,prio) select id ,'%s', '%s', '%s', %s, %s from domains where name='%s'; """ % (name,type,content,ttl,prio,zone)
print >> f, (sql)
except Exception, ex:
print "Error while write data 'all'"
sys.exit(1)
f.close
# +----------------------------------------------------------------------+
def getAXFR(cmd):
""" Run system commands """
zone_a = open(zone_axfr, "w")
try:
proc = subprocess.Popen([cmd], stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()
if err == None:
print >> zone_a, out
return True
else:
print '%s zone available' % err
return False
except Exception, e:
logger.error(" Shell command failed with following error: %s" % e)
sys.exit(1)
# +----------------------------------------------------------------------+
# Run the prog to generate sql
def importZone(args):
""" Import or dump zone information to SQL """
jissueid = args.jiraid
zone = args.zone.lower()
# Jira Login
jirauser, jirapw = jira_login()
# Jira Validation
# User confirm
user_input(jirauser, 'Do you want to step through managed zone into database')
try:
j_valid, j_status = get_issue_by_id(serverurl,jirauser,jirapw,jissueid)
if j_valid:
if j_status:
statuscode = val_status(j_status)
logger.info("Hello %s: You are authorized to run bindadmin, '%s' status is '%s' ... -:)" % (jirauser,jissueid,statuscode))
else:
raise
except Exception, e:
logger.error("Jira issue '%s' does not exist or you don't have permission to view it, please check jira and rerun again" % jissueid)
sys.exit(1)
v_zone = parse_named_file(named_file, zone)
if v_zone:
pass
else:
sys.exit("Error: '%s' is not present in '%s', please check.." % (zone, named_file))
f = open('sql/' + zone + '.sql', "w")
cmd = 'dig @%s %s -t AXFR' % (dnsmaster, zone)
if getAXFR(cmd):
createSQLsoa(zone, 'SOA', f)
createSQLns(zone, 'NS', f)
for type in SUPPORTED_RECORD_TYPES:
createSQLall(zone, type, f)
else:
print "Failed to get AXFR"
sys.exit(1)
if os.path.exists(zone_axfr):
os.unlink(zone_axfr)
print """
**** Successful: Created dump file - sql/%s.sql ****
NOTE: You need to manually dump/apply this to your database.
Example:
mysql> use dnsdb;
mysql> \. sql/%s.sql;
""" % (zone, zone)
# +----------------------------------------------------------------------+
def exportZone(args):
""" Export zone information from SQL or git"""
conn = dbconnection()
mysql = conn.cursor()
buffer = ""
jissueid = args.jiraid
zone = args.zone.lower()
zoneid = zonedetails(zone)
myfile = '%s' % zone
# Jira Login
jirauser, jirapw = jira_login()
# Jira Validation
# User confirm
user_input(jirauser, 'Do you want to step through managed zone into database')
try:
j_valid, j_status = get_issue_by_id(serverurl,jirauser,jirapw,jissueid)
if j_valid:
if j_status:
statuscode = val_status(j_status)
logger.info("Hello %s: You are authorized to run bindadmin, '%s' status is '%s' ... -:)" % (jirauser,jissueid,statuscode))
else:
raise
except Exception, e:
logger.error("Jira issue '%s' does not exist or you don't have permission to view it, please check jira and rerun again" % jissueid)
sys.exit(1)
# Querying soa records
try:
sql = """ select * from domains where name="%s" """ % zone
mysql.execute(sql)
rows = ''
rows=mysql.fetchall()
with open(myfile, 'w') as f:
f.write(";server localhost\n")
f.write(";zone %s.\n" % zone)
for fields in rows:
zone_name = fields[1]
type = fields[2]
first_name_server = fields[3]
administrative_contact = fields[4]
zone_serial = fields[5]
slave_refresh_interval = fields[6]
slave_retry_interval = fields[7]
slave_expiration_time = fields[8]
nxdomain_cache_time = fields[9]
record_ttl = fields[10]
### Begin of the output generation
f.write("; Zone file built with the Python Tool bindmanager:\n")
f.write("$ORIGIN %s.\n" % zone_name)
# print("; " + __doc__.replace("\n","\n; ") )
f.write("$TTL %s ; Default TTL\n" % record_ttl)
f.write("@ IN SOA %s. %s. (\n" % (first_name_server, administrative_contact))
f.write(" %s ; serial\n" % zone_serial)
f.write(" %s ; slave refresh interval\n" % slave_refresh_interval)
f.write(" %s ; slave retry interval\n" % slave_retry_interval)
f.write(" %s ; slave copy expire time\n" % slave_expiration_time)
f.write(" %s ; NXDOMAIN cache time\n" % nxdomain_cache_time)
f.write(" )")
f.write("\n")
f.write("\n")
f.write("; domain name servers\n")
except Exception, ex:
logger.error("Fetching result - no '%s' zone available, please provide correct zone name" % zone)
sys.exit(1)
# Querying nameserver records
try:
nsql = """ select * from supermasters where domain_id='%s' """ % (zoneid)
mysql.execute(nsql)
result = ''
rowsns = ''
rowsns=mysql.fetchall()
mysql.close()
conn.close()
if rowsns:
with open(myfile, 'a') as f:
f.write("\n")
for fields in rowsns:
domain_id = fields[1]
name = fields[2]
type = fields[3]
content = fields[4]
ttl = fields[5]
f.write("@ IN %s %s.\n" % (type, content))
f.write("\n")
else:
raise
except Exception, ex:
logger.error("This may be if you have incorrect set of NS 'objects', which is not present into the zone db.")
sys.exit(1)
# Querying rest of the records
conn = dbconnection()
mysql = conn.cursor()
try:
rsql = """ select * from records where domain_id='%s' """ % (zoneid)
mysql.execute(rsql)
rowsall = ''
rowsall=mysql.fetchall()
mysql.close()
conn.close()
if rowsall:
with open(myfile, 'a') as f:
for fields in rowsall:
domain_id = fields[1]
name = fields[2]
type = fields[3]
content = fields[4]
ttl = fields[5]
name = find_hostname(zone, name)
if name == '':
name = '@'
if type == 'MX':
prio = fields[6]
f.write("@ IN %s %s %s\n" % (type, prio, content))
else:
f.write("$TTL %s ; Default TTL for record\n" % ttl )
f.write("%s IN %s %s\n" % (name, type, content))
except Exception, ex:
logger.error("This may be if you are trying to search incorrect records 'object'.")
sys.exit(1)
# Process args live
if args.live:
print "Step through stored zones in db: "
ans=raw_input("Do you really want to step through the zones in the database?[N,y]: ")
if ans in ['y','Y','yes','Yes','YES']:
print "Thanks..."
print "We are proceed your request to load this zone to zonepath.. please stay until it reloads"
print "......."
else:
print "You typed '%s', quiting..." % ans
sys.exit(1)
os.system ("cp %s %s" % (zone, zonepath))
if check_zone(zonepath, zone):
logger.info("Sanity check went good for '%s'" % zone)
reloadzone(zone)
archivezone(zone)
logger.info("Successfully exported zone '%s'" % zone)
return True
else:
print """
**** Successful: Exported zone '%s' - please check zone file at exported path ****
NOTE: You need to manually copy/validate/reload this to your zone_path.
Example:
$ ls %s
$ cp %s %s
$ %s -t %s %s %s
$ %s freeze %s && %s reload %s && %s thaw %s
""" % (zone, zone, zone, zonepath, checkzone, zonepath, zone, zone, rndc, zone, rndc, zone, rndc, zone)
# +----------------------------------------------------------------------+
def main():
"""
Figure out what you want to do from bindadmin, and then do the
needful (at the earliest).
"""
parser = argparse.ArgumentParser(description="Queries the zone data for just to import(dump)/export(restore) facility, we assume SQL is our central storage", epilog="To know more, write to: %s" % authoremail)
subparsers = parser.add_subparsers()
# zone to sql
parser_import = subparsers.add_parser('import',help="Import or dump zone information to SQL")
parser_import.add_argument("-z", "--zone", help="Set the zone to be dump",required=True)
parser_import.add_argument("-j", "--jiraid", help="Jira ID for auth and request tracking",required=True)
parser_import.set_defaults(func=importZone)
# sql to zone file
parser_export = subparsers.add_parser('export', help="Export zone information from SQL or git")
parser_export.add_argument("-z", "--zone", help="Set the zone to be restore",required=True)
parser_export.add_argument("-j", "--jiraid", help="Jira ID for auth and request tracking",required=True)
parser_export.add_argument("-l", "--live", action='store_true', help="Restore from DB and Put in live env to specified zone",required=False)
parser_export.set_defaults(func=exportZone)
args = parser.parse_args()
args.func(args)
return 0
# +----------------------------------------------------------------------+
if __name__ == "__main__":
sys.exit(main())