construqt 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/lib/construqt/addresses.rb +204 -0
  3. data/lib/construqt/bgps.rb +164 -0
  4. data/lib/construqt/cables.rb +47 -0
  5. data/lib/construqt/firewalls.rb +247 -0
  6. data/lib/construqt/flavour/ciscian/ciscian.rb +687 -0
  7. data/lib/construqt/flavour/ciscian/dialect_dlink-dgs15xx.rb +235 -0
  8. data/lib/construqt/flavour/ciscian/dialect_hp-2510g.rb +114 -0
  9. data/lib/construqt/flavour/delegates.rb +448 -0
  10. data/lib/construqt/flavour/flavour.rb +97 -0
  11. data/lib/construqt/flavour/mikrotik/flavour_mikrotik.rb +417 -0
  12. data/lib/construqt/flavour/mikrotik/flavour_mikrotik_bgp.rb +134 -0
  13. data/lib/construqt/flavour/mikrotik/flavour_mikrotik_interface.rb +79 -0
  14. data/lib/construqt/flavour/mikrotik/flavour_mikrotik_ipsec.rb +65 -0
  15. data/lib/construqt/flavour/mikrotik/flavour_mikrotik_result.rb +182 -0
  16. data/lib/construqt/flavour/mikrotik/flavour_mikrotik_schema.rb +355 -0
  17. data/lib/construqt/flavour/plantuml/plantuml.rb +462 -0
  18. data/lib/construqt/flavour/ubuntu/flavour_ubuntu.rb +381 -0
  19. data/lib/construqt/flavour/ubuntu/flavour_ubuntu_bgp.rb +117 -0
  20. data/lib/construqt/flavour/ubuntu/flavour_ubuntu_dns.rb +97 -0
  21. data/lib/construqt/flavour/ubuntu/flavour_ubuntu_firewall.rb +300 -0
  22. data/lib/construqt/flavour/ubuntu/flavour_ubuntu_ipsec.rb +144 -0
  23. data/lib/construqt/flavour/ubuntu/flavour_ubuntu_opvn.rb +60 -0
  24. data/lib/construqt/flavour/ubuntu/flavour_ubuntu_result.rb +537 -0
  25. data/lib/construqt/flavour/ubuntu/flavour_ubuntu_services.rb +115 -0
  26. data/lib/construqt/flavour/ubuntu/flavour_ubuntu_vrrp.rb +52 -0
  27. data/lib/construqt/flavour/unknown/unknown.rb +175 -0
  28. data/lib/construqt/hostid.rb +42 -0
  29. data/lib/construqt/hosts.rb +98 -0
  30. data/lib/construqt/interfaces.rb +166 -0
  31. data/lib/construqt/ipsecs.rb +64 -0
  32. data/lib/construqt/networks.rb +81 -0
  33. data/lib/construqt/regions.rb +32 -0
  34. data/lib/construqt/resource.rb +42 -0
  35. data/lib/construqt/services.rb +53 -0
  36. data/lib/construqt/tags.rb +61 -0
  37. data/lib/construqt/templates.rb +37 -0
  38. data/lib/construqt/tests/test_addresses.rb +50 -0
  39. data/lib/construqt/tests/test_bgps.rb +24 -0
  40. data/lib/construqt/tests/test_hostid.rb +32 -0
  41. data/lib/construqt/tests/test_hosts.rb +23 -0
  42. data/lib/construqt/tests/test_utils.rb +76 -0
  43. data/lib/construqt/users.rb +19 -0
  44. data/lib/construqt/util.rb +163 -0
  45. data/lib/construqt/version.rb +3 -0
  46. data/lib/construqt/vlans.rb +51 -0
  47. data/lib/construqt.rb +92 -0
  48. metadata +105 -0
@@ -0,0 +1,381 @@
1
+
2
+ require_relative 'flavour_ubuntu_dns.rb'
3
+ require_relative 'flavour_ubuntu_ipsec.rb'
4
+ require_relative 'flavour_ubuntu_bgp.rb'
5
+ require_relative 'flavour_ubuntu_opvn.rb'
6
+ require_relative 'flavour_ubuntu_vrrp.rb'
7
+ require_relative 'flavour_ubuntu_firewall.rb'
8
+ require_relative 'flavour_ubuntu_result.rb'
9
+ require_relative 'flavour_ubuntu_services.rb'
10
+
11
+ module Construqt
12
+ module Flavour
13
+ module Ubuntu
14
+ def self.name
15
+ 'ubuntu'
16
+ end
17
+
18
+ Flavour.add(self)
19
+
20
+ # class Interface < OpenStruct
21
+ # def initialize(cfg)
22
+ # super(cfg)
23
+ # end
24
+
25
+ # def build_config(host, iface)
26
+ # self.clazz.build_config(host, iface||self)
27
+ # end
28
+
29
+ # end
30
+
31
+ class Device < OpenStruct
32
+ def initialize(cfg)
33
+ super(cfg)
34
+ end
35
+
36
+ def self.add_address(host, ifname, iface, lines, writer)
37
+ if iface.address.nil?
38
+ Firewall.create(host, ifname, iface)
39
+ return
40
+ end
41
+
42
+ writer.header.mode(EtcNetworkInterfaces::Entry::Header::MODE_DHCP) if iface.address.dhcpv4?
43
+ writer.header.mode(EtcNetworkInterfaces::Entry::Header::MODE_LOOPBACK) if iface.address.loopback?
44
+ lines.add(iface.flavour) if iface.flavour
45
+ iface.address.ips.each do |ip|
46
+ lines.up("ip addr add #{ip.to_string} dev #{ifname}")
47
+ lines.down("ip addr del #{ip.to_string} dev #{ifname}")
48
+ end
49
+
50
+ iface.address.routes.each do |route|
51
+ if route.metric
52
+ metric = " metric #{route.metric}"
53
+ else
54
+ metric = ""
55
+ end
56
+ lines.up("ip route add #{route.dst.to_string} via #{route.via.to_s}#{metric}")
57
+ lines.down("ip route del #{route.dst.to_string} via #{route.via.to_s}#{metric}")
58
+ end
59
+
60
+ Firewall.create(host, ifname, iface)
61
+ end
62
+
63
+ def build_config(host, iface)
64
+ self.class.build_config(host, iface)
65
+ end
66
+
67
+ def self.add_services(host, ifname, iface, writer)
68
+ iface.services && iface.services.each do |service|
69
+ Services.get_renderer(service).interfaces(host, ifname, iface, writer)
70
+ end
71
+ end
72
+
73
+ def self.build_config(host, iface)
74
+ # binding.pry
75
+ writer = host.result.etc_network_interfaces.get(iface)
76
+ writer.header.protocol(EtcNetworkInterfaces::Entry::Header::PROTO_INET4)
77
+ #binding.pry #unless iface.delegate
78
+ writer.lines.add(iface.delegate.flavour) if iface.delegate.flavour
79
+ ifname = writer.header.get_interface_name
80
+ # ifaces.header.mode(Result::EtcNetworkInterfaces::Entry::Header::MODE_DHCP4) if iface.address.dhcpv4?
81
+ # ifaces.header.mode(Result::EtcNetworkInterfaces::Entry::Header::MODE_LOOOPBACK) if iface.address.loopback?
82
+ writer.lines.up("ip link set mtu #{iface.delegate.mtu} dev #{ifname} up")
83
+ writer.lines.down("ip link set dev #{ifname} down")
84
+ add_address(host, ifname, iface.delegate, writer.lines, writer) #unless iface.address.nil? || iface.address.ips.empty?
85
+ add_services(host, ifname, iface.delegate, writer)
86
+ end
87
+ end
88
+
89
+ class Bond < OpenStruct
90
+ def initialize(cfg)
91
+ super(cfg)
92
+ end
93
+
94
+ def build_config(host, bond)
95
+ bond_delegate = bond.delegate
96
+ bond_delegate.interfaces.each do |i|
97
+ host.result.etc_network_interfaces.get(i).lines.add("bond-master #{bond_delegate.name}")
98
+ end
99
+
100
+ mac_address = bond_delegate.mac_address || Construqt::Util.generate_mac_address_from_name("#{host.name} #{bond_delegate.name}")
101
+ host.result.etc_network_interfaces.get(bond_delegate).lines.add(<<BOND)
102
+ pre-up ip link set dev #{bond_delegate.name} mtu #{bond_delegate.mtu} address #{mac_address}
103
+ bond-mode #{bond_delegate.mode||'active-backup'}
104
+ bond-miimon 100
105
+ bond-lacp-rate 1
106
+ bond-slaves none
107
+ BOND
108
+ Device.build_config(host, bond)
109
+ end
110
+ end
111
+
112
+ class Vlan < OpenStruct
113
+ def initialize(cfg)
114
+ super(cfg)
115
+ end
116
+
117
+ def build_config(host, iface)
118
+ vlan = iface.name.split('.')
119
+ throw "vlan name not valid if.# => #{iface.name}" if vlan.length != 2 ||
120
+ !vlan.first.match(/^[0-9a-zA-Z]+$/) ||
121
+ !vlan.last.match(/^[0-9]+/) ||
122
+ !(1 <= vlan.last.to_i && vlan.last.to_i < 4096)
123
+ Device.build_config(host, iface)
124
+ end
125
+ end
126
+
127
+ class Bridge < OpenStruct
128
+ def initialize(cfg)
129
+ super(cfg)
130
+ end
131
+
132
+ def build_config(host, iface)
133
+ port_list = iface.interfaces.map { |i| i.name }.join(",")
134
+ host.result.etc_network_interfaces.get(iface).lines.add("bridge_ports #{port_list}")
135
+ Device.build_config(host, iface)
136
+ end
137
+ end
138
+
139
+ class Host < OpenStruct
140
+ def initialize(cfg)
141
+ super(cfg)
142
+ end
143
+
144
+ def build_config(host, unused)
145
+ host.result.add(self, <<SCTL, Construqt::Resources::Rights::ROOT_0644, "etc", "sysctl.conf")
146
+ net.ipv4.conf.all.forwarding = 1
147
+ net.ipv4.conf.default.forwarding = 1
148
+ net.ipv4.vs.pmtu_disc=1
149
+
150
+ net.ipv6.conf.all.autoconf=0
151
+ net.ipv6.conf.all.accept_ra=0
152
+ net.ipv6.conf.all.forwarding=1
153
+ SCTL
154
+ host.result.add(self, <<HOSTS, Construqt::Resources::Rights::ROOT_0644, "etc", "hosts")
155
+ 127.0.0.1 localhost
156
+ ::1 localhost ip6-localhost ip6-loopback
157
+ fe00::0 ip6-localnet
158
+ ff00::0 ip6-mcastprefix
159
+ ff02::1 ip6-allnodes
160
+ ff02::2 ip6-allrouters
161
+
162
+ 127.0.1.1 #{host.name} #{host.region.network.fqdn(host.name)}
163
+ HOSTS
164
+ host.result.add(self, host.name, Construqt::Resources::Rights::ROOT_0644, "etc", "hostname")
165
+ host.result.add(self, "# WTF resolvconf", Construqt::Resources::Rights::ROOT_0644, "etc", "resolvconf", "resolv.conf.d", "orignal");
166
+ host.result.add(self,
167
+ (host.region.network.dns_resolver.nameservers.ips.map{|i| "nameserver #{i.to_s}" }+
168
+ ["search #{host.region.network.dns_resolver.search.join(' ')}"]).join("\n"),
169
+ Construqt::Resources::Rights::ROOT_0644, "etc", "resolv.conf")
170
+ #binding.pry
171
+ Dns.build_config(host) if host.delegate.dns_server
172
+ akeys = []
173
+ ykeys = []
174
+ skeys = []
175
+ host.region.users.all.each do |u|
176
+ akeys << u.public_key if u.public_key
177
+ ykeys << "#{u.name}:#{u.yubikey}" if u.yubikey
178
+ skeys << "#{u.shadow}" if u.shadow
179
+ end
180
+
181
+ host.result.add(self, skeys.join(), Construqt::Resources::Rights::ROOT_0644, "etc", "shadow.merge")
182
+ host.result.add(self, akeys.join(), Construqt::Resources::Rights::ROOT_0644, "root", ".ssh", "authorized_keys")
183
+ host.result.add(self, ykeys.join("\n"), Construqt::Resources::Rights::ROOT_0644, "etc", "yubikey_mappings")
184
+
185
+ host.result.add(self, <<SSH , Construqt::Resources::Rights::ROOT_0644, "etc", "ssh", "sshd_config")
186
+ # Package generated configuration file
187
+ # See the sshd_config(5) manpage for details
188
+
189
+ # What ports, IPs and protocols we listen for
190
+ Port 22
191
+ # Use these options to restrict which interfaces/protocols sshd will bind to
192
+ #ListenAddress ::
193
+ #ListenAddress 0.0.0.0
194
+ Protocol 2
195
+ # HostKeys for protocol version 2
196
+ HostKey /etc/ssh/ssh_host_rsa_key
197
+ HostKey /etc/ssh/ssh_host_dsa_key
198
+ HostKey /etc/ssh/ssh_host_ecdsa_key
199
+ HostKey /etc/ssh/ssh_host_ed25519_key
200
+ #Privilege Separation is turned on for security
201
+ UsePrivilegeSeparation yes
202
+
203
+ # Lifetime and size of ephemeral version 1 server key
204
+ KeyRegenerationInterval 3600
205
+ ServerKeyBits 1024
206
+
207
+ # Logging
208
+ SyslogFacility AUTH
209
+ LogLevel INFO
210
+
211
+ # Authentication:
212
+ LoginGraceTime 120
213
+ PermitRootLogin without-password
214
+ StrictModes yes
215
+
216
+ RSAAuthentication yes
217
+ PubkeyAuthentication yes
218
+ #AuthorizedKeysFile %h/.ssh/authorized_keys
219
+
220
+ # Don't read the user's ~/.rhosts and ~/.shosts files
221
+ IgnoreRhosts yes
222
+ # For this to work you will also need host keys in /etc/ssh_known_hosts
223
+ RhostsRSAAuthentication no
224
+ # similar for protocol version 2
225
+ HostbasedAuthentication no
226
+ # Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
227
+ #IgnoreUserKnownHosts yes
228
+
229
+ # To enable empty passwords, change to yes (NOT RECOMMENDED)
230
+ PermitEmptyPasswords no
231
+
232
+ # Change to yes to enable challenge-response passwords (beware issues with
233
+ # some PAM modules and threads)
234
+ ChallengeResponseAuthentication no
235
+
236
+ # Change to no to disable tunnelled clear text passwords
237
+ PasswordAuthentication no
238
+
239
+ # Kerberos options
240
+ #KerberosAuthentication no
241
+ #KerberosGetAFSToken no
242
+ #KerberosOrLocalPasswd yes
243
+ #KerberosTicketCleanup yes
244
+
245
+ # GSSAPI options
246
+ #GSSAPIAuthentication no
247
+ #GSSAPICleanupCredentials yes
248
+
249
+ X11Forwarding yes
250
+ X11DisplayOffset 10
251
+ PrintMotd no
252
+ PrintLastLog yes
253
+ TCPKeepAlive yes
254
+ #UseLogin no
255
+
256
+ #MaxStartups 10:30:60
257
+ #Banner /etc/issue.net
258
+
259
+ # Allow client to pass locale environment variables
260
+ AcceptEnv LANG LC_*
261
+
262
+ Subsystem sftp /usr/lib/openssh/sftp-server
263
+
264
+ # Set this to 'yes' to enable PAM authentication, account processing,
265
+ # and session processing. If this is enabled, PAM authentication will
266
+ # be allowed through the ChallengeResponseAuthentication and
267
+ # PasswordAuthentication. Depending on your PAM configuration,
268
+ # PAM authentication via ChallengeResponseAuthentication may bypass
269
+ # the setting of "PermitRootLogin without-password".
270
+ # If you just want the PAM account and session checks to run without
271
+ # PAM authentication, then enable this but set PasswordAuthentication
272
+ # and ChallengeResponseAuthentication to 'no'.
273
+ UsePAM yes
274
+ SSH
275
+ host.result.add(self, <<PAM , Construqt::Resources::Rights::ROOT_0644, "etc", "pam.d", "openvpn")
276
+ #{host.delegate.yubikey ? '':'# '}auth required pam_yubico.so id=16 authfile=/etc/yubikey_mappings
277
+ auth [success=1 default=ignore] pam_unix.so nullok_secure try_first_pass
278
+ auth requisite pam_deny.so
279
+
280
+ @include common-account
281
+ @include common-session-noninteractive
282
+ PAM
283
+ #binding.pry
284
+ host.delegate.files && host.delegate.files.each do |file|
285
+ if host.result.replace(nil, file.data, file.right, *file.path)
286
+ Construqt.logger.warn("the file #{file.path} was overriden!")
287
+ end
288
+ end
289
+ end
290
+ end
291
+
292
+ class Gre < OpenStruct
293
+ def initialize(cfg)
294
+ super(cfg)
295
+ end
296
+
297
+ def build_config(host, gre)
298
+ gre_delegate = gre.delegate
299
+ # binding.pry
300
+ cfg = nil
301
+ if gre_delegate.local.first_ipv6
302
+ cfg = OpenStruct.new(:prefix=>6, :my=>gre_delegate.local.first_ipv6, :other => gre_delegate.remote.first_ipv6, :mode => "ip6gre")
303
+ elsif gre_delegate.local.first_ipv4
304
+ cfg = OpenStruct.new(:prefix=>4, :my=>gre_delegate.local.first_ipv4, :other => gre_delegate.remote.first_ipv4, :mode => "ipgre")
305
+ end
306
+
307
+ throw "need a local address #{host.name}:#{gre_delegate.name}" unless cfg
308
+ local_iface = host.interfaces.values.find { |iface| iface.address.match_network(cfg.my) }
309
+ throw "need a interface with address #{host.name}:#{cfg.my}" unless local_iface
310
+ iname = Util.clean_if("gt#{cfg.prefix}", gre_delegate.name)
311
+
312
+ writer_local = host.result.etc_network_interfaces.get(local_iface)
313
+ writer_local.lines.up("/bin/bash /etc/network/#{iname}-up.iface")
314
+ writer_local.lines.down("/bin/bash /etc/network/#{iname}-down.iface")
315
+
316
+
317
+ writer = host.result.etc_network_interfaces.get(gre_delegate)
318
+ writer.skip_interfaces.header.interface_name(iname)
319
+ writer.lines.up("ip -#{cfg.prefix} tunnel add #{iname} mode #{cfg.mode} local #{cfg.my.to_s} remote #{cfg.other.to_s}")
320
+ # writer.lines.up("ip -#{cfg.prefix} link set dev #{iname} up")
321
+ Device.build_config(host, gre)
322
+ # Device.add_address(host, iname, iface, writer.lines, writer)
323
+ writer.lines.down("ip -#{cfg.prefix} tunnel del #{iname}")
324
+ end
325
+ end
326
+
327
+ class Template < OpenStruct
328
+ def initialize(cfg)
329
+ super(cfg)
330
+ end
331
+
332
+ def build_config(host, iface)
333
+ end
334
+ end
335
+
336
+ def self.clazzes
337
+ {
338
+ "opvn" => Opvn,
339
+ "gre" => Gre,
340
+ "host" => Host,
341
+ "device"=> Device,
342
+ "vrrp" => Vrrp,
343
+ "bridge" => Bridge,
344
+ "bond" => Bond,
345
+ "vlan" => Vlan,
346
+ "result" => Result,
347
+ "ipsec" => Ipsec,
348
+ "bgp" => Bgp,
349
+ "template" => Template
350
+ }
351
+ end
352
+
353
+ def self.clazz(name)
354
+ ret = self.clazzes[name]
355
+ throw "class not found #{name}" unless ret
356
+ ret
357
+ end
358
+
359
+ def self.create_host(name, cfg)
360
+ cfg['name'] = name
361
+ cfg['result'] = nil
362
+ host = Host.new(cfg)
363
+ host.result = Result.new(host)
364
+ host
365
+ end
366
+
367
+ def self.create_interface(name, cfg)
368
+ cfg['name'] = name
369
+ clazz(cfg['clazz']).new(cfg)
370
+ end
371
+
372
+ def self.create_bgp(cfg)
373
+ Bgp.new(cfg)
374
+ end
375
+
376
+ def self.create_ipsec(cfg)
377
+ Ipsec.new(cfg)
378
+ end
379
+ end
380
+ end
381
+ end
@@ -0,0 +1,117 @@
1
+ module Construqt
2
+ module Flavour
3
+ module Ubuntu
4
+
5
+ class Bgp < OpenStruct
6
+ def initialize(cfg)
7
+ super(cfg)
8
+ end
9
+
10
+ def self.header(host)
11
+ addrs = {}
12
+ host.interfaces.values.each do |iface|
13
+ iface = iface.delegate
14
+ next unless iface.cfg
15
+ next unless iface.cfg.kind_of? Construqt::Bgp
16
+ addrs[iface.name] = iface
17
+ end
18
+ return if addrs.empty?
19
+ bird_v4 = self.header_bird(host, OpenStruct.new(:net_clazz => IPAddress::IPv4, :filter => lambda {|ip| ip.ipv4? }))
20
+ host.result.add(self, bird_v4, Construqt::Resources::Rights::ROOT_0644, "etc", "bird", "bird.conf")
21
+ bird_v6 = self.header_bird(host, OpenStruct.new(:net_clazz => IPAddress::IPv6, :filter => lambda {|ip| ip.ipv6? }))
22
+ host.result.add(self, bird_v6, Construqt::Resources::Rights::ROOT_0644, "etc", "bird", "bird6.conf")
23
+ end
24
+
25
+ def self.header_bird(host, mode)
26
+ # binding.pry
27
+ ret = <<BGP
28
+ log syslog { debug, trace, info, remote, warning, error, auth, fatal, bug };
29
+ router id #{host.id.first_ipv4.first_ipv4.to_s};
30
+ protocol device {
31
+ }
32
+ protocol direct {
33
+ }
34
+ protocol kernel {
35
+ learn;
36
+ persist; # Don't remove routes on bird shutdown
37
+ scan time 20; # Scan kernel routing table every 20 seconds
38
+ export all; # Default is export none
39
+ }
40
+ protocol static {
41
+ }
42
+
43
+ BGP
44
+ Bgps.filters.each do |filter|
45
+ ret = ret + "filter filter_#{filter.name} {\n"
46
+ filter.list.each do |rule|
47
+ nets = rule['network']
48
+ if nets.kind_of?(String)
49
+ nets = Construqt::Tags.find(nets, mode.net_clazz)
50
+ # puts ">>>>>>>>>> #{nets.map{|i| i.class.name}}"
51
+ nets = IPAddress::summarize(nets)
52
+ else
53
+ nets = nets.ips
54
+ end
55
+
56
+ nets.each do |ip|
57
+ next unless mode.filter.call(ip)
58
+ ip_str = ip.to_string
59
+ if rule['prefix_length']
60
+ ip_str = "#{ip.to_string}{#{rule['prefix_length'].first},#{rule['prefix_length'].last}}"
61
+ end
62
+
63
+ ret = ret + " if net ~ [ #{ip_str} ] then { print \"#{rule['rule']}:\",net; #{rule['rule']}; }\n"
64
+ end
65
+ end
66
+
67
+ ret = ret + "}\n\n"
68
+ end
69
+
70
+ ret
71
+ end
72
+
73
+ def build_bird_conf
74
+ if self.my.address.first_ipv4 && self.other.my.address.first_ipv4
75
+ self.my.host.result.add(self, <<BGP, Construqt::Resources::Rights::ROOT_0644, "etc", "bird", "bird.conf")
76
+ protocol bgp #{Util.clean_bgp(self.my.host.name)}_#{Util.clean_bgp(self.other.host.name)} {
77
+ description "#{self.my.host.name} <=> #{self.other.host.name}";
78
+ direct;
79
+ next hop self;
80
+ #{self.as == self.other.as ? '' : '#'}rr client;
81
+ local #{self.my.address.first_ipv4} as #{self.as.num};
82
+ neighbor #{self.other.my.address.first_ipv4} as #{self.other.as.num};
83
+ password "#{Util.password(self.cfg.password)}";
84
+ import #{self.filter['in'] ? "filter filter_"+self.filter['in'].name : "all"};
85
+ export #{self.filter['out'] ? "filter filter_"+self.filter['out'].name : "all"};
86
+ }
87
+ BGP
88
+ end
89
+ end
90
+
91
+ def build_bird6_conf
92
+ # binding.pry
93
+ if self.my.address.first_ipv6 && self.other.my.address.first_ipv6
94
+ self.my.host.result.add(self, <<BGP, Construqt::Resources::Rights::ROOT_0644, "etc", "bird", "bird6.conf")
95
+ protocol bgp #{Util.clean_bgp(self.my.host.name)}_#{Util.clean_bgp(self.other.host.name)} {
96
+ description "#{self.my.host.name} <=> #{self.other.host.name}";
97
+ direct;
98
+ next hop self;
99
+ #{self.as == self.other.as ? '' : '#'}rr client;
100
+ local as #{self.as.num};
101
+ neighbor #{self.other.my.address.first_ipv6} as #{self.other.as.num};
102
+ password "#{Util.password(self.cfg.password)}";
103
+ import #{self.filter['in'] ? "filter filter_"+self.filter['in'].name : "all"};
104
+ export #{self.filter['out'] ? "filter filter_"+self.filter['out'].name : "all"};
105
+ }
106
+ BGP
107
+ end
108
+ end
109
+
110
+ def build_config(unused, unused1)
111
+ build_bird_conf
112
+ build_bird6_conf
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,97 @@
1
+ module Construqt
2
+ module Flavour
3
+
4
+ module Ubuntu
5
+ module Dns
6
+
7
+ def self.write_header(region, domain)
8
+ ret = [<<OUT]
9
+ ; this is a generated file do not edit!!!!!
10
+ ; for #{domain.to_s}
11
+ $TTL 86400 ; 1 day
12
+ #{domain}. IN SOA ns.#{region.network.domain}. #{region.network.contact}. (
13
+ #{Time.now.to_i} ; serial
14
+ 10000 ; refresh (2 hours 46 minutes 40 seconds)
15
+ 3600 ; retry (1 hour)
16
+ 604800 ; expire (1 week)
17
+ 28800 ; minimum (8 hours)
18
+ )
19
+ OUT
20
+ region.hosts.get_hosts.each do |host|
21
+ next unless host.delegate.dns_server
22
+ plain_adr = region.network.addresses.all.find{|i| i.name! == host.name }
23
+ unless plain_adr
24
+ plain_adr = host.id.first_ipv6
25
+ end
26
+
27
+ binding.pry unless plain_adr.name
28
+
29
+ ret << "#{domain}. 3600 IN NS #{region.network.fqdn(plain_adr.name)}."
30
+ #if (domain == Addresses.domain)
31
+ # ret << "#{host.id.first_ipv6.fqdn}. 3600 IN A #{host.id.first_ipv4}" if host.id.first_ipv4
32
+ # ret << "#{host.id.first_ipv6.fqdn}. 3600 IN AAAA #{host.id.first_ipv6}" if host.id.first_ipv6
33
+ #end
34
+ end
35
+
36
+ ret << ""
37
+ ret.join("\n")
38
+ end
39
+
40
+ def self.build_config(host)
41
+ forward = {}
42
+ reverse = {}
43
+ host.region.network.addresses.all.each do |address|
44
+ next unless address
45
+ next if address.ips.empty?
46
+ unless address.name!
47
+ Construqt.logger.warn "unreference address #{address.ips.map{|i| i.to_string}}"
48
+ next
49
+ end
50
+ name = host.region.network.fqdn(address.name!)
51
+ domain = host.region.network.domain
52
+ forward[domain] ||= []
53
+ address.ips.each do |ip|
54
+ next if ip.to_i == ip.network.to_i && ((ip.ipv6? && ip.prefix < 128) || (ip.ipv4? && ip.prefix < 32))
55
+ forward[domain] << "#{"%-42s" % "#{name}."} 3600 IN #{ip.ipv4? ? 'A' : 'AAAA'} #{ip.to_s}"
56
+ if ip.ipv4?
57
+ forward[domain] << "#{"ipv4-%-37s" % "#{name}."} 3600 IN A #{ip.to_s}"
58
+ end
59
+
60
+ if ip.ipv6?
61
+ forward[domain] << "#{"ipv6-%-37s" % "#{name}."} 3600 IN AAAA #{ip.to_s}"
62
+ end
63
+
64
+ network = host.region.network.to_network(ip.network)
65
+ reverse[network] ||= {}
66
+ reverse[network][ip.reverse.to_s] ||= "#{ip.reverse} 3600 IN PTR #{name}."
67
+ end
68
+ end
69
+
70
+ include = {}
71
+ forward.each do |domain, lines|
72
+ include[domain] = "/etc/bind/tables/#{domain}.forward"
73
+ host.result.add(self, write_header(host.region, domain), Construqt::Resources::Rights::ROOT_0644, "etc/bind/tables", "#{domain}.forward")
74
+ host.result.add(self, lines.sort.join("\n"), Construqt::Resources::Rights::ROOT_0644, "etc/bind/tables", "#{domain}.forward")
75
+ end
76
+
77
+ reverse.each do |domain, lines|
78
+ include[domain.rev_domains.first] = "/etc/bind/tables/#{domain}.reverse"
79
+ host.result.add(self, write_header(host.region, domain.rev_domains.first), Construqt::Resources::Rights::ROOT_0644, "etc/bind/tables", "#{domain.to_s}.reverse")
80
+ host.result.add(self, lines.values.sort.join("\n"), Construqt::Resources::Rights::ROOT_0644, "etc/bind/tables", "#{domain.to_s}.reverse")
81
+ end
82
+
83
+ include.each do |domain,path|
84
+ host.result.add(self, <<DNS, Construqt::Resources::Rights::ROOT_0644, "etc/bind/named.conf.local")
85
+ zone "#{domain.to_s}" {
86
+ type master;
87
+ file "#{path}";
88
+ notify yes;
89
+ allow-query { any; };
90
+ };
91
+ DNS
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end