wakame-vdc-agents 11.06.0 → 11.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. data/Rakefile +19 -31
  2. data/bin/hva +15 -5
  3. data/bin/nsa +15 -5
  4. data/bin/sta +9 -222
  5. data/config/db/migrations/0001_v1110_origin.rb +446 -0
  6. data/config/hva.conf.example +19 -11
  7. data/config/nsa.conf.example +1 -1
  8. data/lib/dcmgr.rb +99 -22
  9. data/lib/dcmgr/cli/base.rb +34 -1
  10. data/lib/dcmgr/cli/host.rb +24 -20
  11. data/lib/dcmgr/cli/image.rb +38 -19
  12. data/lib/dcmgr/cli/keypair.rb +16 -12
  13. data/lib/dcmgr/cli/network.rb +189 -81
  14. data/lib/dcmgr/cli/quota.rb +2 -2
  15. data/lib/dcmgr/cli/security_group.rb +106 -0
  16. data/lib/dcmgr/cli/spec.rb +144 -39
  17. data/lib/dcmgr/cli/storage.rb +16 -15
  18. data/lib/dcmgr/cli/tag.rb +20 -14
  19. data/lib/dcmgr/cli/vlan.rb +5 -5
  20. data/lib/dcmgr/drivers/backing_store.rb +32 -0
  21. data/lib/dcmgr/drivers/comstar.rb +81 -0
  22. data/lib/dcmgr/drivers/iijgio_storage.rb +9 -19
  23. data/lib/dcmgr/drivers/iscsi_target.rb +41 -0
  24. data/lib/dcmgr/drivers/kvm.rb +161 -28
  25. data/lib/dcmgr/drivers/linux_iscsi.rb +60 -0
  26. data/lib/dcmgr/drivers/local_storage.rb +24 -0
  27. data/lib/dcmgr/drivers/lxc.rb +167 -125
  28. data/lib/dcmgr/drivers/raw.rb +74 -0
  29. data/lib/dcmgr/drivers/s3_storage.rb +7 -19
  30. data/lib/dcmgr/drivers/snapshot_storage.rb +18 -28
  31. data/lib/dcmgr/drivers/storage_initiator.rb +28 -0
  32. data/lib/dcmgr/drivers/sun_iscsi.rb +32 -0
  33. data/lib/dcmgr/drivers/zfs.rb +77 -0
  34. data/lib/dcmgr/endpoints/core_api.rb +315 -263
  35. data/lib/dcmgr/endpoints/errors.rb +21 -10
  36. data/lib/dcmgr/endpoints/metadata.rb +360 -23
  37. data/lib/dcmgr/helpers/cli_helper.rb +6 -3
  38. data/lib/dcmgr/helpers/ec2_metadata_helper.rb +9 -0
  39. data/lib/dcmgr/helpers/nic_helper.rb +11 -0
  40. data/lib/dcmgr/helpers/snapshot_storage_helper.rb +34 -0
  41. data/lib/dcmgr/models/account.rb +0 -6
  42. data/lib/dcmgr/models/account_resource.rb +0 -4
  43. data/lib/dcmgr/models/base_new.rb +14 -2
  44. data/lib/dcmgr/models/dhcp_range.rb +38 -0
  45. data/lib/dcmgr/models/frontend_system.rb +0 -6
  46. data/lib/dcmgr/models/history.rb +0 -11
  47. data/lib/dcmgr/models/host_node.rb +131 -0
  48. data/lib/dcmgr/models/hostname_lease.rb +0 -8
  49. data/lib/dcmgr/models/image.rb +31 -18
  50. data/lib/dcmgr/models/instance.rb +137 -143
  51. data/lib/dcmgr/models/instance_nic.rb +52 -29
  52. data/lib/dcmgr/models/instance_security_group.rb +9 -0
  53. data/lib/dcmgr/models/instance_spec.rb +163 -31
  54. data/lib/dcmgr/models/ip_lease.rb +10 -21
  55. data/lib/dcmgr/models/mac_lease.rb +30 -11
  56. data/lib/dcmgr/models/network.rb +148 -27
  57. data/lib/dcmgr/models/physical_network.rb +18 -0
  58. data/lib/dcmgr/models/quota.rb +0 -10
  59. data/lib/dcmgr/models/request_log.rb +3 -18
  60. data/lib/dcmgr/models/security_group.rb +66 -0
  61. data/lib/dcmgr/models/security_group_rule.rb +145 -0
  62. data/lib/dcmgr/models/ssh_key_pair.rb +16 -19
  63. data/lib/dcmgr/models/{storage_pool.rb → storage_node.rb} +35 -25
  64. data/lib/dcmgr/models/tag.rb +0 -14
  65. data/lib/dcmgr/models/tag_mapping.rb +1 -7
  66. data/lib/dcmgr/models/vlan_lease.rb +2 -8
  67. data/lib/dcmgr/models/volume.rb +49 -37
  68. data/lib/dcmgr/models/volume_snapshot.rb +15 -17
  69. data/lib/dcmgr/node_modules/hva_collector.rb +69 -28
  70. data/lib/dcmgr/node_modules/instance_ha.rb +23 -12
  71. data/lib/dcmgr/node_modules/instance_monitor.rb +16 -2
  72. data/lib/dcmgr/node_modules/openflow_controller.rb +784 -0
  73. data/lib/dcmgr/node_modules/scheduler.rb +189 -0
  74. data/lib/dcmgr/node_modules/service_netfilter.rb +452 -227
  75. data/lib/dcmgr/node_modules/service_openflow.rb +731 -0
  76. data/lib/dcmgr/node_modules/sta_collector.rb +20 -0
  77. data/lib/dcmgr/node_modules/sta_tgt_initializer.rb +35 -0
  78. data/lib/dcmgr/rack/request_logger.rb +11 -6
  79. data/lib/dcmgr/rpc/hva_handler.rb +256 -110
  80. data/lib/dcmgr/rpc/sta_handler.rb +244 -0
  81. data/lib/dcmgr/scheduler.rb +122 -8
  82. data/lib/dcmgr/scheduler/host_node/exclude_same.rb +24 -0
  83. data/lib/dcmgr/scheduler/host_node/find_first.rb +12 -0
  84. data/lib/dcmgr/scheduler/host_node/least_usage.rb +28 -0
  85. data/lib/dcmgr/scheduler/host_node/per_instance.rb +18 -0
  86. data/lib/dcmgr/scheduler/host_node/specify_node.rb +26 -0
  87. data/lib/dcmgr/scheduler/network/flat_single.rb +23 -0
  88. data/lib/dcmgr/scheduler/network/nat_one_to_one.rb +23 -0
  89. data/lib/dcmgr/scheduler/network/per_instance.rb +39 -0
  90. data/lib/dcmgr/scheduler/network/vif_template.rb +19 -0
  91. data/lib/dcmgr/scheduler/storage_node/find_first.rb +13 -0
  92. data/lib/dcmgr/scheduler/storage_node/least_usage.rb +23 -0
  93. data/lib/dcmgr/storage_service.rb +39 -40
  94. data/lib/dcmgr/tags.rb +3 -3
  95. data/lib/dcmgr/version.rb +1 -1
  96. data/lib/dcmgr/vnet.rb +105 -0
  97. data/lib/dcmgr/vnet/factories.rb +141 -0
  98. data/lib/dcmgr/vnet/isolators/by_securitygroup.rb +21 -0
  99. data/lib/dcmgr/vnet/isolators/dummy.rb +17 -0
  100. data/lib/dcmgr/vnet/netfilter/cache.rb +51 -0
  101. data/lib/dcmgr/vnet/netfilter/chain.rb +66 -0
  102. data/lib/dcmgr/vnet/netfilter/controller.rb +193 -0
  103. data/lib/dcmgr/vnet/netfilter/ebtables_rule.rb +53 -0
  104. data/lib/dcmgr/vnet/netfilter/iptables_rule.rb +45 -0
  105. data/lib/dcmgr/vnet/netfilter/task_manager.rb +459 -0
  106. data/lib/dcmgr/vnet/tasks/accept_all_dns.rb +19 -0
  107. data/lib/dcmgr/vnet/tasks/accept_arp_broadcast.rb +24 -0
  108. data/lib/dcmgr/vnet/tasks/accept_arp_from_friends.rb +34 -0
  109. data/lib/dcmgr/vnet/tasks/accept_arp_from_gateway.rb +21 -0
  110. data/lib/dcmgr/vnet/tasks/accept_arp_to_host.rb +30 -0
  111. data/lib/dcmgr/vnet/tasks/accept_ip_from_friends.rb +26 -0
  112. data/lib/dcmgr/vnet/tasks/accept_ip_from_gateway.rb +23 -0
  113. data/lib/dcmgr/vnet/tasks/accept_ip_to_anywhere.rb +18 -0
  114. data/lib/dcmgr/vnet/tasks/accept_related_established.rb +45 -0
  115. data/lib/dcmgr/vnet/tasks/accept_wakame_dhcp_only.rb +33 -0
  116. data/lib/dcmgr/vnet/tasks/accept_wakame_dns_only.rb +33 -0
  117. data/lib/dcmgr/vnet/tasks/debug_iptables.rb +21 -0
  118. data/lib/dcmgr/vnet/tasks/drop_arp_forwarding.rb +27 -0
  119. data/lib/dcmgr/vnet/tasks/drop_arp_to_host.rb +24 -0
  120. data/lib/dcmgr/vnet/tasks/drop_ip_from_anywhere.rb +18 -0
  121. data/lib/dcmgr/vnet/tasks/drop_ip_spoofing.rb +34 -0
  122. data/lib/dcmgr/vnet/tasks/drop_mac_spoofing.rb +33 -0
  123. data/lib/dcmgr/vnet/tasks/exclude_from_nat.rb +47 -0
  124. data/lib/dcmgr/vnet/tasks/security_group.rb +37 -0
  125. data/lib/dcmgr/vnet/tasks/static_nat.rb +54 -0
  126. data/lib/dcmgr/vnet/tasks/translate_metadata_address.rb +32 -0
  127. metadata +105 -68
  128. data/lib/dcmgr/cli/group.rb +0 -101
  129. data/lib/dcmgr/endpoints/core_api_mock.rb +0 -865
  130. data/lib/dcmgr/models/host_pool.rb +0 -122
  131. data/lib/dcmgr/models/instance_netfilter_group.rb +0 -16
  132. data/lib/dcmgr/models/netfilter_group.rb +0 -89
  133. data/lib/dcmgr/models/netfilter_rule.rb +0 -21
  134. data/lib/dcmgr/scheduler/find_last.rb +0 -16
  135. data/lib/dcmgr/scheduler/find_random.rb +0 -16
  136. data/lib/dcmgr/stm/instance.rb +0 -25
  137. data/lib/dcmgr/stm/snapshot_context.rb +0 -33
  138. data/lib/dcmgr/stm/volume_context.rb +0 -65
@@ -0,0 +1,459 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr
4
+ module VNet
5
+ module Netfilter
6
+
7
+ # Abstract class for task managers that apply netfilter to extend.
8
+ # These have extra methods to create custom chains depending on vnic.
9
+ # Tasks can then be applied to these custom chains.
10
+ class NetfilterTaskManager < TaskManager
11
+
12
+ def apply_vnic_chains(vnic_map)
13
+ raise NotImplementedError
14
+ end
15
+
16
+ def apply_vnic_tasks(vnic_map,tasks)
17
+ raise NotImplementedError
18
+ end
19
+
20
+ # Should remove _tasks_ for this specific vnic if they are applied
21
+ def remove_vnic_tasks(vnic_map,tasks = nil)
22
+ raise NotImplementedError
23
+ end
24
+
25
+ def remove_vnic_chains(vnic_map)
26
+ raise NotImplementedError
27
+ end
28
+ end
29
+
30
+ # Task manager that creates chains based on vif uuid and protocol
31
+ # Supports ebtables rules and iptables rules
32
+ class VNicProtocolTaskManager < NetfilterTaskManager
33
+ include Dcmgr::Helpers::NicHelper
34
+ # These store the protocols used by iptables and ebtables
35
+ attr_reader :iptables_protocols
36
+ attr_reader :ebtables_protocols
37
+ # These are flags that decide whether or not iptables and ebtables are enabled
38
+ attr_accessor :enable_iptables
39
+ attr_accessor :enable_ebtables
40
+ # Flag that decides whether or not we output commands that are applied
41
+ attr_accessor :verbose_commands
42
+
43
+ def initialize
44
+ super
45
+ @iptables_protocols = IptablesRule.protocols
46
+ @ebtables_protocols = EbtablesRule.protocols
47
+ end
48
+
49
+ def iptables_chains(vnic_map)
50
+ chains = []
51
+
52
+ [ 's', 'd' ].each { |bound|
53
+ self.iptables_protocols.each { |k,v|
54
+ chains << IptablesChain.new(:filter, "#{bound}_#{vnic_map[:uuid]}")
55
+ chains << IptablesChain.new(:filter, "#{bound}_#{vnic_map[:uuid]}_#{k}")
56
+
57
+ chains << IptablesChain.new(:filter, "#{bound}_#{vnic_map[:uuid]}_drop")
58
+ chains << IptablesChain.new(:filter, "#{bound}_#{vnic_map[:uuid]}_#{k}_drop")
59
+ }
60
+
61
+ #[ 'pre', 'post'].each { |nat_chain|
62
+ #chains << IptablesChain.new(:nat, "#{bound}_#{vnic_map[:uuid]}_#{nat_chain}")
63
+ #}
64
+ }
65
+ #chains << IptablesChain.new(:nat, "#{vnic_map[:uuid]}_dnat_exceptions")
66
+ chains << IptablesChain.new(:nat, "#{vnic_map[:uuid]}_snat_exceptions")
67
+ chains << IptablesChain.new(:nat, "#{vnic_map[:uuid]}_snat")
68
+
69
+ chains
70
+ end
71
+
72
+ def iptables_forward_chain_jumps(vnic)
73
+ jumps = []
74
+
75
+ #Main jumps from the forward chains
76
+ jumps << IptablesRule.new(:filter,:forward,nil,nil,"-m physdev --physdev-is-bridged --physdev-in #{vnic[:uuid]} -j s_#{vnic[:uuid]}")
77
+ jumps << IptablesRule.new(:filter,:forward,nil,nil,"-m physdev --physdev-is-bridged --physdev-out #{vnic[:uuid]} -j d_#{vnic[:uuid]}")
78
+
79
+ jumps
80
+ end
81
+
82
+ def iptables_protocol_chain_jumps(vnic)
83
+ jumps = []
84
+
85
+ [ 's', 'd' ].each do |bound|
86
+ self.iptables_protocols.each { |k,v|
87
+ case k
88
+ when 'tcp'
89
+ case bound
90
+ when 's'
91
+ jumps << IptablesRule.new(:filter,"#{bound}_#{vnic[:uuid]}",nil,:outgoing,"-m state --state NEW,ESTABLISHED -p #{k} -j #{bound}_#{vnic[:uuid]}_#{k}")
92
+ when 'd'
93
+ jumps << IptablesRule.new(:filter,"#{bound}_#{vnic[:uuid]}",nil,:incoming,"-p #{k} -j #{bound}_#{vnic[:uuid]}_#{k}")
94
+ end
95
+ when 'udp'
96
+ case bound
97
+ when 's'
98
+ jumps << IptablesRule.new(:filter,"#{bound}_#{vnic[:uuid]}",nil,:outgoing,"-m state --state NEW,ESTABLISHED -p #{k} -j #{bound}_#{vnic[:uuid]}_#{k}")
99
+ when 'd'
100
+ jumps << IptablesRule.new(:filter,"#{bound}_#{vnic[:uuid]}",nil,:incoming,"-p #{k} -j #{bound}_#{vnic[:uuid]}_#{k}")
101
+ end
102
+ when 'icmp'
103
+ case bound
104
+ when 's'
105
+ jumps << IptablesRule.new(:filter,"#{bound}_#{vnic[:uuid]}",nil,:outgoing,"-m state --state NEW,ESTABLISHED,RELATED -p #{k} -j #{bound}_#{vnic[:uuid]}_#{k}")
106
+ when 'd'
107
+ jumps << IptablesRule.new(:filter,"#{bound}_#{vnic[:uuid]}",nil,:incoming,"-p #{k} -j #{bound}_#{vnic[:uuid]}_#{k}")
108
+ end
109
+ end
110
+ }
111
+ end
112
+
113
+ jumps
114
+ end
115
+
116
+ # Returns the rules that direct packets for a vnic to that specific vnic's custom nat chains
117
+ def iptables_nat_chain_jumps(vnic_map)
118
+ jumps = []
119
+
120
+ #[ :prerouting, :postrouting].each { |chain|
121
+ #jumps << IptablesRule.new(:nat,:prerouting,nil,nil,"-d #{vnic_map[:ipv4][:nat_address]} -j #{vnic_map[:uuid]}_dnat_exceptions")
122
+ jumps << IptablesRule.new(:nat,:postrouting,nil,nil,"-s #{vnic_map[:ipv4][:address]} -j #{vnic_map[:uuid]}_snat_exceptions")
123
+ jumps << IptablesRule.new(:nat,:postrouting,nil,nil,"-s #{vnic_map[:ipv4][:address]} -j #{vnic_map[:uuid]}_snat")
124
+ #}
125
+
126
+ #jumps << IptablesRule.new(:nat,:prerouting,nil,nil,"-m physdev --physdev-in #{vnic[:uuid]} -j s_#{vnic[:uuid]}_pre")
127
+ #jumps << IptablesRule.new(:nat,:prerouting,nil,nil,"-m physdev --physdev-out #{vnic[:uuid]} -j d_#{vnic[:uuid]}_pre")
128
+ #jumps << IptablesRule.new(:nat,:postrouting,nil,nil,"-m physdev --physdev-in #{vnic[:uuid]} -j s_#{vnic[:uuid]}_post")
129
+ #jumps << IptablesRule.new(:nat,:postrouting,nil,nil,"-m physdev --physdev-out #{vnic[:uuid]} -j d_#{vnic[:uuid]}_post")
130
+
131
+ jumps
132
+ end
133
+
134
+ def ebtables_chains(vnic)
135
+ chains = []
136
+
137
+ chains << EbtablesChain.new(:filter, "s_#{vnic[:uuid]}")
138
+ chains << EbtablesChain.new(:filter, "d_#{vnic[:uuid]}")
139
+ chains << EbtablesChain.new(:filter, "s_#{vnic[:uuid]}_d_hst")
140
+ chains << EbtablesChain.new(:filter, "d_#{vnic[:uuid]}_s_hst")
141
+ self.ebtables_protocols.each { |k,v|
142
+ chains << EbtablesChain.new(:filter, "s_#{vnic[:uuid]}_#{k}")
143
+ chains << EbtablesChain.new(:filter, "d_#{vnic[:uuid]}_#{k}")
144
+ chains << EbtablesChain.new(:filter, "s_#{vnic[:uuid]}_d_hst_#{k}")
145
+ chains << EbtablesChain.new(:filter, "d_#{vnic[:uuid]}_s_hst_#{k}")
146
+ }
147
+
148
+ chains
149
+ end
150
+
151
+ def ebtables_forward_chain_jumps(vnic)
152
+ jumps = []
153
+
154
+ jumps << EbtablesRule.new(:filter,:forward,nil,nil,"-i #{vnic[:uuid]} -j s_#{vnic[:uuid]}")
155
+ jumps << EbtablesRule.new(:filter,:forward,nil,nil,"-o #{vnic[:uuid]} -j d_#{vnic[:uuid]}")
156
+
157
+ jumps
158
+ end
159
+
160
+ def ebtables_protocol_chain_jumps(vnic)
161
+ jumps = []
162
+
163
+ self.ebtables_protocols.each { |k,v|
164
+ jumps << EbtablesRule.new(:filter,"s_#{vnic[:uuid]}",nil,:outgoing,"-p #{v} -j s_#{vnic[:uuid]}_#{k}")
165
+ jumps << EbtablesRule.new(:filter,"d_#{vnic[:uuid]}",nil,:incoming,"-p #{v} -j d_#{vnic[:uuid]}_#{k}")
166
+ jumps << EbtablesRule.new(:filter,"s_#{vnic[:uuid]}_d_hst",nil,:outgoing,"-p #{v} -j s_#{vnic[:uuid]}_d_hst_#{k}")
167
+ jumps << EbtablesRule.new(:filter,"d_#{vnic[:uuid]}_s_hst",nil,:incoming,"-p #{v} -j d_#{vnic[:uuid]}_s_hst_#{k}")
168
+ }
169
+
170
+ jumps
171
+ end
172
+
173
+ def ebtables_input_chain_jumps(vnic)
174
+ jumps = []
175
+
176
+ jumps << EbtablesRule.new(:filter,:input,nil,:outgoing,"-i #{vnic[:uuid]} -j s_#{vnic[:uuid]}_d_hst")
177
+
178
+ jumps
179
+ end
180
+
181
+ def ebtables_output_chain_jumps(vnic)
182
+ jumps = []
183
+
184
+ jumps << EbtablesRule.new(:filter,:output,nil,:incoming,"-o #{vnic[:uuid]} -j d_#{vnic[:uuid]}_s_hst")
185
+
186
+ jumps
187
+ end
188
+
189
+ #Returns commands for creating iptables chains and their jump rules
190
+ def get_iptables_chains_apply_commands(vnic_map)
191
+ commands = []
192
+
193
+ commands << iptables_chains(vnic_map).map { |chain| "iptables -t #{chain.table} -N #{chain.name}"}
194
+
195
+ create_jump_block = Proc.new { |jump|
196
+ "iptables -t #{jump.table} -A #{jump.chain} #{jump.rule}"
197
+ }
198
+
199
+ commands << iptables_forward_chain_jumps(vnic_map).map(&create_jump_block)
200
+ commands << iptables_nat_chain_jumps(vnic_map).map(&create_jump_block)
201
+ commands << iptables_protocol_chain_jumps(vnic_map).map(&create_jump_block)
202
+
203
+ commands.flatten.uniq
204
+ end
205
+
206
+ # Apply the custom iptables chains for this vnic
207
+ # This method only applies the chains and doesn't make any rules
208
+ def apply_iptables_chains(vnic_map)
209
+ cmds = get_iptables_chains_apply_commands(vnic_map)
210
+ puts cmds.join("\n") if self.verbose_commands
211
+ system(cmds.join("\n"))
212
+ end
213
+
214
+ def remove_iptables_chains(vnic)
215
+ cmds = get_iptables_chains_remove_commands(vnic)
216
+ puts cmds.join("\n") if self.verbose_commands
217
+ system(cmds.join("\n"))
218
+ end
219
+
220
+ def get_iptables_chains_remove_commands(vnic_map)
221
+ commands = []
222
+
223
+ delete_jump_block = Proc.new {|jump| "iptables -t #{jump.table} -D #{jump.chain} #{jump.rule}"}
224
+
225
+ commands << iptables_forward_chain_jumps(vnic_map).map(&delete_jump_block)
226
+ commands << iptables_nat_chain_jumps(vnic_map).map(&delete_jump_block)
227
+
228
+ commands << iptables_chains(vnic_map).map {|chain|
229
+ ["iptables -t #{chain.table} -F #{chain.name}","iptables -t #{chain.table} -X #{chain.name}"]
230
+ }
231
+
232
+ commands.flatten.uniq
233
+ end
234
+
235
+ def apply_ebtables_chains(vnic_map)
236
+ cmds = get_ebtables_chains_apply_commands(vnic_map)
237
+ puts cmds.join("\n") if self.verbose_commands
238
+ system(cmds.join("\n"))
239
+ end
240
+
241
+ def get_ebtables_chains_apply_commands(vnic_map)
242
+ commands = []
243
+
244
+ commands << ebtables_chains(vnic_map).map {|chain| ["ebtables -t #{chain.table} -N #{chain.name}","ebtables -t #{chain.table} -P #{chain.name} RETURN"]}#,"ebtables -t #{chain.table} -P #{chain.name} DROP"]}
245
+
246
+ create_jump_block = Proc.new {|jump| "ebtables -t #{jump.table} -A #{jump.chain} #{jump.rule}"}
247
+
248
+ commands << ebtables_forward_chain_jumps(vnic_map).map(&create_jump_block)
249
+ commands << ebtables_input_chain_jumps(vnic_map).map(&create_jump_block)
250
+ commands << ebtables_output_chain_jumps(vnic_map).map(&create_jump_block)
251
+ commands << ebtables_protocol_chain_jumps(vnic_map).map(&create_jump_block)
252
+
253
+ commands.flatten.uniq
254
+ end
255
+
256
+ def remove_ebtables_chains(vnic)
257
+ cmds = get_ebtables_chains_remove_commands(vnic)
258
+ puts cmds.join("\n") if self.verbose_commands
259
+ system(cmds.join("\n"))
260
+ end
261
+
262
+ def get_ebtables_chains_remove_commands(vnic_map)
263
+ commands = []
264
+
265
+ delete_jump_block = Proc.new {|jump| "ebtables -t #{jump.table} -D #{jump.chain} #{jump.rule}"}
266
+
267
+ commands << ebtables_forward_chain_jumps(vnic_map).map(&delete_jump_block)
268
+ commands << ebtables_input_chain_jumps(vnic_map).map(&delete_jump_block)
269
+ commands << ebtables_output_chain_jumps(vnic_map).map(&delete_jump_block)
270
+
271
+ commands << ebtables_chains(vnic_map).map {|chain|
272
+ ["ebtables -t #{chain.table} -F #{chain.name}","ebtables -t #{chain.table} -X #{chain.name}"]
273
+ }
274
+
275
+ commands.flatten.uniq
276
+ end
277
+
278
+ # Jumps to custom chains named after the vnic's uuid,
279
+ # then jumps to more custom chains based on the protocol used.
280
+ # In those the real netfiltering happens
281
+ def apply_vnic_tasks(vnic_map, tasks)
282
+ # Apply the tasks to our chains
283
+ apply_tasks(tailor_vnic_tasks(vnic_map,tasks))
284
+ end
285
+
286
+ def apply_vnic_chains(vnic_map)
287
+ apply_iptables_chains(vnic_map) if self.enable_iptables
288
+ apply_ebtables_chains(vnic_map) if self.enable_ebtables
289
+ end
290
+
291
+ # Translates _rule_ into a command that can be directly passed on to the OS
292
+ # _action_ determines if the command must _:apply_ or _:remove_ a rule.
293
+ def get_rule_command(rule,action)
294
+ actions = {:apply => "I", :remove => "D"}
295
+ raise ArgumentError, "#{rule} is not a Rule" unless rule.is_a? Rule
296
+ raise ArgumentError, "action must be one of the following: '#{actions.keys.join(",")}'" unless actions.member? action
297
+
298
+ if rule.is_a?(IptablesRule) && self.enable_iptables
299
+ "iptables -t #{rule.table} -#{actions[action]} #{rule.chain} #{rule.rule}"
300
+ elsif rule.is_a?(EbtablesRule) && self.enable_ebtables
301
+ "ebtables -t #{rule.table} -#{actions[action]} #{rule.chain} #{rule.rule}"
302
+ else
303
+ nil
304
+ end
305
+ end
306
+
307
+ def apply_tasks(tasks)
308
+ commands = []
309
+
310
+ commands = tasks.map { |task|
311
+ next unless task.is_a? Task
312
+ task.rules.map { |rule|
313
+ next unless rule.is_a? Rule
314
+ get_rule_command(rule,:apply)
315
+ }
316
+ }
317
+
318
+ final_commands = commands.flatten.uniq.compact
319
+ puts final_commands.join("\n") if self.verbose_commands
320
+
321
+ system(final_commands.join("\n"))
322
+ end
323
+
324
+ def remove_tasks(tasks)
325
+ commands = []
326
+
327
+ commands = tasks.map { |task|
328
+ next unless task.is_a? Task
329
+ task.rules.map { |rule|
330
+ get_rule_command(rule,:remove)
331
+ }
332
+ }
333
+
334
+ final_commands = commands.flatten.uniq.compact
335
+ puts final_commands.join("\n") if self.verbose_commands
336
+
337
+ system(final_commands.join("\n"))
338
+ end
339
+
340
+ # Changes the chains of each rule in _tasks_ to match this TaskManager's model
341
+ def tailor_vnic_tasks(vnic,tasks)
342
+ bound = {:incoming => "d", :outgoing => "s"}
343
+ nat_chains = {"PREROUTING" => "pre", "POSTROUTING" => "post"}
344
+
345
+ # Use the marshal trick to make a deep copy of tasks
346
+ new_tasks = Marshal.load( Marshal.dump(tasks) )
347
+
348
+ new_tasks.each { |task|
349
+ # For protocol independent tasks, generate a copy of their rules for each protocol
350
+ # This is needed because this task manager uses custom chains for each protocol
351
+ task.rules = task.rules.map { |rule|
352
+ if rule.protocol.nil?
353
+ rule.class.protocols.values.map { |prot|
354
+ new_rule = rule.dup
355
+ new_rule.protocol = prot
356
+ new_rule
357
+ }
358
+ else
359
+ rule
360
+ end
361
+ }.flatten
362
+
363
+ task.rules.each { |rule|
364
+ # Direct iptables rules to their vnic's custom chains
365
+ if rule.is_a?(IptablesRule) && self.enable_iptables
366
+ case rule.table
367
+ when :nat
368
+ case rule.chain
369
+ when :prerouting.to_s.upcase then
370
+ #unless rule.rule.include? "-j DNAT"
371
+ #rule.chain = "#{vnic[:uuid]}_dnat_exceptions"
372
+ #end
373
+ #p rule.chain
374
+ #rule.chain = "#{bound[rule.bound]}_#{vnic[:uuid]}_#{nat_chains[rule.chain]}"
375
+ #p rule.chain
376
+ when :postrouting.to_s.upcase then
377
+ # Very hackish but should work for now
378
+ if rule.rule.include? "-j SNAT"
379
+ rule.chain = "#{vnic[:uuid]}_snat"
380
+ else
381
+ rule.chain = "#{vnic[:uuid]}_snat_exceptions"
382
+ end
383
+ #rule.chain = "#{bound[rule.bound]}_#{vnic[:uuid]}_#{nat_chains[rule.chain]}"
384
+ end
385
+ when :filter
386
+ case rule.chain
387
+ when :forward.to_s.upcase then
388
+ rule.chain = "#{bound[rule.bound]}_#{vnic[:uuid]}_#{rule.protocol}"
389
+ end
390
+ end
391
+ # Direct ebtables rules to their vnic's custom chains
392
+ elsif rule.is_a?(EbtablesRule) && self.enable_ebtables
393
+ case rule.table
394
+ when :filter then
395
+ case rule.chain
396
+ when :input.to_s.upcase then
397
+ rule.chain = "s_#{vnic[:uuid]}_d_hst_#{rule.protocol}"
398
+ when :output.to_s.upcase then
399
+ rule.chain = "d_#{vnic[:uuid]}_s_hst_#{rule.protocol}"
400
+ when :forward.to_s.upcase then
401
+ rule.chain = "#{bound[rule.bound]}_#{vnic[:uuid]}_#{rule.protocol}"
402
+ end
403
+ end
404
+ end
405
+ }
406
+ }
407
+
408
+ new_tasks
409
+ end
410
+
411
+ # Removes _tasks_ for this specific vnic if they are applied
412
+ # If no _tasks_ argument is provided, all tasks for this vnic will be removed
413
+ def remove_vnic_tasks(vnic,tasks = nil)
414
+ remove_tasks(tailor_vnic_tasks(vnic,tasks))
415
+ end
416
+
417
+ def remove_vnic_chains(vnic)
418
+ remove_iptables_chains(vnic) if self.enable_iptables
419
+ remove_ebtables_chains(vnic) if self.enable_ebtables
420
+ end
421
+
422
+ def apply_task(task)
423
+ task.rules.each { |rule|
424
+ cmds = []
425
+ if rule.is_a?(EbtablesRule) && self.enable_ebtables
426
+ cmds << get_rule_command(rule,:apply)
427
+ elsif rule.is_a?(IptablesRule) && self.enable_iptables
428
+ cmds << get_rule_command(rule,:apply)
429
+ end
430
+ cmds.flatten!
431
+ cmds.compact!
432
+
433
+ puts cmds.join("\n") if self.verbose_commands
434
+
435
+ system(cmds.join("\n"))
436
+ }
437
+ end
438
+
439
+ def remove_task(task)
440
+ task.rules.each { |rule|
441
+ cmds = []
442
+ if rule.is_a?(EbtablesRule) && self.enable_ebtables
443
+ cmds << get_rule_command(rule,:remove)
444
+ elsif rule.is_a?(IptablesRule) && self.enable_iptables
445
+ cmds << get_rule_command(rule,:remove)
446
+ end
447
+ cmds.flatten!
448
+ cmds.compact!
449
+
450
+ puts cmds.join("\n") if self.verbose_commands
451
+
452
+ system(cmds.join("\n"))
453
+ }
454
+ end
455
+ end
456
+
457
+ end
458
+ end
459
+ end