简体   繁体   中英

How do I create a Python class for these DNS database methods?

I'm trying to write some code to zone transfer a DNS zone, then parse the records and put them into a database. I've never used classes before in python, and I figured this could be as good of a time as any to learn how to use them. Not sure what I'm doing wrong here. This is running on Python version 2.6. Can I get some guidance? Having a tough time understanding how to use classes.

Code:

import pymysql
import time
import dns.zone
import dns.query
from pprint import pprint
from dns.exception import DNSException
from dns.rdataclass import *
from dns.rdatatype import *


a_records = {}
cname_records = {}

... # excluding db connection credentials

cur = conn.cursor()

try:
    zone = dns.zone.from_xfr(dns.query.xfr(ns, domain))
    print "zone xferred"
except DNSException, e:
    print e.__class__, e


def main():   
    compile_records()

    for key, value in a_records.iteritems():
        sqlfoo.select_a(domain, key, value)
    for key, value in cname_records.iteritems():
        sqlfoo.select_cname(domain, key, value)

def compile_records(): 
    for (name, ttl, rdata) in zone.iterate_rdatas('A'):
        a_records[name.to_text()] = rdata.to_text()
    for (name, ttl, rdata) in zone.iterate_rdatas('CNAME'):
        cname_records[name.to_text()] = rdata.to_text()


class sqlfoo:

    def __init__(self, domain, subdomain, ip, cname):
        self.domain = domain
        self.subdomain = subdomain
        self.ip = ip
        self.cname = cname
        self.results = results

    def select_a(self, domain, subdomain, ip):
        build_select = """
                        SELECT domain, subdomain, cname, ip 
                        FROM zones 
                        WHERE domain = %s 
                        AND subdomain = %s 
                        AND ip = %s;
                       """
        select_params = [ domain, subdomain, ip ]
        cur.execute(build_select, select_params)
        results = cur.fetchall()
        if not any(results): # if the row isn't found, add it
            print domain, subdomain, ip
            self.insert_a(domain, subdomain, ip)


    def select_cname(self, domain, subdomain, cname):
        build_select = """
                        SELECT domain, subdomain, cname, ip 
                        FROM zones 
                        WHERE domain = %s 
                        AND subdomain = %s 
                        AND cname = %s;
                       """
        select_params = [ domain, subdomain, cname ]
        cur.execute(build_select, select_params)
        results = cur.fetchall()
        if not any(results): # if the row isn't found, add it
            print domain, subdomain, cname
            self.insert_cname(domain, subdomain, cname)

    def insert_a(domain, subdomain, ip):
        build_insert = """
                        INSERT INTO zones
                        (Id,
                         domain,
                         record_type,
                         subdomain,
                         cname,
                         first_seen)
                        VALUES
                        (NULL, %s, `A`, %s, %s, %s);
                       """

        insert_params = [ domain, subdomain, ip, current_epoch ]
        cur.execute(build_insert, insert_params)

    def insert_cname(domain, subdomain, ip):
        build_insert = """
                        INSERT INTO zones
                        (Id,
                         domain,
                         record_type,
                         subdomain,
                         cname,
                         first_seen)
                        VALUES
                        (NULL, %s, `CNAME`, %s, %s, %s);
                       """

        insert_params = [ domain, subdomain, cname, current_epoch ]
        cur.execute(build_insert, insert_params)


main()

cur.close()
conn.close()

When i run the code, i get the following output.

    (venv)[user@server ]$ python zone-etl.py 
    zone xferred
    Traceback (most recent call last):
      File "zone-etl.py", line 125, in <module>
        main()
      File "zone-etl.py", line 42, in main
        sqlfoo.select_a(domain, key, value)
    TypeError: unbound method select_a() must 
be called with sqlfoo instance as first argument (got str instance instead)

You need to create an instance of your class to use the methods. Here's an example:

class Employee:
    def __init__(self, name, salary):
        self.name = name
        self.salary = salary

    def displayEmployee(self):
       print "Name : ", self.name,  ", Salary: ", self.salary

emp = Employee("Aaron", 5000)
emp.displayEmployee()

You have to instantiate your class before using it.

When you call sqlfoo , you should actually do something like:

sqlfoo_instance = sqlfoo(domain_value, subdomain_value, ip_value, cname_value)

...
for key, value in a_records.iteritems():
    sqlfoo.select_a(domain, key, value)
for key, value in cname_records.iteritems():
    sqlfoo.select_cname(domain, key, value)
...

In your case I recommend you to get a little bit more familiar with Object Oriented Programming first, since what you are doing there is only creating more boilerplate code for doing the same thing as you would using procedural programming. Hence, you would reap the benefits of OOP.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM