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.
- data/Rakefile +19 -31
- data/bin/collector +6 -1
- data/config/db/migrations/0001_v1110_origin.rb +446 -0
- data/config/dcmgr.conf.example +51 -0
- data/lib/dcmgr.rb +99 -22
- data/lib/dcmgr/cli/base.rb +34 -1
- data/lib/dcmgr/cli/host.rb +24 -20
- data/lib/dcmgr/cli/image.rb +38 -19
- data/lib/dcmgr/cli/keypair.rb +16 -12
- data/lib/dcmgr/cli/network.rb +189 -81
- data/lib/dcmgr/cli/quota.rb +2 -2
- data/lib/dcmgr/cli/security_group.rb +106 -0
- data/lib/dcmgr/cli/spec.rb +144 -39
- data/lib/dcmgr/cli/storage.rb +16 -15
- data/lib/dcmgr/cli/tag.rb +20 -14
- data/lib/dcmgr/cli/vlan.rb +5 -5
- data/lib/dcmgr/drivers/backing_store.rb +32 -0
- data/lib/dcmgr/drivers/comstar.rb +81 -0
- data/lib/dcmgr/drivers/iijgio_storage.rb +9 -19
- data/lib/dcmgr/drivers/iscsi_target.rb +41 -0
- data/lib/dcmgr/drivers/kvm.rb +161 -28
- data/lib/dcmgr/drivers/linux_iscsi.rb +60 -0
- data/lib/dcmgr/drivers/local_storage.rb +24 -0
- data/lib/dcmgr/drivers/lxc.rb +167 -125
- data/lib/dcmgr/drivers/raw.rb +74 -0
- data/lib/dcmgr/drivers/s3_storage.rb +7 -19
- data/lib/dcmgr/drivers/snapshot_storage.rb +18 -28
- data/lib/dcmgr/drivers/storage_initiator.rb +28 -0
- data/lib/dcmgr/drivers/sun_iscsi.rb +32 -0
- data/lib/dcmgr/drivers/zfs.rb +77 -0
- data/lib/dcmgr/endpoints/core_api.rb +315 -263
- data/lib/dcmgr/endpoints/errors.rb +21 -10
- data/lib/dcmgr/endpoints/metadata.rb +360 -23
- data/lib/dcmgr/helpers/cli_helper.rb +6 -3
- data/lib/dcmgr/helpers/ec2_metadata_helper.rb +9 -0
- data/lib/dcmgr/helpers/nic_helper.rb +11 -0
- data/lib/dcmgr/helpers/snapshot_storage_helper.rb +34 -0
- data/lib/dcmgr/models/account.rb +0 -6
- data/lib/dcmgr/models/account_resource.rb +0 -4
- data/lib/dcmgr/models/base_new.rb +14 -2
- data/lib/dcmgr/models/dhcp_range.rb +38 -0
- data/lib/dcmgr/models/frontend_system.rb +0 -6
- data/lib/dcmgr/models/history.rb +0 -11
- data/lib/dcmgr/models/host_node.rb +131 -0
- data/lib/dcmgr/models/hostname_lease.rb +0 -8
- data/lib/dcmgr/models/image.rb +31 -18
- data/lib/dcmgr/models/instance.rb +137 -143
- data/lib/dcmgr/models/instance_nic.rb +52 -29
- data/lib/dcmgr/models/instance_security_group.rb +9 -0
- data/lib/dcmgr/models/instance_spec.rb +163 -31
- data/lib/dcmgr/models/ip_lease.rb +10 -21
- data/lib/dcmgr/models/mac_lease.rb +30 -11
- data/lib/dcmgr/models/network.rb +148 -27
- data/lib/dcmgr/models/physical_network.rb +18 -0
- data/lib/dcmgr/models/quota.rb +0 -10
- data/lib/dcmgr/models/request_log.rb +3 -18
- data/lib/dcmgr/models/security_group.rb +66 -0
- data/lib/dcmgr/models/security_group_rule.rb +145 -0
- data/lib/dcmgr/models/ssh_key_pair.rb +16 -19
- data/lib/dcmgr/models/{storage_pool.rb → storage_node.rb} +35 -25
- data/lib/dcmgr/models/tag.rb +0 -14
- data/lib/dcmgr/models/tag_mapping.rb +1 -7
- data/lib/dcmgr/models/vlan_lease.rb +2 -8
- data/lib/dcmgr/models/volume.rb +49 -37
- data/lib/dcmgr/models/volume_snapshot.rb +15 -17
- data/lib/dcmgr/node_modules/hva_collector.rb +69 -28
- data/lib/dcmgr/node_modules/instance_ha.rb +23 -12
- data/lib/dcmgr/node_modules/instance_monitor.rb +16 -2
- data/lib/dcmgr/node_modules/openflow_controller.rb +784 -0
- data/lib/dcmgr/node_modules/scheduler.rb +189 -0
- data/lib/dcmgr/node_modules/service_netfilter.rb +452 -227
- data/lib/dcmgr/node_modules/service_openflow.rb +731 -0
- data/lib/dcmgr/node_modules/sta_collector.rb +20 -0
- data/lib/dcmgr/node_modules/sta_tgt_initializer.rb +35 -0
- data/lib/dcmgr/rack/request_logger.rb +11 -6
- data/lib/dcmgr/rpc/hva_handler.rb +256 -110
- data/lib/dcmgr/rpc/sta_handler.rb +244 -0
- data/lib/dcmgr/scheduler.rb +122 -8
- data/lib/dcmgr/scheduler/host_node/exclude_same.rb +24 -0
- data/lib/dcmgr/scheduler/host_node/find_first.rb +12 -0
- data/lib/dcmgr/scheduler/host_node/least_usage.rb +28 -0
- data/lib/dcmgr/scheduler/host_node/per_instance.rb +18 -0
- data/lib/dcmgr/scheduler/host_node/specify_node.rb +26 -0
- data/lib/dcmgr/scheduler/network/flat_single.rb +23 -0
- data/lib/dcmgr/scheduler/network/nat_one_to_one.rb +23 -0
- data/lib/dcmgr/scheduler/network/per_instance.rb +39 -0
- data/lib/dcmgr/scheduler/network/vif_template.rb +19 -0
- data/lib/dcmgr/scheduler/storage_node/find_first.rb +13 -0
- data/lib/dcmgr/scheduler/storage_node/least_usage.rb +23 -0
- data/lib/dcmgr/storage_service.rb +39 -40
- data/lib/dcmgr/tags.rb +3 -3
- data/lib/dcmgr/version.rb +1 -1
- data/lib/dcmgr/vnet.rb +105 -0
- data/lib/dcmgr/vnet/factories.rb +141 -0
- data/lib/dcmgr/vnet/isolators/by_securitygroup.rb +21 -0
- data/lib/dcmgr/vnet/isolators/dummy.rb +17 -0
- data/lib/dcmgr/vnet/netfilter/cache.rb +51 -0
- data/lib/dcmgr/vnet/netfilter/chain.rb +66 -0
- data/lib/dcmgr/vnet/netfilter/controller.rb +193 -0
- data/lib/dcmgr/vnet/netfilter/ebtables_rule.rb +53 -0
- data/lib/dcmgr/vnet/netfilter/iptables_rule.rb +45 -0
- data/lib/dcmgr/vnet/netfilter/task_manager.rb +459 -0
- data/lib/dcmgr/vnet/tasks/accept_all_dns.rb +19 -0
- data/lib/dcmgr/vnet/tasks/accept_arp_broadcast.rb +24 -0
- data/lib/dcmgr/vnet/tasks/accept_arp_from_friends.rb +34 -0
- data/lib/dcmgr/vnet/tasks/accept_arp_from_gateway.rb +21 -0
- data/lib/dcmgr/vnet/tasks/accept_arp_to_host.rb +30 -0
- data/lib/dcmgr/vnet/tasks/accept_ip_from_friends.rb +26 -0
- data/lib/dcmgr/vnet/tasks/accept_ip_from_gateway.rb +23 -0
- data/lib/dcmgr/vnet/tasks/accept_ip_to_anywhere.rb +18 -0
- data/lib/dcmgr/vnet/tasks/accept_related_established.rb +45 -0
- data/lib/dcmgr/vnet/tasks/accept_wakame_dhcp_only.rb +33 -0
- data/lib/dcmgr/vnet/tasks/accept_wakame_dns_only.rb +33 -0
- data/lib/dcmgr/vnet/tasks/debug_iptables.rb +21 -0
- data/lib/dcmgr/vnet/tasks/drop_arp_forwarding.rb +27 -0
- data/lib/dcmgr/vnet/tasks/drop_arp_to_host.rb +24 -0
- data/lib/dcmgr/vnet/tasks/drop_ip_from_anywhere.rb +18 -0
- data/lib/dcmgr/vnet/tasks/drop_ip_spoofing.rb +34 -0
- data/lib/dcmgr/vnet/tasks/drop_mac_spoofing.rb +33 -0
- data/lib/dcmgr/vnet/tasks/exclude_from_nat.rb +47 -0
- data/lib/dcmgr/vnet/tasks/security_group.rb +37 -0
- data/lib/dcmgr/vnet/tasks/static_nat.rb +54 -0
- data/lib/dcmgr/vnet/tasks/translate_metadata_address.rb +32 -0
- data/web/metadata/config.ru +1 -1
- metadata +174 -89
- data/lib/dcmgr/cli/group.rb +0 -101
- data/lib/dcmgr/endpoints/core_api_mock.rb +0 -865
- data/lib/dcmgr/models/host_pool.rb +0 -122
- data/lib/dcmgr/models/instance_netfilter_group.rb +0 -16
- data/lib/dcmgr/models/netfilter_group.rb +0 -89
- data/lib/dcmgr/models/netfilter_rule.rb +0 -21
- data/lib/dcmgr/scheduler/find_last.rb +0 -16
- data/lib/dcmgr/scheduler/find_random.rb +0 -16
- data/lib/dcmgr/stm/instance.rb +0 -25
- data/lib/dcmgr/stm/snapshot_context.rb +0 -33
- 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(
|
8
|
+
def initialize(driver, options = {})
|
9
|
+
@driver = driver
|
9
10
|
@account = {}
|
10
|
-
@account[:
|
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(
|
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
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
when '
|
31
|
-
@
|
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 "#{@
|
34
|
+
raise "#{@driver} is not a recognized storage driver"
|
36
35
|
end
|
37
36
|
|
38
|
-
@
|
39
|
-
@
|
40
|
-
@
|
41
|
-
@
|
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
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
:
|
58
|
-
:
|
59
|
-
:
|
60
|
-
:
|
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
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
data/lib/dcmgr/tags.rb
CHANGED
@@ -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::
|
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::
|
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::
|
51
|
+
to.is_a?(Dcmgr::Models::StorageNode)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
data/lib/dcmgr/version.rb
CHANGED
data/lib/dcmgr/vnet.rb
ADDED
@@ -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
|