wakame-vdc-dcmgr 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 (136) hide show
  1. data/Rakefile +19 -31
  2. data/bin/collector +6 -1
  3. data/config/db/migrations/0001_v1110_origin.rb +446 -0
  4. data/config/dcmgr.conf.example +51 -0
  5. data/lib/dcmgr.rb +99 -22
  6. data/lib/dcmgr/cli/base.rb +34 -1
  7. data/lib/dcmgr/cli/host.rb +24 -20
  8. data/lib/dcmgr/cli/image.rb +38 -19
  9. data/lib/dcmgr/cli/keypair.rb +16 -12
  10. data/lib/dcmgr/cli/network.rb +189 -81
  11. data/lib/dcmgr/cli/quota.rb +2 -2
  12. data/lib/dcmgr/cli/security_group.rb +106 -0
  13. data/lib/dcmgr/cli/spec.rb +144 -39
  14. data/lib/dcmgr/cli/storage.rb +16 -15
  15. data/lib/dcmgr/cli/tag.rb +20 -14
  16. data/lib/dcmgr/cli/vlan.rb +5 -5
  17. data/lib/dcmgr/drivers/backing_store.rb +32 -0
  18. data/lib/dcmgr/drivers/comstar.rb +81 -0
  19. data/lib/dcmgr/drivers/iijgio_storage.rb +9 -19
  20. data/lib/dcmgr/drivers/iscsi_target.rb +41 -0
  21. data/lib/dcmgr/drivers/kvm.rb +161 -28
  22. data/lib/dcmgr/drivers/linux_iscsi.rb +60 -0
  23. data/lib/dcmgr/drivers/local_storage.rb +24 -0
  24. data/lib/dcmgr/drivers/lxc.rb +167 -125
  25. data/lib/dcmgr/drivers/raw.rb +74 -0
  26. data/lib/dcmgr/drivers/s3_storage.rb +7 -19
  27. data/lib/dcmgr/drivers/snapshot_storage.rb +18 -28
  28. data/lib/dcmgr/drivers/storage_initiator.rb +28 -0
  29. data/lib/dcmgr/drivers/sun_iscsi.rb +32 -0
  30. data/lib/dcmgr/drivers/zfs.rb +77 -0
  31. data/lib/dcmgr/endpoints/core_api.rb +315 -263
  32. data/lib/dcmgr/endpoints/errors.rb +21 -10
  33. data/lib/dcmgr/endpoints/metadata.rb +360 -23
  34. data/lib/dcmgr/helpers/cli_helper.rb +6 -3
  35. data/lib/dcmgr/helpers/ec2_metadata_helper.rb +9 -0
  36. data/lib/dcmgr/helpers/nic_helper.rb +11 -0
  37. data/lib/dcmgr/helpers/snapshot_storage_helper.rb +34 -0
  38. data/lib/dcmgr/models/account.rb +0 -6
  39. data/lib/dcmgr/models/account_resource.rb +0 -4
  40. data/lib/dcmgr/models/base_new.rb +14 -2
  41. data/lib/dcmgr/models/dhcp_range.rb +38 -0
  42. data/lib/dcmgr/models/frontend_system.rb +0 -6
  43. data/lib/dcmgr/models/history.rb +0 -11
  44. data/lib/dcmgr/models/host_node.rb +131 -0
  45. data/lib/dcmgr/models/hostname_lease.rb +0 -8
  46. data/lib/dcmgr/models/image.rb +31 -18
  47. data/lib/dcmgr/models/instance.rb +137 -143
  48. data/lib/dcmgr/models/instance_nic.rb +52 -29
  49. data/lib/dcmgr/models/instance_security_group.rb +9 -0
  50. data/lib/dcmgr/models/instance_spec.rb +163 -31
  51. data/lib/dcmgr/models/ip_lease.rb +10 -21
  52. data/lib/dcmgr/models/mac_lease.rb +30 -11
  53. data/lib/dcmgr/models/network.rb +148 -27
  54. data/lib/dcmgr/models/physical_network.rb +18 -0
  55. data/lib/dcmgr/models/quota.rb +0 -10
  56. data/lib/dcmgr/models/request_log.rb +3 -18
  57. data/lib/dcmgr/models/security_group.rb +66 -0
  58. data/lib/dcmgr/models/security_group_rule.rb +145 -0
  59. data/lib/dcmgr/models/ssh_key_pair.rb +16 -19
  60. data/lib/dcmgr/models/{storage_pool.rb → storage_node.rb} +35 -25
  61. data/lib/dcmgr/models/tag.rb +0 -14
  62. data/lib/dcmgr/models/tag_mapping.rb +1 -7
  63. data/lib/dcmgr/models/vlan_lease.rb +2 -8
  64. data/lib/dcmgr/models/volume.rb +49 -37
  65. data/lib/dcmgr/models/volume_snapshot.rb +15 -17
  66. data/lib/dcmgr/node_modules/hva_collector.rb +69 -28
  67. data/lib/dcmgr/node_modules/instance_ha.rb +23 -12
  68. data/lib/dcmgr/node_modules/instance_monitor.rb +16 -2
  69. data/lib/dcmgr/node_modules/openflow_controller.rb +784 -0
  70. data/lib/dcmgr/node_modules/scheduler.rb +189 -0
  71. data/lib/dcmgr/node_modules/service_netfilter.rb +452 -227
  72. data/lib/dcmgr/node_modules/service_openflow.rb +731 -0
  73. data/lib/dcmgr/node_modules/sta_collector.rb +20 -0
  74. data/lib/dcmgr/node_modules/sta_tgt_initializer.rb +35 -0
  75. data/lib/dcmgr/rack/request_logger.rb +11 -6
  76. data/lib/dcmgr/rpc/hva_handler.rb +256 -110
  77. data/lib/dcmgr/rpc/sta_handler.rb +244 -0
  78. data/lib/dcmgr/scheduler.rb +122 -8
  79. data/lib/dcmgr/scheduler/host_node/exclude_same.rb +24 -0
  80. data/lib/dcmgr/scheduler/host_node/find_first.rb +12 -0
  81. data/lib/dcmgr/scheduler/host_node/least_usage.rb +28 -0
  82. data/lib/dcmgr/scheduler/host_node/per_instance.rb +18 -0
  83. data/lib/dcmgr/scheduler/host_node/specify_node.rb +26 -0
  84. data/lib/dcmgr/scheduler/network/flat_single.rb +23 -0
  85. data/lib/dcmgr/scheduler/network/nat_one_to_one.rb +23 -0
  86. data/lib/dcmgr/scheduler/network/per_instance.rb +39 -0
  87. data/lib/dcmgr/scheduler/network/vif_template.rb +19 -0
  88. data/lib/dcmgr/scheduler/storage_node/find_first.rb +13 -0
  89. data/lib/dcmgr/scheduler/storage_node/least_usage.rb +23 -0
  90. data/lib/dcmgr/storage_service.rb +39 -40
  91. data/lib/dcmgr/tags.rb +3 -3
  92. data/lib/dcmgr/version.rb +1 -1
  93. data/lib/dcmgr/vnet.rb +105 -0
  94. data/lib/dcmgr/vnet/factories.rb +141 -0
  95. data/lib/dcmgr/vnet/isolators/by_securitygroup.rb +21 -0
  96. data/lib/dcmgr/vnet/isolators/dummy.rb +17 -0
  97. data/lib/dcmgr/vnet/netfilter/cache.rb +51 -0
  98. data/lib/dcmgr/vnet/netfilter/chain.rb +66 -0
  99. data/lib/dcmgr/vnet/netfilter/controller.rb +193 -0
  100. data/lib/dcmgr/vnet/netfilter/ebtables_rule.rb +53 -0
  101. data/lib/dcmgr/vnet/netfilter/iptables_rule.rb +45 -0
  102. data/lib/dcmgr/vnet/netfilter/task_manager.rb +459 -0
  103. data/lib/dcmgr/vnet/tasks/accept_all_dns.rb +19 -0
  104. data/lib/dcmgr/vnet/tasks/accept_arp_broadcast.rb +24 -0
  105. data/lib/dcmgr/vnet/tasks/accept_arp_from_friends.rb +34 -0
  106. data/lib/dcmgr/vnet/tasks/accept_arp_from_gateway.rb +21 -0
  107. data/lib/dcmgr/vnet/tasks/accept_arp_to_host.rb +30 -0
  108. data/lib/dcmgr/vnet/tasks/accept_ip_from_friends.rb +26 -0
  109. data/lib/dcmgr/vnet/tasks/accept_ip_from_gateway.rb +23 -0
  110. data/lib/dcmgr/vnet/tasks/accept_ip_to_anywhere.rb +18 -0
  111. data/lib/dcmgr/vnet/tasks/accept_related_established.rb +45 -0
  112. data/lib/dcmgr/vnet/tasks/accept_wakame_dhcp_only.rb +33 -0
  113. data/lib/dcmgr/vnet/tasks/accept_wakame_dns_only.rb +33 -0
  114. data/lib/dcmgr/vnet/tasks/debug_iptables.rb +21 -0
  115. data/lib/dcmgr/vnet/tasks/drop_arp_forwarding.rb +27 -0
  116. data/lib/dcmgr/vnet/tasks/drop_arp_to_host.rb +24 -0
  117. data/lib/dcmgr/vnet/tasks/drop_ip_from_anywhere.rb +18 -0
  118. data/lib/dcmgr/vnet/tasks/drop_ip_spoofing.rb +34 -0
  119. data/lib/dcmgr/vnet/tasks/drop_mac_spoofing.rb +33 -0
  120. data/lib/dcmgr/vnet/tasks/exclude_from_nat.rb +47 -0
  121. data/lib/dcmgr/vnet/tasks/security_group.rb +37 -0
  122. data/lib/dcmgr/vnet/tasks/static_nat.rb +54 -0
  123. data/lib/dcmgr/vnet/tasks/translate_metadata_address.rb +32 -0
  124. data/web/metadata/config.ru +1 -1
  125. metadata +174 -89
  126. data/lib/dcmgr/cli/group.rb +0 -101
  127. data/lib/dcmgr/endpoints/core_api_mock.rb +0 -865
  128. data/lib/dcmgr/models/host_pool.rb +0 -122
  129. data/lib/dcmgr/models/instance_netfilter_group.rb +0 -16
  130. data/lib/dcmgr/models/netfilter_group.rb +0 -89
  131. data/lib/dcmgr/models/netfilter_rule.rb +0 -21
  132. data/lib/dcmgr/scheduler/find_last.rb +0 -16
  133. data/lib/dcmgr/scheduler/find_random.rb +0 -16
  134. data/lib/dcmgr/stm/instance.rb +0 -25
  135. data/lib/dcmgr/stm/snapshot_context.rb +0 -33
  136. data/lib/dcmgr/stm/volume_context.rb +0 -65
@@ -0,0 +1,26 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr
4
+ module Scheduler
5
+ module HostNode
6
+
7
+ # Find host node which has the same request_params[:host_node_id].
8
+ class SpecifyNode < HostNodeScheduler
9
+ include Dcmgr::Logger
10
+
11
+ def schedule(instance)
12
+ # TODO:
13
+ # "host_id" and "host_pool_id" will be obsolete.
14
+ # They are used in lib/dcmgr/endpoints/core_api.rb.
15
+ host_node_uuid = instance.request_params['host_id'] || instance.request_params['host_pool_id'] || instance.request_params['host_node_id']
16
+ ds = Models::HostNode.online_nodes.filter(:uuid=>Models::HostNode.trim_uuid(host_node_uuid))
17
+
18
+ host_node = ds.first
19
+
20
+ raise HostNodeSchedulingError if host_node.nil?
21
+ instance.host_node = host_node
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr
4
+ module Scheduler
5
+ module Network
6
+ # Simple network scheduler
7
+ # assign IP address from first found network to single interface.
8
+ class FlatSingle < NetworkScheduler
9
+
10
+ def schedule(instance)
11
+ # add single interface and set network
12
+ network = Models::Network.first
13
+ vif_template = instance.spec.vifs[instance.spec.vifs.keys.first] ||
14
+ {:index=>0, :bandwidth=>100000}
15
+
16
+ vnic = instance.add_nic(vif_template)
17
+ vnic.network = network
18
+ vnic.save
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr
4
+ module Scheduler
5
+ module Network
6
+ # One internal address + NAT external address to single interface.
7
+ class NatOneToOne < NetworkScheduler
8
+
9
+ def schedule(instance)
10
+ network = Models::Network[@options.network_id]
11
+ nat_network = Models::Network[@options.nat_network_id]
12
+
13
+ vif_template = instance.spec.vifs.find{ |name,v| v[:index] == 0 }.last
14
+
15
+ vnic = instance.add_nic(vif_template)
16
+ vnic.network = network
17
+ vnic.nat_network = nat_network
18
+ vnic.save
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,39 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr
4
+ module Scheduler
5
+ module Network
6
+ # Meta scheduler calls another scheduler specified by user.
7
+ class PerInstance < NetworkScheduler
8
+ include Dcmgr::Logger
9
+
10
+ def schedule(instance)
11
+ sched_opts = @options.to_hash || {}
12
+ sched_name = instance.request_params['network_scheduler']
13
+ if sched_name.nil? || sched_name == ''
14
+ if sched_opts.has_key?(:default)
15
+ sched_conf = @options.default
16
+ else
17
+ raise "Missing network_scheduler parameter from the request."
18
+ end
19
+ else
20
+ if sched_opts.has_key?(sched_name.to_sym)
21
+ sched_conf = @options.send(sched_name.to_sym)
22
+ else
23
+ raise "Unknown scheduler definition: #{sched_name} for the instance #{instance.canonical_uuid}"
24
+ end
25
+ end
26
+
27
+ sched_class = Scheduler.scheduler_class(sched_conf.scheduler, ::Dcmgr::Scheduler::Network)
28
+ sched = if sched_conf.respond_to?(:options)
29
+ sched_class.new(sched_conf.options)
30
+ else
31
+ sched_class.new
32
+ end
33
+ logger.info("Selected network scheduler: #{sched_name} #{sched_class} for the instance #{instance.canonical_uuid}")
34
+ sched.schedule(instance)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,19 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr
4
+ module Scheduler
5
+ module Network
6
+ # Setup vnics by following InstanceSpec#vifs template.
7
+ class VifTemplate < NetworkScheduler
8
+
9
+ def schedule(instance)
10
+ instance.spec.vifs.each { |name, vif|
11
+ vnic = instance.add_nic(vif)
12
+ vnic.network = Models::Network[@options[name]]
13
+ vnic.save
14
+ }
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr; module Scheduler; module StorageNode
4
+ class FindFirst < StorageNodeScheduler
5
+
6
+ protected
7
+ def schedule_node(volume)
8
+ params = volume.request_params
9
+
10
+ volume.storage_node = Models::StorageNode.first
11
+ end
12
+ end
13
+ end; end; end
@@ -0,0 +1,23 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr
4
+ module Scheduler
5
+ module StorageNode
6
+
7
+ # Find storage node which has the largest available disk space.
8
+ class LeastUsage < StorageNodeScheduler
9
+ include Dcmgr::Logger
10
+
11
+ def schedule(volume)
12
+ storage_node = Models::StorageNode.online_nodes.all.find_all { |s|
13
+ s.free_disk_space >= volume.size
14
+ }.sort_by { |s|
15
+ s.free_disk_space
16
+ }.reverse.first
17
+ raise StorageNodeSchedulingError if storage_node.nil?
18
+ volume.storage_node = storage_node
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -5,40 +5,39 @@ module Dcmgr
5
5
 
6
6
  @snapshot_repository_config = nil
7
7
 
8
- def initialize(provider, access_key, secret_key)
8
+ def initialize(driver, options = {})
9
+ @driver = driver
9
10
  @account = {}
10
- @account[:provider] = provider.upcase
11
- @account[:access_key] = access_key
12
- @account[:secret_key] = secret_key
11
+ @account[:id] = options[:account_id]
12
+ @account[:access_key] = options[:access_key]
13
+ @account[:secret_key] = options[:secret_key]
13
14
  end
14
15
 
15
16
  def self.snapshot_repository_config
16
17
  if @snapshot_repository_config.nil?
17
- config_file = YAML.load_file(File.join(File.expand_path(DCMGR_ROOT), 'config', 'snapshot_repository.yml'))
18
+ config_file = YAML.load_file(File.join(File.expand_path('../../../', __FILE__), 'config', 'snapshot_repository.yml'))
18
19
  @snapshot_repository_config = config_file
19
20
  else
20
21
  @snapshot_repository_config
21
22
  end
22
23
  end
23
24
 
24
- def self.has_driver?(driver)
25
- %w(S3 IIJGIO).include? driver.upcase
26
- end
27
-
28
- def bucket(name)
29
- case @account[:provider]
30
- when 'S3'
31
- @driver = Dcmgr::Drivers::S3Storage.new(name)
32
- when 'IIJGIO'
33
- @driver = Dcmgr::Drivers::IIJGIOStorage.new(name)
25
+ def snapshot_storage(bucket, path)
26
+ case @driver
27
+ when 'local'
28
+ @storage = Dcmgr::Drivers::LocalStorage.new(@account[:id], bucket, path)
29
+ when 's3'
30
+ @storage = Dcmgr::Drivers::S3Storage.new(@account[:id], bucket, path)
31
+ when 'iijgio'
32
+ @storage = Dcmgr::Drivers::IIJGIOStorage.new(@account[:id], bucket, path)
34
33
  else
35
- raise "#{@account[:provider]} is not a recognized storage provider"
34
+ raise "#{@driver} is not a recognized storage driver"
36
35
  end
37
36
 
38
- @driver.setenv('SERVICE', @account[:provider].downcase)
39
- @driver.setenv('ACCESS_KEY_ID', @account[:access_key])
40
- @driver.setenv('SECRET_ACCESS_KEY', @account[:secret_key])
41
- @driver
37
+ @storage.setenv('SERVICE', @driver)
38
+ @storage.setenv('ACCESS_KEY_ID', @account[:access_key])
39
+ @storage.setenv('SECRET_ACCESS_KEY', @account[:secret_key])
40
+ @storage
42
41
  end
43
42
 
44
43
  def self.repository(repository_address)
@@ -47,32 +46,33 @@ module Dcmgr
47
46
  end
48
47
  tmp = repository_address.split(',')
49
48
  destination_key = tmp[0]
50
- dest = destination_key.match(/^([a-z0-9_]+)@([a-z0-9_-]+):([a-z0-9_-]+):([a-z0-9_\-\/]+)(snap-[a-z0-9]+\.zsnap)+$/)
51
- if dest.nil?
52
- raise "Invalid format: #{repository_address}"
53
- end
54
-
55
- h = {
56
- :destination => dest[1],
57
- :driver => dest[2],
58
- :bucket => dest[3],
59
- :path => dest[4],
60
- :filename => dest[5],
49
+
50
+ # ex. 'local@local:none:/home/ubuntu/work/repos/git/github.com/wakame-vdc/tmp/snap/a-shpoolxx/snap-gkosnc56.snap'
51
+ # dest = destination_key.match(/^([a-z0-9_]+)@([a-z0-9_-]+):([a-z0-9_-]+):([a-z0-9._\-\/]+)(snap-[a-z0-9]+\.snap)+$/)
52
+ results = destination_key.split(':', 3)
53
+ accounts = results[0].split('@', 2)
54
+
55
+ h = {
56
+ :destination => accounts[0],
57
+ :driver => accounts[1],
58
+ :bucket => results[1],
59
+ :path => File.dirname(results[2]),
60
+ :filename => File.basename(results[2]),
61
61
  :access_key => tmp[1],
62
62
  :secret_key => tmp[2],
63
- }
64
- end
63
+ }
64
+ end
65
65
 
66
66
  def self.repository_address(destination_key)
67
67
  format = '%s,%s,%s'
68
68
  config_data = self.snapshot_repository_config
69
69
  destination = destination_key.split('@')[0]
70
70
 
71
- if destination == 'local'
72
- config = {:access_key => '', :secret_key => ''}
73
- else
74
- config = config_data[destination]
75
- end
71
+ config = if destination == 'local'
72
+ {'access_key' => '', 'secret_key' => ''}
73
+ else
74
+ config_data[destination]
75
+ end
76
76
 
77
77
  sprintf(format, *[destination_key, config["access_key"], config["secret_key"]])
78
78
  end
@@ -90,9 +90,8 @@ module Dcmgr
90
90
  if config.nil?
91
91
  raise "Destination isn't exists"
92
92
  end
93
- store_path = "snapshots/#{account_id}/"
94
93
  end
95
- sprintf(format, *[destination, config["driver"], config["bucket"], File.join(store_path, filename)])
94
+ sprintf(format, *[destination, config["driver"], config["bucket"], File.join("#{store_path}/#{account_id}/", filename)])
96
95
  end
97
96
  end
98
97
  end
@@ -32,12 +32,12 @@ module Dcmgr::Tags
32
32
 
33
33
  class HostPool < Models::Tag
34
34
  def accept_mapping?(to)
35
- to.is_a?(Dcmgr::Models::HostPool)
35
+ to.is_a?(Dcmgr::Models::HostNode)
36
36
  end
37
37
 
38
38
  def pick(spec)
39
39
  mapped_uuids.map { |t|
40
- Dcmgr::Models::HostPool[t.uuid]
40
+ Dcmgr::Models::HostNode[t.uuid]
41
41
  }.find_all { |h|
42
42
  h.check_capacity(spec)
43
43
  }.sort_by { |h|
@@ -48,7 +48,7 @@ module Dcmgr::Tags
48
48
 
49
49
  class StoragePool < Models::Tag
50
50
  def accept_mapping?(to)
51
- to.is_a?(Dcmgr::Models::StoragePool)
51
+ to.is_a?(Dcmgr::Models::StorageNode)
52
52
  end
53
53
  end
54
54
  end
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  module Dcmgr
4
- VERSION_MAJOR="11.06"
4
+ VERSION_MAJOR="11.12"
5
5
  VERSION_MINOR=0
6
6
 
7
7
  VERSION="#{VERSION_MAJOR}.#{VERSION_MINOR}"
@@ -0,0 +1,105 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr
4
+ module VNet
5
+
6
+ # Abstract class for a Cache implementation to extend
7
+ class Cache
8
+ # Makes a call to the database and updates the Cache
9
+ def update
10
+ raise NotImplementedError
11
+ end
12
+
13
+ # Returns the cache
14
+ # if _force_update_ is set to true, the cache will be updated from the database
15
+ def get(force_update = false)
16
+ raise NotImplementedError
17
+ end
18
+
19
+ # Adds a newly started instance to the existing cache
20
+ def add_instance(inst_map)
21
+ raise NotImplementedError
22
+ end
23
+
24
+ # Removes a terminated instance from the existing cache
25
+ def remove_instance(inst_id)
26
+ raise NotImplementedError
27
+ end
28
+ end
29
+
30
+ # A controller interface to be implemented
31
+ class Controller
32
+ def apply_instance(instance)
33
+ raise NotImplementedError
34
+ end
35
+
36
+ def remove_instance(instance)
37
+ raise NotImplementedError
38
+ end
39
+
40
+ def join_security_group(instance,group)
41
+ raise NotImplementedError
42
+ end
43
+
44
+ def leave_security_group(instance,group)
45
+ raise NotImplementedError
46
+ end
47
+
48
+ def update_security_group(group)
49
+ raise NotImplementedError
50
+ end
51
+ end
52
+
53
+ class Rule
54
+
55
+ end
56
+
57
+ class Task
58
+ #Must be an array of rules
59
+ attr_accessor :rules
60
+
61
+ def initialize
62
+ @rules = []
63
+ end
64
+
65
+ end
66
+
67
+ # Abstract class for task managers to extend
68
+ # A task manager should be able to understand certain rules in a task and be able to apply those
69
+ class TaskManager
70
+
71
+ def apply_task(task)
72
+ raise NotImplementedError
73
+ end
74
+
75
+ def apply_tasks(tasks)
76
+ raise ArgumentError, "tasks must be an Array of Tasks." unless tasks.is_a?(Array)
77
+ tasks.each { |task|
78
+ next unless task.is_a?(Task)
79
+ apply_task(task)
80
+ }
81
+ end
82
+
83
+ def remove_task(task)
84
+ raise NotImplementedError
85
+ end
86
+
87
+ #TODO: Change Array to Enumerable
88
+ def remove_tasks(tasks)
89
+ raise ArgumentError, "tasks must be an Array of Tasks." unless tasks.is_a?(Array)
90
+ tasks.each { |task|
91
+ next unless task.is_a?(Task)
92
+ remove_task(task)
93
+ }
94
+ end
95
+ end
96
+
97
+ # Abstract class that determines how to isolate instances (vnics) from each other
98
+ class Isolator
99
+ def determine_friends(me,others)
100
+ raise notImplementedError
101
+ end
102
+ end
103
+
104
+ end
105
+ end
@@ -0,0 +1,141 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Dcmgr
4
+ module VNet
5
+ # This file stores the factories. It is their job to read config files etc. to decide which implementation to use.
6
+ V = Dcmgr::VNet
7
+ class ControllerFactory
8
+ def self.create_controller(node)
9
+ V::Netfilter::NetfilterController.new(node)
10
+ end
11
+ end
12
+
13
+ class IsolatorFactory
14
+ def self.create_isolator
15
+ V::Isolators::BySecurityGroup.new
16
+ #V::Isolators::DummyIsolator.new
17
+ end
18
+ end
19
+
20
+ class TaskManagerFactory
21
+ def self.create_task_manager(node)
22
+ manager = V::Netfilter::VNicProtocolTaskManager.new
23
+ manager.enable_ebtables = node.manifest.config.enable_ebtables
24
+ manager.enable_iptables = node.manifest.config.enable_iptables
25
+ manager.verbose_commands = node.manifest.config.verbose_netfilter
26
+
27
+ manager
28
+ end
29
+ end
30
+
31
+ class TaskFactory
32
+ extend Dcmgr::Helpers::NicHelper
33
+ include V::Tasks
34
+
35
+ def self.create_tasks_for_isolation(vnic,friends,node)
36
+ tasks = []
37
+ enable_logging = node.manifest.config.packet_drop_log
38
+ ipset_enabled = node.manifest.config.use_ipset
39
+ friend_ips = friends.map {|vnic_map| vnic_map[:ipv4][:address]}
40
+
41
+ tasks << AcceptARPFromFriends.new(vnic[:ipv4][:address],friend_ips,enable_logging,"A arp friend #{vnic[:uuid]}")
42
+ #tasks << AcceptIpFromFriends(friend_ips)
43
+
44
+ if is_natted? vnic
45
+ # Friends don't use NAT, friends talk to each other with their REAL ip addresses.
46
+ # It's a heart warming scene, really
47
+ if ipset_enabled
48
+ # Not implemented yet
49
+ #tasks << ExcludeFromNatIpSet.new(friend_ips,vnic[:ipv4][:address])
50
+ else
51
+ tasks << ExcludeFromNat.new(friend_ips,vnic[:ipv4][:address])
52
+ end
53
+ end
54
+
55
+ tasks
56
+ end
57
+
58
+ # Returns the tasks required for applying this security group
59
+ def self.create_tasks_for_secgroup(secgroup)
60
+ [SecurityGroup.new(secgroup)]
61
+ end
62
+
63
+ # Returns the tasks that drop all traffic
64
+ def self.create_drop_tasks_for_vnic(vnic,node)
65
+ enable_logging = node.manifest.config.packet_drop_log
66
+
67
+ #TODO: Add logging to ip drops
68
+ [DropIpFromAnywhere.new, DropArpForwarding.new(enable_logging,"D arp #{vnic[:uuid]}: ")]
69
+ end
70
+
71
+ # Creates tasks related to network address translation
72
+ def self.create_nat_tasks_for_vnic(vnic,node)
73
+ #friend_ips = friends.map {|vnic_map| vnic_map[:ipv4][:address]}
74
+ #ipset_enabled = node.manifest.config.use_ipset
75
+ tasks = []
76
+
77
+ # Nat tasks
78
+ if is_natted? vnic
79
+ # Exclude instances in the same security group form using nat
80
+ #if ipset_enabled
81
+ # Not implemented yet
82
+ #tasks << ExcludeFromNatIpSet.new(friend_ips,vnic[:ipv4][:address])
83
+ #else
84
+ #tasks << ExcludeFromNat.new(friend_ips,vnic[:ipv4][:address])
85
+ #end
86
+
87
+ tasks << StaticNatLog.new(vnic[:ipv4][:address], vnic[:ipv4][:nat_address], "SNAT #{vnic[:uuid]}", "DNAT #{vnic[:uuid]}") if node.manifest.config.packet_drop_log
88
+ tasks << StaticNat.new(vnic[:ipv4][:address], vnic[:ipv4][:nat_address], clean_mac(vnic[:mac_addr]))
89
+ end
90
+
91
+ tasks << TranslateMetadataAddress.new(vnic[:uuid],vnic[:ipv4][:network][:metadata_server],vnic[:ipv4][:network][:metadata_server_port] || 80) unless vnic[:ipv4][:network][:metadata_server].nil?
92
+
93
+ tasks
94
+ end
95
+
96
+ #Returns the netfilter tasks required for this vnic
97
+ # The _friends_ parameter is an array of vnic_maps that should not be isolated from _vnic_
98
+ def self.create_tasks_for_vnic(vnic,friends,security_groups,node)
99
+ tasks = []
100
+
101
+ host_addr = Isono::Util.default_gw_ipaddr
102
+ enable_logging = node.manifest.config.packet_drop_log
103
+ ipset_enabled = node.manifest.config.use_ipset
104
+
105
+ # Drop all traffic that isn't explicitely accepted
106
+ tasks += self.create_drop_tasks_for_vnic(vnic,node)
107
+
108
+ # General data link layer tasks
109
+ tasks << AcceptARPToHost.new(host_addr,vnic[:ipv4][:address],enable_logging,"A arp to_host #{vnic[:uuid]}: ")
110
+ tasks << AcceptARPFromGateway.new(vnic[:ipv4][:network][:ipv4_gw],enable_logging,"A arp from_gw #{vnic[:uuid]}: ") unless vnic[:ipv4][:network][:ipv4_gw].nil?
111
+ tasks << DropIpSpoofing.new(vnic[:ipv4][:address],enable_logging,"D arp sp #{vnic[:uuid]}: ")
112
+ tasks << DropMacSpoofing.new(clean_mac(vnic[:mac_addr]),enable_logging,"D ip sp #{vnic[:uuid]}: ")
113
+ tasks << AcceptArpBroadcast.new(host_addr,enable_logging,"A arp bc #{vnic[:uuid]}: ")
114
+
115
+ # General ip layer tasks
116
+ tasks << AcceptIcmpRelatedEstablished.new
117
+ tasks << AcceptTcpRelatedEstablished.new
118
+ tasks << AcceptUdpEstablished.new
119
+ tasks << AcceptAllDNS.new
120
+ tasks << AcceptWakameDHCPOnly.new(vnic[:ipv4][:network][:dhcp_server]) unless vnic[:ipv4][:network][:dhcp_server].nil?
121
+ # Accept OUTGOING traffic from instances to anywhere in the network
122
+ #tasks << AcceptIpToAnywhere.new
123
+
124
+ # VM isolation based
125
+ tasks += self.create_tasks_for_isolation(vnic,friends,node)
126
+ tasks += self.create_nat_tasks_for_vnic(vnic,node)
127
+
128
+ # Accept ip traffic from the gateway that isn't blocked by other tasks
129
+ tasks << AcceptIpFromGateway.new(vnic[:ipv4][:network][:ipv4_gw]) unless vnic[:ipv4][:network][:ipv4_gw].nil?
130
+
131
+ # Security group tasks
132
+ security_groups.each { |secgroup|
133
+ tasks += self.create_tasks_for_secgroup(secgroup)
134
+ }
135
+
136
+ tasks
137
+ end
138
+ end
139
+
140
+ end
141
+ end