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,537 @@
1
+
2
+ module Construqt
3
+ module Flavour
4
+ module Ubuntu
5
+
6
+ class EtcNetworkIptables
7
+ def initialize
8
+ @mangle = Section.new('mangle')
9
+ @nat = Section.new('nat')
10
+ @raw = Section.new('raw')
11
+ @filter = Section.new('filter')
12
+ end
13
+
14
+ class Section
15
+ class Block
16
+ def initialize(section)
17
+ @section = section
18
+ @rows = []
19
+ end
20
+
21
+ class Row
22
+ include Util::Chainable
23
+ chainable_attr_value :row, nil
24
+ chainable_attr_value :table, nil
25
+ chainable_attr_value :chain, nil
26
+ end
27
+
28
+ class RowFactory
29
+ include Util::Chainable
30
+ chainable_attr_value :table, nil
31
+ chainable_attr_value :chain, nil
32
+ chainable_attr_value :rows, nil
33
+ def create
34
+ ret = Row.new.table(get_table).chain(get_chain)
35
+ get_rows.push(ret)
36
+ ret
37
+ end
38
+ end
39
+
40
+ def table(table, chain = nil)
41
+ RowFactory.new.rows(@rows).table(table).chain(chain)
42
+ end
43
+
44
+ def prerouting
45
+ table("", 'PREROUTING')
46
+ end
47
+
48
+ def postrouting
49
+ table("", 'POSTROUTING')
50
+ end
51
+
52
+ def forward
53
+ table("", 'FORWARD')
54
+ end
55
+
56
+ def output
57
+ table("", 'OUTPUT')
58
+ end
59
+
60
+ def input
61
+ table("", 'INPUT')
62
+ end
63
+
64
+ def commit
65
+ #puts @rows.inspect
66
+ tables = @rows.inject({}) do |r, row|
67
+ r[row.get_table] ||= {}
68
+ r[row.get_table][row.get_chain] ||= []
69
+ r[row.get_table][row.get_chain] << row
70
+ r
71
+ end
72
+
73
+ return "" if tables.empty?
74
+ ret = ["*#{@section.name}"]
75
+ ret += tables.keys.sort.map do |k|
76
+ v = tables[k]
77
+ if k.empty?
78
+ v.keys.map{|o| ":#{o} ACCEPT [0:0]" }
79
+ else
80
+ ":#{k} - [0:0]"
81
+ end
82
+ end
83
+
84
+ tables.keys.sort.each do |k,v|
85
+ v = tables[k]
86
+ v.keys.sort.each do |chain|
87
+ rows = v[chain]
88
+ table = !k.empty? ? "-A #{k}" : "-A #{chain}"
89
+ rows.each do |row|
90
+ ret << "#{table} #{row.get_row}"
91
+ end
92
+ end
93
+ end
94
+
95
+ ret << "COMMIT"
96
+ ret << ""
97
+ ret.join("\n")
98
+ end
99
+ end
100
+
101
+ def initialize(name)
102
+ @name = name
103
+ @ipv4 = Block.new(self)
104
+ @ipv6 = Block.new(self)
105
+ end
106
+
107
+ def name
108
+ @name
109
+ end
110
+
111
+ def ipv4
112
+ @ipv4
113
+ end
114
+
115
+ def ipv6
116
+ @ipv6
117
+ end
118
+
119
+ def commitv6
120
+ @ipv6.commit
121
+ end
122
+
123
+ def commitv4
124
+ @ipv4.commit
125
+ end
126
+ end
127
+
128
+ def mangle
129
+ @mangle
130
+ end
131
+
132
+ def raw
133
+ @raw
134
+ end
135
+
136
+ def nat
137
+ @nat
138
+ end
139
+
140
+ def filter
141
+ @filter
142
+ end
143
+
144
+ def commitv4
145
+ mangle.commitv4+raw.commitv4+nat.commitv4+filter.commitv4
146
+ end
147
+
148
+ def commitv6
149
+ mangle.commitv6+raw.commitv6+nat.commitv6+filter.commitv6
150
+ end
151
+ end
152
+
153
+ class EtcNetworkInterfaces
154
+ def initialize(result)
155
+ @result = result
156
+ @entries = {}
157
+ end
158
+
159
+ class Entry
160
+ class Header
161
+ MODE_MANUAL = :manual
162
+ MODE_DHCP = :dhcp
163
+ MODE_LOOPBACK = :loopback
164
+ PROTO_INET6 = :inet6
165
+ PROTO_INET4 = :inet
166
+ AUTO = :auto
167
+ def mode(mode)
168
+ @mode = mode
169
+ self
170
+ end
171
+
172
+ def protocol(protocol)
173
+ @protocol = protocol
174
+ self
175
+ end
176
+
177
+ def noauto
178
+ @auto = false
179
+ self
180
+ end
181
+
182
+ def initialize(entry)
183
+ @entry = entry
184
+ @auto = true
185
+ @mode = MODE_MANUAL
186
+ @protocol = PROTO_INET4
187
+ @interface_name = nil
188
+ end
189
+
190
+ def interface_name(name)
191
+ @interface_name = name
192
+ end
193
+
194
+ def get_interface_name
195
+ @interface_name || @entry.iface.name
196
+ end
197
+
198
+ def commit
199
+ return "" if @entry.skip_interfaces?
200
+ out = <<OUT
201
+ # #{@entry.iface.clazz}
202
+ #{@auto ? "auto #{get_interface_name}" : ""}
203
+ iface #{get_interface_name} #{@protocol.to_s} #{@mode.to_s}
204
+ up /bin/bash /etc/network/#{get_interface_name}-up.iface
205
+ down /bin/bash /etc/network/#{get_interface_name}-down.iface
206
+ OUT
207
+ end
208
+ end
209
+
210
+ class Lines
211
+ def initialize(entry)
212
+ @entry = entry
213
+ @lines = []
214
+ @ups = []
215
+ @downs = []
216
+ end
217
+
218
+ def up(block)
219
+ @ups += block.each_line.map{|i| i.strip }.select{|i| !i.empty? }
220
+ end
221
+
222
+ def down(block)
223
+ @downs += block.each_line.map{|i| i.strip }.select{|i| !i.empty? }
224
+ end
225
+
226
+ def add(block)
227
+ @lines += block.each_line.map{|i| i.strip }.select{|i| !i.empty? }
228
+ end
229
+
230
+ def write_s(direction, blocks)
231
+ @entry.result.add(self.class, <<BLOCK, Construqt::Resources::Rights::ROOT_0755, "etc", "network", "#{@entry.header.get_interface_name}-#{direction}.iface")
232
+ #!/bin/bash
233
+ exec > >(logger -t "#{@entry.header.get_interface_name}-#{direction}") 2>&1
234
+ #{blocks.join("\n")}
235
+ iptables-restore < /etc/network/iptables.cfg
236
+ ip6tables-restore < /etc/network/ip6tables.cfg
237
+ BLOCK
238
+ end
239
+
240
+ def commit
241
+ write_s("up", @ups)
242
+ write_s("down", @downs)
243
+ sections = @lines.inject({}) {|r, line| key = line.split(/\s+/).first; r[key] ||= []; r[key] << line; r }
244
+ sections.keys.sort.map do |key|
245
+ if sections[key]
246
+ sections[key].map{|j| " #{j}" }
247
+ else
248
+ nil
249
+ end
250
+ end.compact.flatten.join("\n")+"\n\n"
251
+ end
252
+ end
253
+
254
+ def iface
255
+ @iface
256
+ end
257
+
258
+ def initialize(result, iface)
259
+ @result = result
260
+ @iface = iface
261
+ @header = Header.new(self)
262
+ @lines = Lines.new(self)
263
+ @skip_interfaces = false
264
+ end
265
+
266
+ def result
267
+ @result
268
+ end
269
+
270
+ def name
271
+ @iface.name
272
+ end
273
+
274
+ def header
275
+ @header
276
+ end
277
+
278
+ def lines
279
+ @lines
280
+ end
281
+
282
+ def skip_interfaces?
283
+ @skip_interfaces
284
+ end
285
+
286
+ def skip_interfaces
287
+ @skip_interfaces = true
288
+ self
289
+ end
290
+
291
+ def commit
292
+ @header.commit + @lines.commit
293
+ end
294
+ end
295
+
296
+ def get(iface)
297
+ throw "clazz needed #{iface.name}" unless iface.clazz
298
+ @entries[iface.name] ||= Entry.new(@result, iface)
299
+ end
300
+
301
+ def commit
302
+ # binding.pry
303
+ out = [@entries['lo']]
304
+ clazzes = {}
305
+ @entries.values.each do |entry|
306
+ name = entry.iface.clazz#.name[entry.iface.clazz.name.rindex(':')+1..-1]
307
+ #puts "NAME=>#{name}:#{entry.iface.clazz.name.rindex(':')+1}:#{entry.iface.clazz.name}:#{entry.name}"
308
+ clazzes[name] ||= []
309
+ clazzes[name] << entry
310
+ end
311
+
312
+ ['device', 'bond', 'vlan', 'bridge', 'gre'].each do |type|
313
+ out += (clazzes[type]||[]).select{|i| !out.first || i.name != out.first.name }.sort{|a,b| a.name<=>b.name }
314
+ end
315
+
316
+ out.flatten.compact.inject("") { |r, entry| r += entry.commit; r }
317
+ end
318
+ end
319
+
320
+ class EtcNetworkVrrp
321
+ def initialize
322
+ @interfaces = {}
323
+ end
324
+
325
+ class Vrrp
326
+ def initialize
327
+ @masters = []
328
+ @backups = []
329
+ end
330
+
331
+ def add_master(master)
332
+ @masters << master
333
+ self
334
+ end
335
+
336
+ def add_backup(backup)
337
+ @backups << backup
338
+ self
339
+ end
340
+
341
+ def render(lines, direction)
342
+ lines.map do |line|
343
+ [
344
+ " logger '#{direction}#{line}'",
345
+ " #{line}"
346
+ ]
347
+ end.join("\n")
348
+ end
349
+
350
+ def render_masters
351
+ render(@masters, 'STARTING:')
352
+ end
353
+
354
+ def render_backups
355
+ render(@backups, 'STOPPING:')
356
+ end
357
+ end
358
+
359
+ def get(ifname)
360
+ @interfaces[ifname] ||= Vrrp.new
361
+ end
362
+
363
+ def commit(result)
364
+ @interfaces.keys.sort.each do |ifname|
365
+ vrrp = @interfaces[ifname]
366
+ result.add(self, <<VRRP, Construqt::Resources::Rights::ROOT_0755, "etc", "network", "vrrp.#{ifname}.sh")
367
+ #!/bin/bash
368
+
369
+ TYPE=$1
370
+ NAME=$2
371
+ STATE=$3
372
+
373
+ case $STATE in
374
+ "MASTER")
375
+ #{vrrp.render_masters}
376
+ exit 0
377
+ ;;
378
+ "BACKUP")
379
+ #{vrrp.render_backups}
380
+ exit 0
381
+ ;;
382
+ *) echo "unknown state"
383
+ exit 1
384
+ ;;
385
+ esac
386
+ VRRP
387
+ end
388
+ end
389
+ end
390
+
391
+ class Result
392
+ def initialize(host)
393
+ @host = host
394
+ @etc_network_interfaces = EtcNetworkInterfaces.new(self)
395
+ @etc_network_iptables = EtcNetworkIptables.new
396
+ @etc_network_vrrp = EtcNetworkVrrp.new
397
+ @result = {}
398
+ end
399
+
400
+ def etc_network_interfaces
401
+ @etc_network_interfaces
402
+ end
403
+
404
+ def etc_network_iptables
405
+ @etc_network_iptables
406
+ end
407
+
408
+ def etc_network_vrrp(ifname)
409
+ @etc_network_vrrp.get(ifname)
410
+ end
411
+
412
+ def host
413
+ @host
414
+ end
415
+
416
+ def empty?(name)
417
+ not @result[name]
418
+ end
419
+
420
+ class ArrayWithRight < Array
421
+ attr_accessor :right
422
+ def initialize(right)
423
+ self.right = right
424
+ end
425
+ end
426
+
427
+ def add(clazz, block, right, *path)
428
+ path = File.join(*path)
429
+ throw "not a right #{path}" unless right.respond_to?('right') && right.respond_to?('owner')
430
+ unless @result[path]
431
+ @result[path] = ArrayWithRight.new(right)
432
+ #binding.pry
433
+ #@result[path] << [clazz.xprefix(@host)].compact
434
+ end
435
+
436
+ @result[path] << block+"\n"
437
+ end
438
+
439
+ def replace(clazz, block, right, *path)
440
+ path = File.join(*path)
441
+ replaced = !!@result[path]
442
+ @result.delete(path) if @result[path]
443
+ add(clazz, block, right, *path)
444
+ replaced
445
+ end
446
+
447
+ def directory_mode(mode)
448
+ mode = mode.to_i(8)
449
+ 0!=(mode & 06) && (mode = (mode | 01))
450
+ 0!=(mode & 060) && (mode = (mode | 010))
451
+ 0!=(mode & 0600) && (mode = (mode | 0100))
452
+ "0#{mode.to_s(8)}"
453
+ end
454
+
455
+ def import_fname(fname)
456
+ '/'+File.dirname(fname)+"/.#{File.basename(fname)}.import"
457
+ end
458
+
459
+ def commit
460
+ add(EtcNetworkIptables, etc_network_iptables.commitv4, Construqt::Resources::Rights::ROOT_0644, "etc", "network", "iptables.cfg")
461
+ add(EtcNetworkIptables, etc_network_iptables.commitv6, Construqt::Resources::Rights::ROOT_0644, "etc", "network", "ip6tables.cfg")
462
+ add(EtcNetworkInterfaces, etc_network_interfaces.commit, Construqt::Resources::Rights::ROOT_0644, "etc", "network", "interfaces")
463
+ @etc_network_vrrp.commit(self)
464
+ out = [<<BASH]
465
+ #!/bin/bash
466
+ hostname=`hostname`
467
+ if [ $hostname != "" ]
468
+ then
469
+ hostname=`grep '^\s*[^#]' /etc/hostname`
470
+ fi
471
+ if [ $hostname != #{@host.name} ]
472
+ then
473
+ echo 'You try to run a deploy script on a host which has not the right name $hostname != #{@host.name}'
474
+ else
475
+ echo Configure Host #{@host.name}
476
+ fi
477
+ updates=''
478
+ for i in language-pack-en language-pack-de git aptitude traceroute vlan bridge-utils tcpdump mtr-tiny \\
479
+ bird keepalived strace iptables conntrack openssl racoon ulogd2 ifenslave
480
+ do
481
+ dpkg -l $i > /dev/null 2> /dev/null
482
+ if [ $? != 0 ]
483
+ then
484
+ updates="$updates $i"
485
+ fi
486
+ done
487
+ apt-get -qq -y install $updates
488
+ if [ ! -d /root/construqt.git ]
489
+ then
490
+ echo generate history in /root/construqt.git
491
+ git init --bare /root/construqt.git
492
+ fi
493
+ BASH
494
+ out += @result.map do |fname, block|
495
+ text = block.flatten.select{|i| !(i.nil? || i.strip.empty?) }.join("\n")
496
+ next if text.strip.empty?
497
+ Util.write_str(text, @host.name, fname)
498
+ # binding.pry
499
+ #
500
+ [
501
+ File.dirname("/#{fname}").split('/')[1..-1].inject(['']) do |res, part|
502
+ res << File.join(res.last, part); res
503
+ end.select{|i| !i.empty? }.map do |i|
504
+ "[ ! -d #{i} ] && mkdir #{i} && chown #{block.right.owner} #{i} && chmod #{directory_mode(block.right.right)} #{i}"
505
+ end,
506
+ "openssl enc -base64 -d > #{import_fname(fname)} <<BASE64", Base64.encode64(text), "BASE64",
507
+ <<BASH]
508
+ chown #{block.right.owner} #{import_fname(fname)}
509
+ chmod #{block.right.right} #{import_fname(fname)}
510
+ if [ ! -f /#{fname} ]
511
+ then
512
+ mv #{import_fname(fname)} /#{fname}
513
+ echo created /#{fname} to #{block.right.owner}:#{block.right.right}
514
+ else
515
+ diff -rq #{import_fname(fname)} /#{fname}
516
+ if [ $? != 0 ]
517
+ then
518
+ mv #{import_fname(fname)} /#{fname}
519
+ echo updated /#{fname} to #{block.right.owner}:#{block.right.right}
520
+ else
521
+ rm #{import_fname(fname)}
522
+ fi
523
+ git --git-dir /root/construqt.git --work-tree=/ add /#{fname}
524
+ fi
525
+ BASH
526
+ end.flatten
527
+ out += [<<BASH]
528
+ git --git-dir /root/construqt.git config user.name #{ENV['USER']}
529
+ git --git-dir /root/construqt.git config user.email #{ENV['USER']}@construqt.net
530
+ git --git-dir /root/construqt.git --work-tree=/ commit -q -m '#{ENV['USER']} #{`hostname`.strip} "#{`git log --pretty=format:"%h - %an, %ar : %s" -1`.strip.inspect}"' > /dev/null && echo COMMITED
531
+ BASH
532
+ Util.write_str(out.join("\n"), @host.name, "deployer.sh")
533
+ end
534
+ end
535
+ end
536
+ end
537
+ end
@@ -0,0 +1,115 @@
1
+
2
+ module Construqt
3
+ module Flavour
4
+ module Ubuntu
5
+ module Services
6
+ class DhcpV4Relay
7
+ def initialize(service)
8
+ @service = service
9
+ end
10
+
11
+ def up(ifname)
12
+ "/usr/sbin/dhcrelay -pf /run/dhcrelay-v4.#{ifname}.pid -d -q -4 -i #{ifname} #{@service.servers.map{|i| i.to_s}.join(' ')}"
13
+ end
14
+
15
+ def down(ifname)
16
+ "kill `/run/dhcrelay-v4.#{ifname}.pid`"
17
+ end
18
+
19
+ def vrrp(host, ifname, iface)
20
+ host.result.etc_network_vrrp(iface.name).add_master(up(ifname)).add_backup(down(ifname))
21
+ end
22
+
23
+ def interfaces(host, ifname, iface, writer)
24
+ #binding.pry
25
+ return unless iface.address && iface.address.first_ipv4
26
+ return if @service.servers.empty?
27
+ writer.lines.up(up(ifname))
28
+ writer.lines.down(down(ifname))
29
+ end
30
+ end
31
+
32
+ class DhcpV6Relay
33
+ def initialize(service)
34
+ @service = service
35
+ end
36
+
37
+ def up(ifname)
38
+ "/usr/sbin/dhcrelay -pf /run/dhcrelay-v6.#{ifname}.pid -d -q -6 -i #{ifname} #{@service.servers.map{|i| i.to_s}.join(' ')}"
39
+ end
40
+
41
+ def down(ifname)
42
+ "kill `/run/dhcrelay-v6.#{ifname}.pid`"
43
+ end
44
+
45
+ def vrrp(host, ifname, iface)
46
+ host.result.etc_network_vrrp(iface.name).add_master(up(ifname)).add_backup(down(ifname))
47
+ end
48
+
49
+ def interfaces(host, ifname, iface, writer)
50
+ return unless iface.address && iface.address.first_ipv6
51
+ return if @service.servers.empty?
52
+ writer.lines.up(up(ifname))
53
+ writer.lines.down(down(ifname))
54
+ end
55
+ end
56
+
57
+ class Radvd
58
+ def initialize(service)
59
+ @service = service
60
+ end
61
+
62
+ def up(ifname)
63
+ "/usr/sbin/radvd -C /etc/network/radvd.#{ifname}.conf -p /run/radvd.#{ifname}.pid"
64
+ end
65
+
66
+ def down(ifname)
67
+ "kill `cat /run/radvd.#{ifname}.pid`"
68
+ end
69
+
70
+ def vrrp(host, ifname, iface)
71
+ #binding.pry
72
+ host.result.etc_network_vrrp(iface.name).add_master(up(ifname)).add_backup(down(ifname))
73
+ end
74
+
75
+ def interfaces(host, ifname, iface, writer)
76
+ # binding.pry
77
+ return unless iface.address && iface.address.first_ipv6
78
+ writer.lines.up(up(ifname))
79
+ writer.lines.down(down(ifname))
80
+ host.result.add(self, <<RADV, Construqt::Resources::Rights::ROOT_0644, "etc", "network", "radvd.#{ifname}.conf")
81
+ interface #{ifname}
82
+ {
83
+ AdvManagedFlag on;
84
+ AdvSendAdvert on;
85
+ AdvOtherConfigFlag on;
86
+ #AdvAutonomous on;
87
+ #AdvLinkMTU 1480;
88
+ #MinRtrAdvInterval 3;
89
+ #MaxRtrAdvInterval 60;
90
+ prefix #{iface.address.first_ipv6.network.to_string}
91
+ {
92
+ AdvOnLink on;
93
+ AdvAutonomous off;
94
+ AdvRouterAddr on;
95
+ };
96
+
97
+ };
98
+ RADV
99
+ end
100
+ end
101
+
102
+ def self.get_renderer(service)
103
+ factory = {
104
+ Construqt::Services::DhcpV4Relay => DhcpV4Relay,
105
+ Construqt::Services::DhcpV6Relay => DhcpV6Relay,
106
+ Construqt::Services::Radvd => Radvd
107
+ }
108
+ found = factory.keys.find{ |i| service.kind_of?(i) }
109
+ throw "service type unknown #{service.name} #{service.class.name}" unless found
110
+ factory[found].new(service)
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,52 @@
1
+ module Construqt
2
+ module Flavour
3
+ module Ubuntu
4
+
5
+ class Vrrp < OpenStruct
6
+ def initialize(cfg)
7
+ super(cfg)
8
+ end
9
+
10
+ def self.header(host)
11
+ host.result.add(self, <<GLOBAL, Construqt::Resources::Rights::ROOT_0644, "etc", "keepalived", "keepalived.conf")
12
+ global_defs {
13
+ lvs_id #{host.name}
14
+ }
15
+ GLOBAL
16
+ end
17
+
18
+ def build_config(host, iface)
19
+ iface = iface.delegate
20
+ my_iface = iface.interfaces.find{|iface| iface.host == host }
21
+ ret = []
22
+ ret << "vrrp_instance #{iface.name} {"
23
+ ret << " state MASTER"
24
+ ret << " interface #{my_iface.name}"
25
+ ret << " virtual_router_id #{iface.vrid||iface.interfaces.map{|a,b| a.priority<=>b.priority}.first}"
26
+ ret << " priority #{my_iface.priority}"
27
+ ret << " authentication {"
28
+ ret << " auth_type PASS"
29
+ ret << " auth_pass fw"
30
+ ret << " }"
31
+ ret << " virtual_ipaddress {"
32
+ iface.address.ips.each do |ip|
33
+ ret << " #{ip.to_string} dev #{my_iface.name}"
34
+ end
35
+
36
+ ret << " }"
37
+ if iface.services && !iface.services.empty?
38
+ ret << " notify /etc/network/vrrp.#{iface.name}.sh"
39
+ writer = host.result.etc_network_interfaces.get(iface)
40
+ iface.services.each do |service|
41
+ Services.get_renderer(service).interfaces(host, my_iface.name, my_iface, writer)
42
+ Services.get_renderer(service).vrrp(host, my_iface.name, iface)
43
+ end
44
+ end
45
+
46
+ ret << "}"
47
+ host.result.add(self, ret.join("\n"), Construqt::Resources::Rights::ROOT_0644, "etc", "keepalived", "keepalived.conf")
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end