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,53 @@
1
+ module Construqt
2
+ class Services
3
+
4
+ class DhcpV4Relay
5
+ attr_accessor :servers, :name
6
+ def initialize(name)
7
+ self.name = name
8
+ self.servers = []
9
+ end
10
+ def add_server(ip)
11
+ ip = IPAddress.parse(ip)
12
+ throw "ip must be a v4 address" unless ip.ipv4?
13
+ self.servers << ip
14
+ self
15
+ end
16
+ end
17
+ class DhcpV6Relay
18
+ attr_accessor :servers, :name
19
+ def initialize(name)
20
+ self.name = name
21
+ self.servers = []
22
+ end
23
+ def add_server(ip)
24
+ ip = IPAddress.parse(ip)
25
+ throw "ip must be a v6 address" unless ip.ipv6?
26
+ self.servers << ip
27
+ self
28
+ end
29
+ end
30
+ class Radvd
31
+ attr_accessor :servers, :name
32
+ def initialize(name)
33
+ self.name = name
34
+ end
35
+ end
36
+
37
+ def initialize
38
+ @services = {}
39
+ end
40
+
41
+ def find(name)
42
+ found = @services[name]
43
+ throw "service with name #{name} not found" unless found
44
+ found
45
+ end
46
+
47
+ def add(service)
48
+ @services[service.name] = service
49
+ self
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,61 @@
1
+
2
+ module Construqt
3
+ module Tags
4
+ @tags = {}
5
+ @object_id_tags = {}
6
+ def self.add(tag_str, &block)
7
+ (name, *tags) = tag_str.split(/\s*#\s*/)
8
+ obj = block.call(name, tags)
9
+ #binding.pry
10
+ tags && tags.uniq.each do |tag|
11
+ @tags[tag] ||= []
12
+ @tags[tag] << obj unless @tags[tag].include?(obj)
13
+ end
14
+ if obj.respond_to? :tags
15
+ obj.tags = tags
16
+ end
17
+ @object_id_tags[obj.object_id] ||= []
18
+ @object_id_tags[obj.object_id] = (@object_id_tags[obj.object_id] + tags).uniq
19
+ [name, obj]
20
+ end
21
+
22
+ def self.from(obj)
23
+ @object_id_tags[obj.object_id]
24
+ end
25
+
26
+ def self.find(tag, clazz = nil)
27
+ #binding.pry
28
+ ret = (@tags[tag] || []).select{|o| clazz.nil? || o.kind_of?(clazz) }
29
+ Construqt.logger.warn("tag #{tag} #{clazz.inspect} empty result") if ret.empty?
30
+ ret
31
+ end
32
+
33
+ def self.ips_net(tag, family)
34
+ ip_module = family==Construqt::Addresses::IPV4 ? IPAddress::IPv4: IPAddress::IPv6
35
+ IPAddress::IPv4::summarize(*(@tags[tag]||[]).map do |obj|
36
+ if obj.kind_of?(IPAddress)
37
+ obj
38
+ elsif obj.respond_to? :ips
39
+ obj.ips
40
+ elsif obj.kind_of?(Construqt::Flavour::HostDelegate)
41
+ #binding.pry
42
+ res = obj.interfaces.values.map do |i|
43
+ i.delegate.address.ips.map do |a|
44
+ prefix = a.ipv4? ? 32 : 128
45
+ ret = IPAddress.parse("#{a.to_s}/#{prefix}")
46
+ puts "ADR=#{tag} #{ret.to_string} #{a.to_s}"
47
+ ret
48
+ end
49
+ end.flatten
50
+ puts "HOST=>#{tag} #{res.map{|i| i.to_string }}"
51
+ res
52
+ else
53
+ nil
54
+ end
55
+ end.flatten.compact.select do |i|
56
+ (family==Construqt::Addresses::IPV4 && i.ipv4?) ||
57
+ (family==Construqt::Addresses::IPV6 && i.ipv6?)
58
+ end)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,37 @@
1
+
2
+ module Construqt
3
+ class Templates
4
+ def initialize(region)
5
+ @region = region
6
+ @templates = {}
7
+ end
8
+
9
+ class Template < OpenStruct
10
+ def initialize(cfg)
11
+ super(cfg)
12
+ end
13
+
14
+ def is_tagged?(vlan_id)
15
+ self.vlans.each do |vlan|
16
+ return vlan.tagged? if vlan.vlan_id == vlan_id
17
+ end
18
+
19
+ throw "vlan with id #{vlan_id} not found in template #{self}"
20
+ end
21
+ end
22
+
23
+ def find(name)
24
+ ret = @templates[name]
25
+ throw "template with name #{name} not found" unless @templates[name]
26
+ ret
27
+ end
28
+
29
+ def add(name, cfg)
30
+ throw "template with name #{name} exists" if @templates[name]
31
+ cfg['name'] = name
32
+ ret = Template.new(cfg)
33
+ @templates[name] = ret
34
+ ret
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,50 @@
1
+
2
+ addresses = Construqt::Addresses.new(7)
3
+
4
+ assert_eq(addresses.network, 7)
5
+
6
+ adr = addresses.create
7
+
8
+ assert_eq(addresses.all.length, 0)
9
+
10
+ adr.set_name("jojo")
11
+ assert_eq(adr.name, "jojo")
12
+
13
+ adr.name = "jojojo"
14
+ assert_eq(adr.name, "jojojo")
15
+
16
+ adr.add_ip("192.168.0.1")
17
+ assert_eq(adr.all.length, 1)
18
+ assert_eq(adr.v4s.length, 1)
19
+ assert_eq(adr.v6s.length, 0)
20
+
21
+ adr.add_ip("192.168.0.2")
22
+ assert_eq(adr.all.length, 2)
23
+ assert_eq(adr.v4s.length, 2)
24
+ assert_eq(adr.v6s.length, 0)
25
+
26
+ adr.add_ip("2000::/27")
27
+ assert_eq(adr.all.length, 3)
28
+ assert_eq(adr.v4s.length, 2)
29
+ assert_eq(adr.v6s.length, 1)
30
+
31
+ adr.add_ip("2001::/27")
32
+ assert_eq(adr.all.length, 4)
33
+ assert_eq(adr.v4s.length, 2)
34
+ assert_eq(adr.v6s.length, 2)
35
+
36
+ assert_eq(adr.first_ipv4, "192.168.0.1")
37
+ assert_eq(adr.first_ipv6, "2001::/27")
38
+
39
+ assert_eq(adr.dhcpv4?, false)
40
+ adr.add_ip(DHCPV4)
41
+ assert_eq(adr.dhcpv4?, true)
42
+
43
+ assert_eq(adr.dhcpv6?, false)
44
+ adr.add_ip(DHCPV6)
45
+ assert_eq(adr.dhcpv6?, true)
46
+
47
+ assert_eq(adr.loopback?, false)
48
+ adr.add_ip(LOOPBACK)
49
+ assert_eq(adr.loopback?, true)
50
+
@@ -0,0 +1,24 @@
1
+
2
+ Construqt::Bgps.add_as(93925993, "redistribute-connected" => true,
3
+ "redistribute-static" => true,
4
+ "redistribute-other-bgp" => true,
5
+ "description" => "test-93925993")
6
+
7
+ Construqt::Bgps.add_as(73925993, "redistribute-connected" => true,
8
+ "redistribute-static" => true,
9
+ "redistribute-other-bgp" => true,
10
+ "description" => "test-73925993")
11
+
12
+ Construqt::Bgps.connection("name_it",
13
+ "password" => "geheim",
14
+ "left" => {
15
+ "as" => Construqt::Bgps::find_as(93925993),
16
+ "my" => ipsec.left.interface,
17
+ "filter" => { "in" => Construqt::Bgps.find_filter('mgmt_net_in'), "out" => Construqt::Bgps.find_filter('mgmt_net_out') },
18
+ },
19
+ "right" => {
20
+ "as" => Construqt::Bgps::find_as(73925993),
21
+ "my" => ipsec.right.interface,
22
+ "filter" => { "in" => Construqt::Bgps.find_filter('mgmt_net_in'), "out" => Construqt::Bgps.find_filter('mgmt_net_out') },
23
+ }
24
+ )
@@ -0,0 +1,32 @@
1
+
2
+
3
+ id = Construqt::HostId.create do |block|
4
+ assert_eq(block.interfaces.length, 0)
5
+ end
6
+
7
+ assert_eq(id.first_ipv6!, nil)
8
+ assert_eq(id.first_ipv4!, nil)
9
+
10
+ begin
11
+ id.first_ipv4
12
+ assert("should not happend")
13
+ raise
14
+ end
15
+
16
+ begin
17
+ id.first_ipv6
18
+ assert("should not happend")
19
+ raise
20
+ end
21
+
22
+ iface = XXXXX
23
+ id = Construqt::HostId.create do |block|
24
+ assert_eq(block.interfaces.length, 0)
25
+ block.interfaces << iface
26
+ end
27
+
28
+ assert_eq(id.first_ipv6!, iface.first_ipv6)
29
+ assert_eq(id.first_ipv4!, iface.first_ipv4)
30
+
31
+ assert_eq(id.first_ipv6, iface.first_ipv6)
32
+ assert_eq(id.first_ipv4, iface.first_ipv4)
@@ -0,0 +1,23 @@
1
+
2
+ hosts = Hosts.new(19)
3
+
4
+ assert_eq(hosts.region, 19)
5
+
6
+ hosts.set_default_password("9339")
7
+ assert_eq(hosts.default_password, "9339")
8
+
9
+ assert_eq(hosts.get_hosts.length, 0)
10
+
11
+ begin
12
+ hosts.add("test", "lutz" => "fuchs") do |host|
13
+ end
14
+ end
15
+
16
+ begin
17
+ hosts.add("test", "lutz" => "fuchs") do |host|
18
+ end
19
+ assert("Should not happend")
20
+ raise
21
+ end
22
+
23
+
@@ -0,0 +1,76 @@
1
+
2
+ class Test
3
+ include Chainable
4
+ #def initialize
5
+ # puts ">>>test instance=#{"%x"%self.object_id} class=#{"%x"%self.class.object_id}"
6
+ #end
7
+ attr_reader :sideeffect
8
+ chainable_attr :bloed0
9
+ chainable_attr :bloed1
10
+ chainable_attr :test, 1, 2
11
+ chainable_attr :testbool, false, true
12
+ chainable_attr :testbool2, true, true
13
+ chainable_attr :testside, 1, 2, lambda {|i| @sideeffect ||= 9; @sideeffect += 1 }
14
+ end
15
+ class Test2
16
+ include Chainable
17
+ #def initialize
18
+ # puts ">>>test instance=#{"%x"%self.object_id} class=#{"%x"%self.class.object_id}"
19
+ #end
20
+ attr_reader :sideeffect
21
+ chainable_attr :bloed0
22
+ chainable_attr :bloed1
23
+ chainable_attr :test, 3, 4
24
+ chainable_attr :testbool, true, false
25
+ chainable_attr :testside, 3, 4, lambda {|i| @sideeffect ||= 5; @sideeffect += 1 }
26
+ end
27
+ def self.test
28
+ 3.times do |i|
29
+ t = Test.new
30
+ #throw "chainable failed input_only" unless t.input_only? == true
31
+ #throw "chainable failed output_only" unless t.output_only? == true
32
+
33
+ #puts "#{i}=>#{t.testbool?} #{t.testbool2?}"
34
+ throw "chainable failed test should 2 #{t.get_test.inspect}" if t.get_test != 2
35
+ t.test
36
+ throw "chainable failed this should be 1 " if t.get_test != 1
37
+ t.test(3)
38
+ throw "chainable failed" if t.get_test != 3
39
+
40
+ throw "chainable failed test should 2 #{t.get_testside.inspect}" if t.get_testside != 2
41
+ throw "chainable failed sideeffect should 1 nil #{t.sideeffect.inspect}" if !t.sideeffect.nil?
42
+ t.testside
43
+ throw "chainable failed this should be 1 " if t.get_testside != 1
44
+ throw "chainable failed sideeffect should 2 nil #{t.sideeffect.inspect}" if t.sideeffect != 10
45
+ t.testside(3)
46
+ throw "chainable failed" if t.get_testside != 3
47
+ throw "chainable failed sideeffect should 2 nil #{t.sideeffect.inspect}" if t.sideeffect != 11
48
+
49
+ throw "chainable failed true" unless t.testbool? == true
50
+ t.testbool
51
+ throw "chainable failed false" unless t.testbool? == false
52
+ t.testbool(4)
53
+ throw "chainable failed 4" unless t.testbool? == 4
54
+ t.testbool
55
+ throw "chainable failed false" unless t.testbool? == false
56
+
57
+ throw "chainable failed 2 true" unless t.testbool2? == true
58
+ t.testbool2
59
+ throw "chainable failed 2 false" unless t.testbool2? == true
60
+ t.testbool2(4)
61
+ throw "chainable failed 2 4" unless t.testbool2? == 4
62
+ t.testbool2
63
+ throw "chainable failed 2 false" unless t.testbool2? == true
64
+ end
65
+ a=[Test.new,Test.new,Test.new]
66
+ a[0].testbool(0)
67
+ throw "chainable failed 0" unless a[0].testbool? == 0
68
+ throw "chainable failed 1" unless a[1].testbool? == true
69
+ a[2].testbool
70
+ throw "chainable failed 2" unless a[2].testbool? == false
71
+
72
+ throw "chainable failed 0" unless a[0].testbool? == 0
73
+ throw "chainable failed 1" unless a[1].testbool? == true
74
+ throw "chainable failed 2" unless a[2].testbool? == false
75
+ end
76
+ @test = self.test
@@ -0,0 +1,19 @@
1
+ module Construqt
2
+ class Users
3
+ def initialize(region)
4
+ @region = region
5
+ @users = {}
6
+ end
7
+
8
+ def add(name, cfg)
9
+ throw "user exists #{name}" if @users[name]
10
+ cfg['name'] = name
11
+ cfg['yubikey'] ||= nil
12
+ @users[name] = OpenStruct.new(cfg)
13
+ end
14
+
15
+ def all
16
+ @users.values
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,163 @@
1
+ module Construqt
2
+ module Util
3
+ module Chainable
4
+
5
+ def self.included(other)
6
+ #puts "Chainable #{other.name}"
7
+ other.class.send("define_method", "chainable_attr") do |*args|
8
+ #puts "chainable_attr:#{self.name} #{args.inspect}"
9
+ Chainable.chainable_attr(self, *args)
10
+ end
11
+
12
+ other.class.send("define_method", "chainable_attr_value") do |*args|
13
+ #puts "chainable_attr_value:#{self.name} #{args.inspect}"
14
+ Chainable.chainable_attr_value(self, *args)
15
+ end
16
+ end
17
+
18
+ def self.chainable_attr_value(clazz, arg, init = nil)
19
+ instance_variable_name = "@#{arg}".to_sym
20
+ self.instance_variable_set(instance_variable_name, init)
21
+ define_method(arg.to_s) do |val|
22
+ self.instance_variable_set(instance_variable_name, val)
23
+ self
24
+ end
25
+
26
+ define_method("get_#{arg}") do
27
+ self.instance_variable_get(instance_variable_name.to_sym)
28
+ end
29
+ end
30
+
31
+ def self.chainable_attr(clazz, arg, set_value = true, init = false, aspect = lambda{|i|})
32
+ instance_variable_name = "@#{arg}".to_sym
33
+ # puts ">>>chainable_attr #{"%x"%self.object_id} init=#{init}"
34
+ # self.instance_variable_set(instance_variable_name, init)
35
+ #puts "self.chainable_attr #{clazz.name} #{arg.to_sym} #{set_value} #{init}"
36
+ clazz.send("define_method", arg.to_sym) do |*args|
37
+ instance_eval(&aspect)
38
+ self.instance_variable_set(instance_variable_name, args.length>0 ? args[0] : set_value)
39
+ self
40
+ end
41
+
42
+ if ((set_value.kind_of?(true.class) || set_value.kind_of?(false.class)) &&
43
+ (init.kind_of?(true.class) || init.kind_of?(false.class)))
44
+ get_name = "#{arg}?"
45
+ else
46
+ get_name = "get_#{arg}"
47
+ end
48
+
49
+ get_name_proc = Proc.new do
50
+ unless self.instance_variables.include?(instance_variable_name)
51
+ #puts "init #{get_name} #{instance_variable_name} #{defined?(instance_variable_name)} #{set_value} #{init}"
52
+ self.instance_variable_set(instance_variable_name, init)
53
+ end
54
+
55
+ ret = self.instance_variable_get(instance_variable_name)
56
+ #puts "#{self.class.name} #{get_name} #{set_value} #{init} => #{ret.inspect}"
57
+ ret
58
+ end
59
+
60
+ clazz.send("define_method", get_name, get_name_proc)
61
+ end
62
+ end
63
+
64
+ def self.write_str(str, *path)
65
+ path = File.join("cfgs", *path)
66
+ FileUtils.mkdir_p(File.dirname(path))
67
+ File.open(path, 'w') {|f| f.write(str) }
68
+ Construqt.logger.info "Write:#{path}"
69
+ return str
70
+ end
71
+
72
+ def self.password(a)
73
+ a
74
+ end
75
+
76
+ def self.add_gre_prefix(name)
77
+ unless name.start_with?("gt")
78
+ return "gt"+name
79
+ end
80
+
81
+ name
82
+ end
83
+
84
+ @clean_if = []
85
+ def self.add_clean_ip_pattern(pat)
86
+ @clean_if << pat
87
+ end
88
+
89
+ def self.clean_if(prefix, name)
90
+ unless name.start_with?(prefix)
91
+ name = prefix+name
92
+ end
93
+
94
+ name = name.gsub(/[^a-z0-9]/, '')
95
+ @clean_if.each { |pat| name.gsub!(pat, '') }
96
+ name
97
+ end
98
+
99
+ def self.clean_bgp(name)
100
+ name.gsub(/[^a-z0-9]/, '_')
101
+ end
102
+
103
+ def self.portNeighbors?(port1, port2)
104
+ port2.succ == port1 || port1.succ == port2
105
+ end
106
+
107
+ def self.createRangeDefinition(ports)
108
+ ranges=[]
109
+ lastPort=nil
110
+
111
+ #remove duplicates
112
+ ports.uniq.sort do |l,r|
113
+ fc = l.to_s.length <=> r.to_s.length
114
+ fc!=0 ? fc : l<=>r
115
+ end.each do |port|
116
+ port = port.to_s
117
+ if (ranges.length>0 && portNeighbors?(port, ranges[ranges.length-1]["to"]))
118
+ ranges[ranges.length-1]["to"] = port
119
+ else
120
+ ranges << {"from" => port, "to" => port}
121
+ end
122
+ end
123
+
124
+ ranges = ranges.map do |range|
125
+ range["from"] == range["to"] ? range["from"] : range["from"] +"-"+range["to"]
126
+ end
127
+ #puts "self.createRangeDefinition[#{ports}]=>#{ranges}"
128
+ ranges.join(",")
129
+ end
130
+
131
+ PORTS_DEF_REGEXP = "([^\\d\\s]*[\\d,-]+)+"
132
+ PORT_NAME_REGEXP="^(.*?)(\\d+)$"
133
+ def self.expandRangeDefinition(list_str)
134
+ ports = list_str.strip.split(",").map do |range_def|
135
+ range = range_def.split("-")
136
+ if (range.length==1)
137
+ range
138
+ elsif (range.length==2)
139
+ range[0]=~/#{PORT_NAME_REGEXP}/
140
+ prefix_from=$1
141
+ from = $2
142
+ range[1]=~/#{PORT_NAME_REGEXP}/
143
+ prefix_to=$1
144
+ to = $2
145
+ throw "port prefixes differ" unless prefix_from==prefix_to
146
+ (from.to_i .. to.to_i).map {|n| prefix_from + n.to_s }
147
+ else
148
+ throw "invalid range found #{range_def}"
149
+ end
150
+ end
151
+ ports.flatten
152
+ end
153
+
154
+ def self.generate_mac_address_from_name(name)
155
+ # http://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml
156
+ '8f:'+Digest::SHA256.hexdigest("#{name}").scan(/../)[0,5].join(':')
157
+ end
158
+
159
+ def self.indent(body, ident)
160
+ body.lines.map { |line| ident+line }.join("\n")
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,3 @@
1
+ module Construqt
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,51 @@
1
+
2
+ module Construqt
3
+ class Vlans
4
+ def initialize(region)
5
+ @region = region
6
+ @vlans_id = {}
7
+ @vlans_description = {}
8
+ end
9
+
10
+ class Vlan < OpenStruct
11
+ def initialize(cfg)
12
+ super(cfg)
13
+ end
14
+
15
+ def tagged?
16
+ @tagged
17
+ end
18
+
19
+ def tagged
20
+ @tagged=true
21
+ self
22
+ end
23
+
24
+ def untagged?
25
+ !@tagged
26
+ end
27
+
28
+ def untagged
29
+ @tagged = false
30
+ self
31
+ end
32
+ end
33
+
34
+ def add(vlan, cfg)
35
+ throw "vlan has to be a fixnum #{vlan}" unless vlan.kind_of?(Fixnum)
36
+ throw "vlan need #{vlan} description" unless cfg['description']
37
+ throw "vlan with id #{vlan} exists" if @vlans_id[vlan]
38
+ throw "vlan with description #{vlan} exists" if @vlans_description[cfg['description']]
39
+ cfg['vlan_id'] = vlan
40
+ ret = Vlan.new(cfg)
41
+ @vlans_id[vlan] = ret
42
+ @vlans_description[cfg['description']] = ret
43
+ ret
44
+ end
45
+
46
+ def clone(key)
47
+ throw "vlan clone key not found #{key}" unless @vlans_id[key] || @vlans_description[key]
48
+ (@vlans_id[key] || @vlans_description[key]).clone
49
+ end
50
+ end
51
+ end
data/lib/construqt.rb ADDED
@@ -0,0 +1,92 @@
1
+ require 'logger'
2
+
3
+ require 'fileutils'
4
+ require 'ostruct'
5
+
6
+ require 'ipaddress'
7
+ require 'digest/sha1'
8
+ require 'digest/md5'
9
+ require "base64"
10
+ require 'securerandom'
11
+
12
+
13
+ module Construqt
14
+
15
+ @logger = Logger.new(STDOUT)
16
+ @logger.level = Logger::DEBUG
17
+
18
+ def self.log_level(level)
19
+ @logger.level = level
20
+ end
21
+
22
+ if !IPAddress::IPv6.instance_methods.include?(:rev_domains)
23
+ @logger.fatal "you need the right ipaddress version from https://github.com/mabels/ipaddress"
24
+ end
25
+
26
+ if !OpenStruct.instance_methods.include?(:to_h)
27
+ OpenStruct.class_eval do
28
+ def to_h
29
+ @table.dup
30
+ end
31
+ end
32
+
33
+ @logger.warn "Your running a patched version of OpenStruct"
34
+ end
35
+
36
+ def self.logger
37
+ @logger
38
+ end
39
+
40
+ # ugly but i need the logger during initialization
41
+ require_relative 'construqt/util.rb'
42
+ require_relative 'construqt/services.rb'
43
+ require_relative 'construqt/networks.rb'
44
+ require_relative 'construqt/addresses.rb'
45
+ require_relative 'construqt/bgps.rb'
46
+ require_relative 'construqt/users.rb'
47
+ require_relative 'construqt/firewalls.rb'
48
+ require_relative 'construqt/flavour/delegates.rb'
49
+ require_relative 'construqt/resource.rb'
50
+ require_relative 'construqt/hostid.rb'
51
+ require_relative 'construqt/hosts.rb'
52
+ require_relative 'construqt/interfaces.rb'
53
+ require_relative 'construqt/cables.rb'
54
+ require_relative 'construqt/ipsecs.rb'
55
+ require_relative 'construqt/firewalls.rb'
56
+ require_relative 'construqt/templates.rb'
57
+ require_relative 'construqt/regions.rb'
58
+ require_relative 'construqt/vlans.rb'
59
+ require_relative 'construqt/tags.rb'
60
+ require_relative 'construqt/flavour/flavour.rb'
61
+
62
+ require_relative 'construqt/flavour/unknown/unknown.rb'
63
+ [
64
+ 'construqt/flavour/ciscian/ciscian.rb',
65
+ 'construqt/flavour/plantuml/plantuml.rb',
66
+ 'construqt/flavour/mikrotik/flavour_mikrotik.rb',
67
+ 'construqt/flavour/ubuntu/flavour_ubuntu.rb'].each do |fname|
68
+ begin
69
+ require_relative fname
70
+ rescue LoadError
71
+ Construqt::logger.warn("can not load driver:#{fname}")
72
+ end
73
+ end
74
+
75
+ def self.produce(region_or_hosts)
76
+ hosts = false
77
+ hosts = region_or_hosts if region_or_hosts.kind_of?(Array)
78
+ hosts = region_or_hosts.hosts.get_hosts if region_or_hosts.kind_of?(Construqt::Regions::Region)
79
+ throw "need a region or hosts list" unless hosts
80
+ Construqt::Ipsecs.build_config()
81
+ Construqt::Bgps.build_config()
82
+ hosts.inject({}) do |r, host|
83
+ r[host.region.name] ||= []
84
+ r[host.region.name] << host
85
+ r
86
+ end.values.each do |hosts|
87
+ hosts.first.region.hosts.build_config(hosts)
88
+ hosts.first.region.interfaces.build_config(hosts)
89
+ hosts.first.region.hosts.commit(hosts)
90
+ end
91
+ end
92
+ end