24 # the label used for alias4/6 hosts |
26 # the label used for alias4/6 hosts |
25 ALIAS4_FMT = '{host}-ipv4' |
27 ALIAS4_FMT = '{host}-ipv4' |
26 ALIAS6_FMT = '{host}-ipv6' |
28 ALIAS6_FMT = '{host}-ipv6' |
27 |
29 |
28 @classmethod |
30 @classmethod |
29 def expand (cls, options, host, range, ip, **opts) : |
31 def expand (cls, options, range, host, domain, ip, **opts) : |
30 host = pvl.dns.zone.parse_generate_field(host) |
32 host = pvl.dns.zone.parse_generate_field(host) |
31 ip = pvl.dns.zone.parse_generate_field(ip) |
33 ip = pvl.dns.zone.parse_generate_field(ip) |
32 |
34 |
33 for i in range : |
35 for i in range : |
34 yield cls.build(options, host(i), |
36 yield cls.build(options, host(i), domain, |
35 ip = ip(i), |
37 ip = ip(i), |
36 **opts |
38 **opts |
37 ) |
39 ) |
38 |
40 |
39 @classmethod |
41 @classmethod |
40 def config (cls, options, host, ip=None, **extra) : |
42 def config (cls, options, host, section=None, domain=None, ip=None, **extra) : |
41 """ |
43 """ |
42 Yield Hosts from a config section's scalars. |
44 Yield Hosts from a config section's scalars. |
43 """ |
45 |
44 |
46 options - pvl.args Options |
|
47 host - the name of the section (or file) containing this host item. |
|
48 section - the parent section containing this host item, or None |
|
49 used for domain |
|
50 """ |
|
51 |
|
52 if domain : |
|
53 log.debug("%s: explicit domain: %s", host, domain) |
|
54 elif options.hosts_domain : |
|
55 log.debug("%s: default domain to --hots-domain: %s", host, options.hosts_domain) |
|
56 domain = options.hosts_domain |
|
57 elif section : |
|
58 log.debug("%s: default domain to section: %s", host, section) |
|
59 domain = section |
|
60 elif '.' in host : |
|
61 log.debug("%s: using as fqdn without domain", host) |
|
62 domain = None |
|
63 else : |
|
64 raise ValueError("%s: no domain given" % (host, )) |
|
65 |
45 if '{' in host : |
66 if '{' in host : |
46 pre, host = host.split('{', 1) |
67 pre, host = host.split('{', 1) |
47 range, post = host.rsplit('}', 1) |
68 range, post = host.rsplit('}', 1) |
48 |
69 |
49 range = pvl.dns.zone.parse_generate_range(range) |
70 range = pvl.dns.zone.parse_generate_range(range) |
50 host = pre + "$" + post |
71 host = pre + "$" + post |
51 |
72 |
52 for host in cls.expand(options, host, range, ip, **extra) : |
73 for host in cls.expand(options, range, host, domain, ip, **extra) : |
53 yield host |
74 yield host |
54 else : |
75 else : |
55 yield cls.build(options, host, ip=ip, **extra) |
76 yield cls.build(options, host, domain, ip=ip, **extra) |
56 |
77 |
57 @classmethod |
78 @classmethod |
58 def build (cls, options, host, domain=None, ip=None, ip6=None, owner=None, boot=None, alias=None, alias4=None, alias6=None, **extra) : |
79 def build (cls, options, host, domain, |
|
80 ip=None, ip6=None, owner=None, boot=None, alias=None, alias4=None, alias6=None, forward=None, reverse=None, |
|
81 **extra) : |
59 """ |
82 """ |
60 Return a Host from a config section's scalars. |
83 Return a Host from a config section's scalars. |
|
84 |
61 """ |
85 """ |
62 |
86 |
63 if alias : |
87 if alias : |
64 alias = alias.split() |
88 alias = alias.split() |
65 else : |
89 else : |
90 for eth in value.split() : |
114 for eth in value.split() : |
91 ethernet[len(ethernet)] = eth |
115 ethernet[len(ethernet)] = eth |
92 else : |
116 else : |
93 raise ValueError("%s: Unknown host field: %s=%s" % (host, field, value)) |
117 raise ValueError("%s: Unknown host field: %s=%s" % (host, field, value)) |
94 |
118 |
95 if domain is None : |
119 |
96 domain = options.hosts_domain |
120 if forward is None : |
|
121 # normal zone |
|
122 pass |
|
123 elif forward : |
|
124 # alias to external zone |
|
125 pass |
|
126 else : |
|
127 # omit |
|
128 forward = False |
97 |
129 |
|
130 if reverse is None : |
|
131 # normal zone |
|
132 pass |
|
133 elif reverse : |
|
134 # alias to external zone |
|
135 pass |
|
136 else : |
|
137 # omit |
|
138 reverse = False |
|
139 |
98 return cls(host, |
140 return cls(host, |
99 domain = domain, |
141 domain = domain, |
100 ip = ipaddr.IPv4Address(ip) if ip else None, |
142 ip = ipaddr.IPv4Address(ip) if ip else None, |
101 ip6 = ipaddr.IPv6Address(ip6) if ip6 else None, |
143 ip6 = ipaddr.IPv6Address(ip6) if ip6 else None, |
102 ethernet = ethernet, |
144 ethernet = ethernet, |
103 alias = alias, |
145 alias = alias, |
104 alias4 = alias4, |
146 alias4 = alias4, |
105 alias6 = alias6, |
147 alias6 = alias6, |
106 owner = owner, |
148 owner = owner, |
107 boot = boot, |
149 boot = boot, |
|
150 forward = forward, |
|
151 reverse = reverse, |
108 ) |
152 ) |
109 |
153 |
110 def __init__ (self, host, domain=None, ip=None, ip6=None, ethernet={ }, alias=(), owner=None, boot=None, alias4=None, alias6=None) : |
154 def __init__ (self, host, |
|
155 domain=None, |
|
156 ip=None, ip6=None, |
|
157 ethernet={ }, |
|
158 alias=(), |
|
159 owner=None, |
|
160 boot=None, |
|
161 alias4=None, alias6=None, |
|
162 forward=None, reverse=None, |
|
163 ) : |
111 """ |
164 """ |
112 host - str |
165 host - str |
113 domain - str |
166 domain - str |
114 ip - ipaddr.IPv4Address |
167 ip - ipaddr.IPv4Address |
115 ip6 - ipaddr.IPv6Address |
168 ip6 - ipaddr.IPv6Address |
116 ethernet - { index: ethernet } |
169 ethernet - { index: ethernet } |
117 alias - list |
170 alias - list |
118 owner - str: LDAP uid |
171 owner - str: LDAP uid |
119 alias4 - list (CNAME -> A) |
172 alias4 - list (CNAME -> A) |
120 alias6 - list (CNAME -> AAAA) |
173 alias6 - list (CNAME -> AAAA) |
121 """ |
174 forward - generate forward records, or CNAME into given zone |
|
175 reverse - generate reverse records, or CNAME into given zone |
|
176 """ |
|
177 |
122 self.host = host |
178 self.host = host |
123 self.domain = domain |
179 self.domain = domain |
124 self.ip = ip |
180 self.ip = ip |
125 self.ip6 = ip6 |
181 self.ip6 = ip6 |
126 self.ethernet = ethernet |
182 self.ethernet = ethernet |
127 self.alias = alias |
183 self.alias = alias |
128 self.alias4 = alias4 |
184 self.alias4 = alias4 |
129 self.alias6 = alias6 |
185 self.alias6 = alias6 |
130 self.owner = owner |
186 self.owner = owner |
131 self.boot = boot |
187 self.boot = boot |
|
188 self.forward = forward |
|
189 self.reverse = reverse |
132 |
190 |
133 def fqdn (self) : |
191 def fqdn (self) : |
134 if '.' in self.host : |
192 if '.' in self.host : |
135 return self.host + '.' |
193 return self.host + '.' |
136 elif self.domain : |
194 elif self.domain : |
139 raise ValueError("%s: have no fqdn/domain" % (self, )) |
197 raise ValueError("%s: have no fqdn/domain" % (self, )) |
140 |
198 |
141 def __str__ (self) : |
199 def __str__ (self) : |
142 return str(self.host) |
200 return str(self.host) |
143 |
201 |
144 def apply_hosts_config (options, config, name, defaults={}) : |
202 def apply_hosts_config (options, config, name, defaults={}, parent=None) : |
145 """ |
203 """ |
146 Load hosts from a ConfigObj section. |
204 Load hosts from a ConfigObj section. |
147 """ |
205 """ |
148 |
206 |
149 scalars = dict((scalar, config[scalar]) for scalar in config.scalars) |
207 scalars = dict((scalar, config[scalar]) for scalar in config.scalars) |
150 |
208 |
151 if config.sections : |
209 if config.sections : |
152 # recurse; this is a domain meta-section |
210 # recurse; this is a domain meta-section |
153 params = dict(defaults, domain=name) |
211 params = dict(defaults) |
154 params.update(**scalars) # override |
212 params.update(**scalars) # override |
155 |
213 |
156 for section in config.sections : |
214 for section in config.sections : |
157 for host in apply_hosts_config(options, config[section], section, params) : |
215 for host in apply_hosts_config(options, config[section], section, params, name) : |
158 yield host |
216 yield host |
159 |
217 |
160 elif name : |
218 elif name : |
161 params = dict(defaults, **scalars) |
219 params = dict(defaults, **scalars) |
162 |
220 |
163 # this is a host section |
221 # this is a host section |
164 for host in Host.config(options, name, **params) : |
222 for host in Host.config(options, name, parent, **params) : |
165 yield host |
223 yield host |
166 |
224 |
167 else : |
225 else : |
168 raise ValueError("No sections in config") |
226 raise ValueError("No sections in config") |
169 |
227 |