construqt 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2ec8fbada65d807c3b03a0659270b3574e274fce
4
+ data.tar.gz: 021691f9b160814aa6cd08580b0888337f1d8160
5
+ SHA512:
6
+ metadata.gz: cd0256802fca445d8739ba16c613a936664144cb19162ad0c09bc4b91b0e8b27b3522d304647d2b23283812c3b2843db1ee22dd376175c48310bc57eea78c1f2
7
+ data.tar.gz: e46c4967d8df48ed987ccf52b553ba2ecfb1ba4ff2c988947798f44a8ae2603c747c99bcc764776950dbefaa695034671994dbe0b1c3652b66800664986c77e9
@@ -0,0 +1,204 @@
1
+
2
+ module Construqt
3
+ class Addresses
4
+
5
+ UNREACHABLE = :unreachable
6
+ LOOOPBACK = :looopback
7
+ DHCPV4 = :dhcpv4
8
+ DHCPV6 = :dhcpv6
9
+ IPV4 = :ipv4
10
+ IPV6 = :ipv6
11
+
12
+ def initialize(network)
13
+ @network = network
14
+ @Addresses = []
15
+ end
16
+
17
+ def network
18
+ @network
19
+ end
20
+
21
+ class Address
22
+ attr_accessor :host
23
+ attr_accessor :interface
24
+ attr_accessor :ips
25
+ attr_accessor :tags
26
+ def dhcpv4?
27
+ @dhcpv4
28
+ end
29
+
30
+ def dhcpv6?
31
+ @dhcpv6
32
+ end
33
+
34
+ def loopback?
35
+ @loopback
36
+ end
37
+
38
+ def initialize()
39
+ self.ips = []
40
+ self.host = nil
41
+ self.interface = nil
42
+ self.routes = []
43
+ self.tags = []
44
+ @loopback = @dhcpv4 = @dhcpv6 = false
45
+ @name = nil
46
+ end
47
+
48
+ def match_network(ip)
49
+ if ip.ipv4?
50
+ self.v4s.find{|nip| nip.include?(ip) }
51
+ else
52
+ self.v6s.find{|nip| nip.include?(ip) }
53
+ end
54
+ end
55
+
56
+ def v6s
57
+ self.ips.select{|ip| ip.ipv6? }
58
+ end
59
+
60
+ def v4s
61
+ self.ips.select{|ip| ip.ipv4? }
62
+ end
63
+
64
+ def first_ipv4
65
+ v4s.first
66
+ end
67
+
68
+ def first_ipv6
69
+ v6s.first
70
+ end
71
+
72
+ def merge_tag(name, &block)
73
+ Construqt::Tags.add(([name]+self.tags).join("#")) { |name| block.call(name) }
74
+ end
75
+
76
+ def tag(tag)
77
+ self.tags << tag
78
+ self
79
+ end
80
+
81
+ def set_name(xname)
82
+ (@name, obj) = self.merge_tag(xname) { |xname| self }
83
+ self
84
+ end
85
+
86
+ def name=(name)
87
+ set_name(name)
88
+ end
89
+
90
+ def name
91
+ ret = self.name!
92
+ throw "unreferenced address [#{self.ips.map{|i| i.to_string }}]" unless ret
93
+ ret
94
+ end
95
+
96
+ def name!
97
+ return @name if @name
98
+ return "#{self.interface.name}-#{self.interface.host.name}" if self.interface
99
+ return self.host.name if self.host
100
+ nil
101
+ end
102
+
103
+ def add_ip(ip, region = "")
104
+ throw "please give a ip #{ip}" unless ip
105
+ if ip
106
+ #puts ">>>>> #{ip} #{ip.class.name}"
107
+ if DHCPV4 == ip
108
+ @dhcpv4 = true
109
+ elsif DHCPV6 == ip
110
+ @dhcpv6 = true
111
+ elsif LOOOPBACK == ip
112
+ @loopback = true
113
+ else
114
+ (unused, ip) = self.merge_tag(ip) { |ip| IPAddress.parse(ip) }
115
+ self.ips << ip
116
+ end
117
+ end
118
+
119
+ self
120
+ end
121
+
122
+ # @nameservers = []
123
+ # def add_nameserver(ip)
124
+ # @nameservers << IPAddress.parse(ip)
125
+ # self
126
+ # end
127
+
128
+ attr_accessor :routes
129
+ def add_routes(addr_s, via, options = {})
130
+ addrs = addr_s.kind_of?(Array) ? addr_s : [addr_s]
131
+ addrs.each{|addr| addr.ips.each {|i| add_route(i.to_string, via, options) } }
132
+ self
133
+ end
134
+
135
+ def add_route(dst, via, option = {})
136
+ #puts "DST => "+dst.class.name+":"+dst.to_s
137
+ (unused, dst) = self.merge_tag(dst) { |dst| IPAddress.parse(dst) }
138
+ metric = option['metric']
139
+ if via == UNREACHABLE
140
+ via = nil
141
+ type = 'unreachable'
142
+ else
143
+ if via.nil?
144
+ via = nil
145
+ else
146
+ via = IPAddress.parse(via)
147
+ throw "different type #{dst} #{via}" unless dst.ipv4? == via.ipv4? && dst.ipv6? == via.ipv6?
148
+ end
149
+
150
+ type = nil
151
+ end
152
+
153
+ self.routes << OpenStruct.new("dst" => dst, "via" => via, "type" => type, "metric" => metric)
154
+ self
155
+ end
156
+
157
+ def to_s
158
+ "<Address:Address #{@name}=>#{self.ips.map{|i| i.to_s}.join(":")}>"
159
+ end
160
+ end
161
+
162
+ def create
163
+ ret = Address.new()
164
+ @Addresses << ret
165
+ ret
166
+ end
167
+
168
+ def tag(tag)
169
+ create.tag(tag)
170
+ end
171
+
172
+ def add_ip(ip, region = "")
173
+ create.add_ip(ip, region)
174
+ end
175
+
176
+ def add_route(dest, via = nil)
177
+ create.add_route(dest, via)
178
+ end
179
+
180
+ def set_name(name)
181
+ create.set_name(name)
182
+ end
183
+
184
+ def all
185
+ @Addresses
186
+ end
187
+
188
+ def v4_default_route(tag = "")
189
+ nets = [(1..9),(11..126),(128..168),(170..171),(173..191),(193..223)].map do |range|
190
+ range.to_a.map{|i| "#{i}.0.0.0/8"}
191
+ end.flatten
192
+ nets += (0..255).to_a.select{|i| i!=254}.map{|i| "169.#{i}.0.0/16" }
193
+ nets += (0..255).to_a.select{|i| !(16<=i&&i<31)}.map{|i| "172.#{i}.0.0/16" }
194
+ nets += (0..255).to_a.select{|i| i!=168}.map{|i| "192.#{i}.0.0/16" }
195
+
196
+ v4_default_route = self.create
197
+ v4_default_route.set_name(tag).tag(tag) if tag && !tag.empty?
198
+ IPAddress::IPv4::summarize(*(nets.map{|i| IPAddress::IPv4.new(i) })).each do |i|
199
+ v4_default_route.add_ip(i.to_string)
200
+ end
201
+ v4_default_route
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,164 @@
1
+ module Construqt
2
+ module Bgps
3
+ class Bgp < OpenStruct
4
+ def initialize(cfg)
5
+ super(cfg)
6
+ end
7
+
8
+ def build_config()
9
+ self.left.build_config(nil, nil)
10
+ self.right.build_config(nil, nil)
11
+ end
12
+
13
+ def ident
14
+ self.left.ident
15
+ end
16
+ end
17
+
18
+ @bgps = {}
19
+ def self.connections
20
+ @bgps.values
21
+ end
22
+
23
+ def self.add_connection(cfg, id)
24
+ throw "my not found #{cfg[id]['my'].inspect}" unless cfg[id]['my']
25
+ throw "as not found #{cfg[id]['as'].inspect}" unless cfg[id]['as']
26
+ throw "as not a as #{cfg[id]['as'].inspect}" unless cfg[id]['as'].kind_of?(As)
27
+ #throw "filter not found #{cfg.inspect}" unless cfg[id]['filter']
28
+ cfg[id]['filter'] ||= {}
29
+ cfg[id]['other'] = nil
30
+ cfg[id]['cfg'] = nil
31
+ cfg[id]['host'] = cfg[id]['my'].host
32
+ cfg[id] = cfg[id]['host'].flavour.create_bgp(cfg[id])
33
+ end
34
+
35
+ def self.connection(name, cfg)
36
+ throw "filter not allowed" if cfg['filter']
37
+ throw "duplicated name #{name}" if @bgps[name]
38
+ add_connection(cfg, 'left')
39
+ add_connection(cfg, 'right')
40
+ cfg['name'] = name
41
+
42
+ cfg = @bgps[name] = Bgp.new(cfg)
43
+ cfg.left.other = cfg.right
44
+ cfg.left.cfg = cfg
45
+ cfg.right.other = cfg.left
46
+ cfg.right.cfg = cfg
47
+ cfg
48
+ end
49
+
50
+ def self.build_config()
51
+ #binding.pry
52
+ hosts = {}
53
+ @bgps.each do |name, bgp|
54
+ bgp.build_config()
55
+ hosts[bgp.left.host.name] = bgp.left
56
+ hosts[bgp.right.host.name] = bgp.right
57
+ end
58
+
59
+ #hosts.values.each do |flavour_bgp|
60
+ # flavour_bgp.header(flavour_bgp.host)
61
+ # flavour_bgp.footer(flavour_bgp.host)
62
+ #end
63
+ end
64
+
65
+ @filters = {}
66
+
67
+ class Filter
68
+ def initialize(name)
69
+ @name = name
70
+ @list = []
71
+ end
72
+
73
+ def list
74
+ @list
75
+ end
76
+
77
+ def name
78
+ @name
79
+ end
80
+
81
+ def addr_v_(cfg)
82
+ [OpenStruct.new({:code=>4, :is? => lambda {|i| i.ipv4? }, :max_prefix=>32}),
83
+ OpenStruct.new({:code=>6, :is? => lambda {|i| i.ipv6? }, :max_prefix=>128})].each do |family|
84
+ addr = cfg["addr_v#{family.code}"]
85
+ next unless addr
86
+ cfg.delete("addr_v#{family.code}")
87
+ addr_sub_prefix = cfg['addr_sub_prefix']
88
+ cfg.delete('addr_sub_prefix')
89
+ #puts addr.inspect
90
+ (addr.kind_of?(Construqt::Addresses::Address) ? [addr] : addr).each do |addr|
91
+ addr.ips.each do |net|
92
+ next unless family.is?.call(net)
93
+ network = Construqt::Addresses::Address.new
94
+ network.add_ip(net.to_string)
95
+ cfg = { 'network' => network }.merge(cfg)
96
+ cfg['prefix_length'] = [net.prefix,family.max_prefix] if addr_sub_prefix
97
+ @list << cfg
98
+ end
99
+ end
100
+
101
+ nil
102
+ end
103
+ end
104
+
105
+ def accept(cfg)
106
+ cfg = {}.merge(cfg)
107
+ cfg['rule'] = 'accept'
108
+ addr_v_(cfg)
109
+ @list << cfg if cfg['network']
110
+ end
111
+
112
+ def reject(cfg)
113
+ cfg = {}.merge(cfg)
114
+ cfg['rule'] = 'reject'
115
+ addr_v_(cfg)
116
+ @list << cfg if cfg['network']
117
+ end
118
+ end
119
+
120
+ class As < OpenStruct
121
+ def initialize(cfg)
122
+ super(cfg)
123
+ end
124
+
125
+ def name
126
+ (self.prefix || "AS") + self.as.to_s
127
+ end
128
+
129
+ def num
130
+ self.as
131
+ end
132
+ end
133
+
134
+ @as = {}
135
+ def self.add_as(as, config)
136
+ throw "as must be a number #{as}" unless as.kind_of?(Fixnum)
137
+ throw "as defined before #{as}" if @as[as]
138
+ config['as'] = as
139
+ @as[as] = As.new(config)
140
+ end
141
+
142
+ def self.find_as(as)
143
+ ret = @as[as]
144
+ throw "as not found #{as}" unless ret
145
+ ret
146
+ end
147
+
148
+ def self.add_filter(name, &block)
149
+ @filters[name] = Filter.new(name)
150
+ block.call(@filters[name])
151
+ @filters[name]
152
+ end
153
+
154
+ def self.filters
155
+ @filters.values
156
+ end
157
+
158
+ def self.find_filter(name)
159
+ ret = @filters[name]
160
+ throw "bgp not filter with name #{name}" unless ret
161
+ ret
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,47 @@
1
+
2
+ module Construqt
3
+
4
+ class Cables
5
+
6
+ def initialize(region)
7
+ @region = region
8
+ @cables = {}
9
+ end
10
+
11
+ def region
12
+ @region
13
+ end
14
+
15
+ class Cable
16
+ attr_reader :left, :right
17
+ def initialize(left, right)
18
+ @left = left
19
+ @right = right
20
+ end
21
+
22
+ def key
23
+ [left.name, right.name].sort.join("<=>")
24
+ end
25
+ end
26
+
27
+ class DirectedCable
28
+ attr_accessor :cable, :other
29
+ def initialize(cable, other)
30
+ self.cable = cable
31
+ self.other = other
32
+ end
33
+ end
34
+
35
+ def add(iface_left, iface_right)
36
+ # throw "left should be a iface #{iface_left.class.name}" unless iface_left.kind_of?(Construqt::Flavour::InterfaceDelegate)
37
+ # throw "right should be a iface #{iface_right.class.name}" unless iface_right.kind_of?(Construqt::Flavour::InterfaceDelegate)
38
+ throw "left has a cable #{iface_left.cable}" if iface_left.cable
39
+ throw "right has a cable #{iface_right.cable}" if iface_right.cable
40
+ cable = Cable.new(iface_left, iface_right)
41
+ throw "cable exists #{iface_left.cable}=#{iface_right.cable}" if @cables[cable.key]
42
+ iface_left.cable = DirectedCable.new(cable, iface_right)
43
+ iface_right.cable = DirectedCable.new(cable, iface_left)
44
+ cable
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,247 @@
1
+ module Construqt
2
+ module Firewalls
3
+
4
+ @firewalls = {}
5
+ module Actions
6
+ NOTRACK = :NOTRACK
7
+ SNAT = :SNAT
8
+ ACCEPT = :ACCEPT
9
+ DROP = :DROP
10
+ end
11
+
12
+ class Firewall
13
+ def initialize(name)
14
+ @name = name
15
+ @raw = Raw.new(self)
16
+ @nat = Nat.new(self)
17
+ @forward = Forward.new(self)
18
+ @host = Host.new(self)
19
+ end
20
+
21
+ def name
22
+ @name
23
+ end
24
+
25
+ class Raw
26
+ attr_reader :firewall
27
+ def initialize(firewall)
28
+ @firewall = firewall
29
+ @rules = []
30
+ end
31
+
32
+ class RawEntry
33
+ include Util::Chainable
34
+ chainable_attr :prerouting, true, false, lambda{|i| @output = false; input_only(true); output_only(false) }
35
+ chainable_attr :input_only, true
36
+ chainable_attr :output, true, false, lambda {|i| @prerouting = false; input_only(false); output_only(true) }
37
+ chainable_attr :output_only, true
38
+ chainable_attr :interface
39
+ chainable_attr :from_interface, true, false
40
+ chainable_attr_value :from_net, nil
41
+ chainable_attr_value :to, nil
42
+ chainable_attr_value :to_net, nil
43
+ chainable_attr_value :action, nil
44
+
45
+ def initialize
46
+ @from_is = nil
47
+ end
48
+
49
+ def from_is_inbound?
50
+ @from_is == :inbound
51
+ end
52
+ def from_is_outbound?
53
+ @from_is == :outbound
54
+ end
55
+ def from_is(direction)
56
+ @from_is = direction
57
+ end
58
+ end
59
+
60
+ def add
61
+ entry = RawEntry.new
62
+ @rules << entry
63
+ entry
64
+ end
65
+
66
+
67
+ def rules
68
+ @rules
69
+ end
70
+ end
71
+
72
+ def get_raw
73
+ @raw
74
+ end
75
+
76
+ def raw(&block)
77
+ block.call(@raw)
78
+ end
79
+
80
+ class Nat
81
+ attr_reader :firewall, :rules
82
+ def initialize(firewall)
83
+ @firewall = firewall
84
+ @rules = []
85
+ end
86
+
87
+ class NatEntry
88
+ include Util::Chainable
89
+ chainable_attr :prerouting, true, false, lambda{|i| @postrouting = false; input_only(true); output_only(false) }
90
+ chainable_attr :input_only
91
+ chainable_attr :postrouting, true, false, lambda{|i| @prerouting = false; input_only(false); output_only(true) }
92
+ chainable_attr :output_only
93
+ chainable_attr :to_source
94
+ chainable_attr :interface
95
+ chainable_attr :from_interface, true, false
96
+ chainable_attr_value :from_net, nil
97
+ chainable_attr_value :to_net, nil
98
+ chainable_attr_value :action, nil
99
+ end
100
+
101
+ def add
102
+ entry = NatEntry.new
103
+ @rules << entry
104
+ entry
105
+ end
106
+ end
107
+
108
+ def get_nat
109
+ @nat
110
+ end
111
+
112
+ def nat(&block)
113
+ block.call(@nat)
114
+ end
115
+
116
+ class Mangle
117
+ @rules = []
118
+ class Tcpmss
119
+ end
120
+
121
+ def tcpmss
122
+ @rules << Tcpmss.new
123
+ end
124
+ end
125
+
126
+ def mangle(&block)
127
+ block.call(@mangle)
128
+ end
129
+
130
+ class Forward
131
+ attr_reader :firewall, :rules
132
+ def initialize(firewall)
133
+ @firewall = firewall
134
+ @rules = []
135
+ end
136
+
137
+ class ForwardEntry
138
+ include Util::Chainable
139
+ chainable_attr :interface
140
+ chainable_attr :connection
141
+ chainable_attr :input_only, true, true
142
+ chainable_attr :output_only, true, true
143
+ chainable_attr :from_interface, true, false
144
+ chainable_attr :connection
145
+ chainable_attr :tcp
146
+ chainable_attr :udp
147
+ chainable_attr_value :log, nil
148
+ chainable_attr_value :from_net, nil
149
+ chainable_attr_value :to_net, nil
150
+ chainable_attr_value :action, nil
151
+
152
+ def initialize
153
+ @from_is = nil
154
+ end
155
+
156
+ def from_is_inbound?
157
+ @from_is == :inbound
158
+ end
159
+ def from_is_outbound?
160
+ @from_is == :outbound
161
+ end
162
+ def from_is(direction)
163
+ @from_is = direction
164
+ end
165
+
166
+ def port(port)
167
+ @ports ||= []
168
+ @ports << port
169
+ self
170
+ end
171
+
172
+ def get_ports
173
+ @ports ||= []
174
+ end
175
+ end
176
+
177
+ def add
178
+ entry = ForwardEntry.new
179
+ #puts "ForwardEntry: #{@firewall.name} #{entry.input_only?} #{entry.output_only?}"
180
+ @rules << entry
181
+ entry
182
+ end
183
+ end
184
+
185
+ def get_forward
186
+ @forward
187
+ end
188
+
189
+ def forward(&block)
190
+ block.call(@forward)
191
+ end
192
+
193
+ class Host
194
+ attr_reader :firewall, :rules
195
+ def initialize(firewall)
196
+ @firewall = firewall
197
+ @rules = []
198
+ end
199
+
200
+ class HostEntry < Forward::ForwardEntry
201
+ include Util::Chainable
202
+ chainable_attr :from_host
203
+ chainable_attr :to_host
204
+ end
205
+
206
+ def add
207
+ entry = HostEntry.new
208
+ #puts "ForwardEntry: #{@firewall.name} #{entry.input_only?} #{entry.output_only?}"
209
+ @rules << entry
210
+ entry
211
+ end
212
+ end
213
+
214
+ def get_host
215
+ @host
216
+ end
217
+
218
+ def host(&block)
219
+ block.call(@host)
220
+ end
221
+
222
+ # class Input
223
+ # class All
224
+ # end
225
+
226
+ # @rules = []
227
+ # def all(cfg)
228
+ # @rules << All.new(cfg)
229
+ # end
230
+
231
+ # end
232
+ end
233
+
234
+ def self.add(name, &block)
235
+ throw "firewall with this name exists #{name}" if @firewalls[name]
236
+ fw = @firewalls[name] = Firewall.new(name)
237
+ block.call(fw)
238
+ fw
239
+ end
240
+
241
+ def self.find(name)
242
+ ret = @firewalls[name]
243
+ throw "firewall with this name #{name} not found" unless @firewalls[name]
244
+ ret
245
+ end
246
+ end
247
+ end