1#
2#  setup.py for easyzone package
3#
4#  Created by Chris Miles on 2007-01-29.
5#  Copyright (c) 2007-2011 Chris Miles. All rights reserved.
6#
7
8try:
9    from setuptools import setup, Command
10    use_setuptools = True
11except ImportError:
12    from distutils.core import setup, Command
13    use_setuptools = False
14
15from glob import glob
16import os
17import sys
18from unittest import TextTestRunner, TestLoader
19
20from easyzone.easyzone import __version__
21
22
23class TestCommand(Command):
24    user_options = []
25
26    def initialize_options(self):
27        self._dir = os.getcwd()
28
29    def finalize_options(self):
30        build = self.get_finalized_command('build')
31        self.build_purelib = build.build_purelib
32        self.build_platlib = build.build_platlib
33
34    def run(self):
35        '''Finds all the tests modules in tests/, and runs them.
36        '''
37        sys.path.insert(0, self.build_purelib)
38        sys.path.insert(0, self.build_platlib)
39
40        testfiles = []
41        for t in glob(os.path.join(self._dir, 'tests', '*.py')):
42            if not t.endswith('__init__.py'):
43                testfiles.append('.'.join(
44                    ['tests', os.path.splitext(os.path.basename(t))[0]])
45                )
46
47        tests = TestLoader().loadTestsFromNames(testfiles)
48        t = TextTestRunner(verbosity = 2)
49        t.run(tests)
50
51
52class CleanCommand(Command):
53    user_options = []
54
55    def initialize_options(self):
56        self._clean_me = []
57        for root, dirs, files in os.walk('.'):
58            for f in files:
59                if f.endswith('.pyc'):
60                    self._clean_me.append(os.path.join(root, f))
61
62    def finalize_options(self):
63        pass
64
65    def run(self):
66        for clean_me in self._clean_me:
67            try:
68                os.unlink(clean_me)
69            except:
70                pass
71
72
73
74setup_args = dict(
75    name = 'easyzone',
76    version = __version__,
77    author = 'Chris Miles',
78    author_email = 'miles.chris@gmail.com',
79    description = 'Easy Zone - DNS Zone abstraction module',
80    long_description = '''\
81easyzone
82========
83
84Overview
85--------
86
87Easyzone is a package to manage the common record types of a
88zone file, including SOA records.  This module sits on top of
89the dnspython package and provides a higher level abstraction
90for common zone file manipulation use cases.
91
92http://www.psychofx.com/easyzone/
93http://pypi.python.org/pypi/easyzone
94https://bitbucket.org/chrismiles/easyzone/
95
96
97Main features:
98
99* A high-level abstraction on top of dnspython.
100* Load a zone file into objects.
101* Modify/add/delete zone/record objects.
102* Save back to zone file.
103* Auto-update serial (if necessary).
104
105
106Requirements
107------------
108
109  * dnspython - http://www.dnspython.org/
110
111
112Build/Test/Install
113------------------
114
115Build::
116
117  $ python setup.py build
118
119Test::
120
121  $ python setup.py test
122
123Install::
124
125  $ python setup.py install
126
127
128OR with setuptools::
129
130  $ easy_install easyzone
131
132
133Examples
134--------
135
136easyzone::
137
138  >>> from easyzone import easyzone
139  >>> z = easyzone.zone_from_file('example.com', '/var/namedb/example.com')
140  >>> z.domain
141  'example.com.'
142  >>> z.root.soa.serial
143  2007012902L
144  >>> z.root.records('NS').items
145  ['ns1.example.com.', 'ns2.example.com.']
146  >>> z.root.records('MX').items
147  [(10, 'mail.example.com.'), (20, 'mail2.example.com.')]
148  >>> z.names['foo.example.com.'].records('A').items
149  ['10.0.0.1']
150
151  >>> ns = z.root.records('NS')
152  >>> ns.add('ns3.example.com.')
153  >>> ns.items
154  ['ns1.example.com.', 'ns2.example.com.', 'ns3.example.com.']
155  >>> ns.delete('ns2.example.com')
156  >>> ns.items
157  ['ns1.example.com.', 'ns3.example.com.']
158
159  >>> z.save(autoserial=True)
160
161ZoneCheck::
162
163  >>> from easyzone.zone_check import ZoneCheck
164  >>> c = ZoneCheck()
165  >>> c.isValid('example.com', '/var/named/zones/example.com')
166  True
167  >>> c.isValid('foo.com', '/var/named/zones/example.com')
168  False
169  >>> c.error
170  'Bad syntax'
171  >>>
172  >>> c = ZoneCheck(checkzone='/usr/sbin/named-checkzone')
173  >>> c.isValid('example.com', '/var/named/zones/example.com')
174  True
175  >>>
176
177ZoneReload::
178
179  >>> from easyzone.zone_reload import ZoneReload
180  >>> r = ZoneReload()
181  >>> r.reload('example.com')
182  zone reload up-to-date
183  >>> r.reload('foo.com')
184  rndc: 'reload' failed: not found
185  Traceback (most recent call last):
186    File "<stdin>", line 1, in <module>
187    File "easyzone/zone_reload.py", line 51, in reload
188      raise ZoneReloadError("rndc failed with return code %d" % r)
189  easyzone.zone_reload.ZoneReloadError: rndc failed with return code 1
190  >>>
191  >>> r = ZoneReload(rndc='/usr/sbin/rndc')
192  >>> r.reload('example.com')
193  zone reload up-to-date
194  >>>
195''',
196    url = 'http://www.psychofx.com/easyzone/',
197    packages = ['easyzone'],
198    cmdclass = { 'test': TestCommand, 'clean': CleanCommand },
199)
200
201if use_setuptools:
202    setup_args.update(dict(
203        classifiers=[
204            "Development Status :: 4 - Beta",
205            "License :: OSI Approved :: MIT License",
206            "Topic :: Internet :: Name Service (DNS)",
207            "Topic :: System :: Systems Administration",
208        ], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
209        keywords='',
210        license='MIT',
211        include_package_data=True,
212        zip_safe=False,
213        install_requires=[
214            # -*- Extra requirements: -*-
215            "dnspython",
216        ],
217        entry_points="""
218        # -*- Entry points: -*-
219        """,
220    ))
221
222setup(**setup_args)
223