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
@@ -4,54 +4,186 @@ module Dcmgr::Models
|
|
4
4
|
class InstanceSpec < AccountResource
|
5
5
|
taggable 'is'
|
6
6
|
|
7
|
-
inheritable_schema do
|
8
|
-
String :name, :null=>false
|
9
|
-
String :hypervisor, :null=>false
|
10
|
-
String :arch, :null=>false
|
11
|
-
|
12
|
-
Fixnum :cpu_cores, :null=>false, :unsigned=>true
|
13
|
-
Fixnum :memory_size, :null=>false, :unsigned=>true
|
14
|
-
Float :quota_weight, :null=>false, :default=>1.0
|
15
|
-
Text :config, :null=>false, :default=>''
|
16
|
-
Text :storage, :null=>false, :default=>''
|
17
|
-
|
18
|
-
index [:account_id, :name], {:unique=>true}
|
19
|
-
end
|
20
|
-
with_timestamps
|
21
|
-
|
22
7
|
# serialization plugin must be defined at the bottom of all class
|
23
8
|
# method calls.
|
24
|
-
# Possible column data:
|
25
|
-
# hypervisor=kvm:
|
26
|
-
# {:block_driver=>'virtio', :nic_driver=>'virtio'}
|
27
9
|
plugin :serialization
|
28
10
|
serialize_attributes :yaml, :config
|
29
|
-
#
|
30
|
-
# {
|
31
|
-
# '
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
11
|
+
# initial attached virtual interface definition:
|
12
|
+
# {
|
13
|
+
# 'vif1' => {
|
14
|
+
# :index => 0, # (>=0) required and unique
|
15
|
+
# :bandwidth=>512, # (kbps) required
|
16
|
+
# },
|
17
|
+
# 'vif2' => {
|
18
|
+
# :index => 10, # (>=0) required and unique
|
19
|
+
# :bandwidth=>50000, # (kbps) required
|
20
|
+
# },
|
21
|
+
# }
|
22
|
+
serialize_attributes :yaml, :vifs
|
23
|
+
# initial attached disk definition:
|
24
|
+
# {
|
25
|
+
# # blank disk image file on host OS for swap device.
|
26
|
+
# 'swap1' => {
|
27
|
+
# :index => 0, # (>=0) required and unique
|
28
|
+
# :type => :local, # required
|
29
|
+
# :size => 100, # (MB) required
|
30
|
+
# },
|
31
|
+
# # attach volume disk from snapshot.
|
32
|
+
# 'volume1' => {
|
33
|
+
# :index => 1, # (>=0) required and unique
|
34
|
+
# :type => :volume, # required
|
35
|
+
# :snapshot_id => 'snap-xxxxxx', # required
|
36
|
+
# },
|
37
|
+
# # attach blank volume disk.
|
38
|
+
# 'volume2' => {
|
39
|
+
# :index => 5, # (>=0) required and unique
|
40
|
+
# :type => :volume, # required
|
41
|
+
# :size => 100, # (MB) required
|
42
|
+
# },
|
43
|
+
# }
|
44
|
+
serialize_attributes :yaml, :drives
|
45
|
+
|
46
|
+
def before_validation
|
47
|
+
default_config = {}
|
40
48
|
|
41
49
|
self.config = default_config.merge(self.config || {})
|
50
|
+
|
51
|
+
# Set empty hash for
|
52
|
+
self.vifs ||= {}
|
53
|
+
self.drives ||= {}
|
54
|
+
super
|
55
|
+
end
|
56
|
+
|
57
|
+
def validate
|
58
|
+
super
|
59
|
+
|
60
|
+
# uniquness check for :index
|
61
|
+
unless self.vifs.values.map {|i| i[:index] }.uniq.size == self.vifs.size
|
62
|
+
errors.add(:vifs, "duplicate index value.")
|
63
|
+
end
|
64
|
+
unless self.drives.values.map {|i| i[:index] }.uniq.size == self.drives.size
|
65
|
+
errors.add(:drives, "duplicate index value.")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def before_destroy
|
70
|
+
if !Instance.alives.filter(:instance_spec_id=>self.id).empty?
|
71
|
+
raise "There are one or more running instances refers this record."
|
72
|
+
end
|
73
|
+
|
42
74
|
super
|
43
75
|
end
|
44
76
|
|
45
77
|
def to_hash
|
46
78
|
super.merge({:config=>self.config, # yaml -> Hash
|
47
|
-
:
|
79
|
+
:vifs => self.vifs, # yaml -> Hash
|
80
|
+
:drives => self.drives, # yaml -> Hash
|
48
81
|
})
|
49
82
|
end
|
50
83
|
|
51
84
|
def to_api_document
|
52
|
-
doc =
|
85
|
+
doc = super()
|
53
86
|
doc.delete(:config)
|
54
87
|
doc
|
55
88
|
end
|
89
|
+
|
90
|
+
# Modify methods for vifs,drives hash parameters.
|
91
|
+
def add_vif(name, index, bandwidth)
|
92
|
+
raise "Duplicate interface name: #{name}" if self.vifs.has_key?(name)
|
93
|
+
self.vifs[name]={
|
94
|
+
:index => index,
|
95
|
+
:bandwidth => bandwidth,
|
96
|
+
}
|
97
|
+
self.changed_columns << :vifs
|
98
|
+
self
|
99
|
+
end
|
100
|
+
|
101
|
+
def update_vif_index(name, new_index)
|
102
|
+
raise "Unknown interface name: #{name}" if !self.vifs.has_key?(name)
|
103
|
+
self.vifs[name][:index]=new_index
|
104
|
+
self.changed_columns << :vifs
|
105
|
+
self
|
106
|
+
end
|
107
|
+
|
108
|
+
def update_vif_bandwidth(name, bandwidth)
|
109
|
+
raise "Unknown interface name: #{name}" if !self.vifs.has_key?(name)
|
110
|
+
self.vifs[name][:bandwidth]=bandwidth
|
111
|
+
self.changed_columns << :vifs
|
112
|
+
self
|
113
|
+
end
|
114
|
+
|
115
|
+
def remove_vif(name)
|
116
|
+
self.vifs.delete(name)
|
117
|
+
self.changed_columns << :vifs
|
118
|
+
self
|
119
|
+
end
|
120
|
+
|
121
|
+
def add_local_drive(name, index, size)
|
122
|
+
raise "Duplicate drive name: #{name}" if self.drives.has_key?(name)
|
123
|
+
self.drives[name] = {
|
124
|
+
:index => index,
|
125
|
+
:type => :local,
|
126
|
+
:size => size,
|
127
|
+
}
|
128
|
+
self.changed_columns << :drives
|
129
|
+
self
|
130
|
+
end
|
131
|
+
|
132
|
+
def add_volume_drive(name, index, size)
|
133
|
+
raise "Duplicate drive name: #{name}" if self.drives.has_key?(name)
|
134
|
+
self.drives[name] = {
|
135
|
+
:index => index,
|
136
|
+
:type => :volume,
|
137
|
+
:size => size,
|
138
|
+
}
|
139
|
+
self.changed_columns << :drives
|
140
|
+
self
|
141
|
+
end
|
142
|
+
|
143
|
+
def add_volume_drive_from_snapshot(name, index, snapshot_id)
|
144
|
+
raise "Duplicate drive name: #{name}" if self.drives.has_key?(name)
|
145
|
+
self.drives[name] = {
|
146
|
+
:index => index,
|
147
|
+
:type => :volume,
|
148
|
+
:snapshot_id => snapshot_id,
|
149
|
+
}
|
150
|
+
self.changed_columns << :drives
|
151
|
+
self
|
152
|
+
end
|
153
|
+
|
154
|
+
def update_drive_index(name, new_index)
|
155
|
+
raise "Unknown drive name: #{name}" if !self.drives.has_key?(name)
|
156
|
+
drive = self.drives[name]
|
157
|
+
drive[:index] = new_index
|
158
|
+
self.changed_columns << :drives
|
159
|
+
self
|
160
|
+
end
|
161
|
+
|
162
|
+
def update_drive_snapshot_id(name, snapshot_id)
|
163
|
+
raise "Unknown drive name: #{name}" if !self.drives.has_key?(name)
|
164
|
+
drive = self.drives[name]
|
165
|
+
raise "Snapshot ID can only be set to volume drive" if !(drive[:type] == :volume)
|
166
|
+
drive.delete(:size)
|
167
|
+
# TODO: syntax check for snapshot_id
|
168
|
+
drive[:snapshot_id] = snapshot_id
|
169
|
+
self.changed_columns << :drives
|
170
|
+
self
|
171
|
+
end
|
172
|
+
|
173
|
+
def update_drive_size(name, size)
|
174
|
+
raise "Unknown drive name: #{name}" if !self.drives.has_key?(name)
|
175
|
+
drive = self.drives[name]
|
176
|
+
drive.delete(:snapshot_id) if drive[:type] == :volume
|
177
|
+
drive[:size] = size
|
178
|
+
self.changed_columns << :drives
|
179
|
+
self
|
180
|
+
end
|
181
|
+
|
182
|
+
def remove_drive(name)
|
183
|
+
self.drives.delete(name)
|
184
|
+
self.changed_columns << :drives
|
185
|
+
self
|
186
|
+
end
|
187
|
+
|
56
188
|
end
|
57
189
|
end
|
@@ -15,18 +15,6 @@ module Dcmgr::Models
|
|
15
15
|
TYPE_MANUAL=>'manual'
|
16
16
|
}
|
17
17
|
|
18
|
-
inheritable_schema do
|
19
|
-
Fixnum :instance_nic_id
|
20
|
-
Fixnum :network_id, :null=>false
|
21
|
-
String :ipv4, :size=>50
|
22
|
-
Fixnum :alloc_type, :null=>false, :default=>TYPE_AUTO
|
23
|
-
Text :description
|
24
|
-
|
25
|
-
index [:network_id, :ipv4], {:unique=>true}
|
26
|
-
index [:instance_nic_id, :network_id]
|
27
|
-
end
|
28
|
-
with_timestamps
|
29
|
-
|
30
18
|
many_to_one :instance_nic
|
31
19
|
many_to_one :network
|
32
20
|
|
@@ -35,7 +23,7 @@ module Dcmgr::Models
|
|
35
23
|
begin
|
36
24
|
addr = IPAddress::IPv4.new("#{self.ipv4}")
|
37
25
|
# validate if ipv4 is in the range of network_id.
|
38
|
-
unless network.
|
26
|
+
unless network.include?(addr)
|
39
27
|
errors.add(:ipv4, "IP address #{addr} is out of range: #{network.canonical_uuid})")
|
40
28
|
end
|
41
29
|
rescue => e
|
@@ -54,8 +42,8 @@ module Dcmgr::Models
|
|
54
42
|
# if the IpLease has a pair NAT address it will return
|
55
43
|
# outside IpLease.
|
56
44
|
def nat_outside_lease
|
57
|
-
if self.
|
58
|
-
self.class.find(:instance_nic_id=>self.instance_nic.id, :network_id=>self.
|
45
|
+
if self.instance_nic.nat_network_id
|
46
|
+
self.class.find(:instance_nic_id=>self.instance_nic.id, :network_id=>self.instance_nic.nat_network_id)
|
59
47
|
else
|
60
48
|
nil
|
61
49
|
end
|
@@ -65,7 +53,7 @@ module Dcmgr::Models
|
|
65
53
|
# @return [IpLease,nil] IpLease (outside) will return inside
|
66
54
|
# IpLease.
|
67
55
|
def nat_inside_lease
|
68
|
-
if self.
|
56
|
+
if self.instance_nic.nat_network_id.nil?
|
69
57
|
self.class.find(:instance_nic_id=>self.instance_nic.id, :network_id=>nil)
|
70
58
|
else
|
71
59
|
nil
|
@@ -75,14 +63,15 @@ module Dcmgr::Models
|
|
75
63
|
def self.lease(instance_nic, network)
|
76
64
|
raise TypeError unless instance_nic.is_a?(InstanceNic)
|
77
65
|
raise TypeError unless network.is_a?(Network)
|
78
|
-
|
79
|
-
|
80
|
-
reserved
|
66
|
+
|
67
|
+
reserved = []
|
68
|
+
reserved << network.ipv4_gw_ipaddress if network.ipv4_gw
|
69
|
+
reserved << IPAddress::IPv4.new(network.dhcp_server) if network.dhcp_server
|
81
70
|
reserved = reserved.map {|i| i.to_u32 }
|
82
71
|
# use SELECT FOR UPDATE to lock rows within same network.
|
83
|
-
addrs =
|
72
|
+
addrs = network.ipv4_u32_dynamic_range_array -
|
84
73
|
reserved - network.ip_lease_dataset.for_update.all.map {|i| IPAddress::IPv4.new(i.ipv4).to_u32 }
|
85
|
-
raise "
|
74
|
+
raise "Run out of dynamic IP addresses from the network segment: #{network.ipv4_network.to_s}/#{network.prefix}" if addrs.empty?
|
86
75
|
|
87
76
|
leaseaddr = IPAddress::IPv4.parse_u32(addrs[rand(addrs.size).to_i])
|
88
77
|
create(:ipv4=>leaseaddr.to_s, :network_id=>network.id, :instance_nic_id=>instance_nic.id)
|
@@ -4,19 +4,38 @@ module Dcmgr::Models
|
|
4
4
|
# MAC address lease information
|
5
5
|
class MacLease < BaseNew
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
# register MAC address.
|
8
|
+
# @params [String] 6 or 12 length of HEX value in string.
|
9
|
+
def self.lease(mac_addr)
|
10
|
+
case mac_addr.size
|
11
|
+
when 12
|
12
|
+
when 6
|
13
|
+
# Assign bottom 6 device ID dynamically.
|
14
|
+
vendor_id = mac_addr.dup
|
15
|
+
begin
|
16
|
+
mac_addr = vendor_id + ("%02x%02x%02x" % [rand(0xff),rand(0xff),rand(0xff)])
|
17
|
+
end while self.find(:mac_addr=> mac_addr)
|
18
|
+
else
|
19
|
+
raise ArgumentError, "Invalid MAC address string: 6 or 12 length of HEX value is needed."
|
20
|
+
end
|
21
|
+
create(:mac_addr=>mac_addr)
|
11
22
|
end
|
12
|
-
with_timestamps
|
13
23
|
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
24
|
+
# show default vendor ID for the hypervisor.
|
25
|
+
# The virtual interface can be applied any valid MAC address. But using
|
26
|
+
# the well known vendor IDs for hypervisor have some benefits. For
|
27
|
+
# example, 70-persistent-net.rules issue can be avoided with newer
|
28
|
+
# udev release.
|
29
|
+
def self.default_vendor_id(hypervisor)
|
30
|
+
case hypervisor.to_sym
|
31
|
+
when :kvm
|
32
|
+
'525400'
|
33
|
+
when :lxc
|
34
|
+
# LXC is not known with the specific vendor ID. This may be wrong.
|
35
|
+
'525400'
|
36
|
+
else
|
37
|
+
raise "Unknown hypervisor name: #{hypervisor}"
|
38
|
+
end
|
20
39
|
end
|
21
40
|
end
|
22
41
|
end
|
data/lib/dcmgr/models/network.rb
CHANGED
@@ -7,22 +7,6 @@ module Dcmgr::Models
|
|
7
7
|
class Network < AccountResource
|
8
8
|
taggable 'nw'
|
9
9
|
|
10
|
-
inheritable_schema do
|
11
|
-
String :ipv4_gw, :null=>false
|
12
|
-
Fixnum :prefix, :null=>false, :default=>24, :unsigned=>true
|
13
|
-
String :domain_name
|
14
|
-
String :dns_server
|
15
|
-
String :dhcp_server
|
16
|
-
String :metadata_server
|
17
|
-
Fixnum :metadata_server_port
|
18
|
-
Fixnum :bandwidth #in Mbit/s
|
19
|
-
Fixnum :vlan_lease_id, :null=>false, :default=>0
|
20
|
-
Fixnum :nat_network_id
|
21
|
-
Text :description
|
22
|
-
index :nat_network_id
|
23
|
-
end
|
24
|
-
with_timestamps
|
25
|
-
|
26
10
|
module IpLeaseMethods
|
27
11
|
def add_reserved(ipaddr, description=nil)
|
28
12
|
model.create(:network_id=>model_object.id,
|
@@ -37,19 +21,51 @@ module Dcmgr::Models
|
|
37
21
|
many_to_one :nat_network, :key => :nat_network_id, :class => self
|
38
22
|
one_to_many :inside_networks, :key => :nat_network_id, :class => self
|
39
23
|
|
24
|
+
one_to_many :dhcp_range
|
25
|
+
many_to_one :physical_network
|
26
|
+
|
27
|
+
def before_validation
|
28
|
+
self.link_interface ||= "br-#{self[:uuid]}"
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
40
32
|
def validate
|
41
33
|
super
|
42
34
|
|
35
|
+
unless (1..31).include?(self.prefix.to_i)
|
36
|
+
errors.add(:prefix, "prefix must be 1-31: #{self.prefix}")
|
37
|
+
end
|
38
|
+
|
39
|
+
network_addr = begin
|
40
|
+
IPAddress::IPv4.new("#{self.ipv4_network}/#{self.prefix}").network
|
41
|
+
rescue => e
|
42
|
+
errors.add(:ipv4_network, "Invalid IP address syntax: #{self.ipv4_network}")
|
43
|
+
end
|
43
44
|
# validate ipv4 syntax
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
if self.ipv4_gw
|
46
|
+
begin
|
47
|
+
if !network_addr.include?(IPAddress::IPv4.new("#{self.ipv4_gw}"))
|
48
|
+
errors.add(:ipv4_gw, "Out of network address range: #{network_addr.to_s}")
|
49
|
+
end
|
50
|
+
rescue => e
|
51
|
+
errors.add(:ipv4_gw, "Invalid IP address syntax: #{self.ipv4_gw}")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
if self.dhcp_server
|
56
|
+
begin
|
57
|
+
if !network_addr.include?(IPAddress::IPv4.new("#{self.dhcp_server}"))
|
58
|
+
errors.add(:dhcp_server, "Out of network address range: #{network_addr.to_s}")
|
59
|
+
end
|
60
|
+
rescue => e
|
61
|
+
errors.add(:dhcp_server, "Invalid IP address syntax: #{self.dhcp_server}")
|
62
|
+
end
|
48
63
|
end
|
49
64
|
|
50
|
-
|
51
|
-
errors.add(:
|
65
|
+
if self.link_interface.size > 16
|
66
|
+
errors.add(:link_interface, "Can not be the character lenth more than 16(=IF_NAMESIZ) ASCII characters.")
|
52
67
|
end
|
68
|
+
|
53
69
|
end
|
54
70
|
|
55
71
|
def to_hash
|
@@ -60,6 +76,11 @@ module Dcmgr::Models
|
|
60
76
|
:description=>description.to_s,
|
61
77
|
:vlan_id => vlan_lease.nil? ? 0 : vlan_lease.tag_id,
|
62
78
|
})
|
79
|
+
if self.physical_network
|
80
|
+
h[:physical_network] = self.physical_network.to_hash
|
81
|
+
end
|
82
|
+
|
83
|
+
h
|
63
84
|
end
|
64
85
|
|
65
86
|
def before_destroy
|
@@ -78,14 +99,19 @@ module Dcmgr::Models
|
|
78
99
|
end
|
79
100
|
|
80
101
|
def to_api_document
|
81
|
-
to_hash
|
102
|
+
to_hash.merge(:id=>self.canonical_uuid)
|
82
103
|
end
|
83
104
|
|
84
105
|
def nat_network
|
85
106
|
Network.find(:id => self.nat_network_id)
|
86
107
|
end
|
87
108
|
|
88
|
-
def
|
109
|
+
def ipv4_ipaddress
|
110
|
+
IPAddress::IPv4.new("#{self.ipv4_network}/#{self.prefix}").network
|
111
|
+
end
|
112
|
+
|
113
|
+
def ipv4_gw_ipaddress
|
114
|
+
return nil if self.ipv4_gw.nil?
|
89
115
|
IPAddress::IPv4.new("#{self.ipv4_gw}/#{self.prefix}")
|
90
116
|
end
|
91
117
|
|
@@ -93,16 +119,111 @@ module Dcmgr::Models
|
|
93
119
|
# @param [String] ipaddr IP address
|
94
120
|
def include?(ipaddr)
|
95
121
|
ipaddr = ipaddr.is_a?(IPAddress::IPv4) ? ipaddr : IPAddress::IPv4.new(ipaddr)
|
96
|
-
self.
|
122
|
+
self.ipv4_ipaddress.network.include?(ipaddr)
|
97
123
|
end
|
98
124
|
|
99
125
|
# register reserved IP address in this network
|
100
126
|
def add_reserved(ipaddr)
|
101
|
-
|
127
|
+
raise "Out of subnet range: #{ipaddr} to #{self.ipv4_ipaddress}/#{self.prefix}" if !self.include?(ipaddr)
|
128
|
+
add_ip_lease(:ipv4=>ipaddr.to_s, :type=>IpLease::TYPE_RESERVED)
|
102
129
|
end
|
103
130
|
|
104
131
|
def available_ip_nums
|
105
|
-
self.
|
132
|
+
self.ipv4_ipaddress.hosts.size - self.ip_lease_dataset.count
|
133
|
+
end
|
134
|
+
|
135
|
+
def ipv4_u32_dynamic_range_array
|
136
|
+
ary=[]
|
137
|
+
dhcp_range_dataset.each { |r|
|
138
|
+
ary += (r.range_begin.to_u32 .. r.range_end.to_u32).to_a
|
139
|
+
}
|
140
|
+
ary
|
141
|
+
end
|
142
|
+
|
143
|
+
def add_ipv4_dynamic_range(range_begin, range_end)
|
144
|
+
test_inclusion(*validate_range_args(range_begin, range_end)) { |range, op|
|
145
|
+
case op
|
146
|
+
when :coverbegin
|
147
|
+
range.range_end = range_begin
|
148
|
+
when :coverend
|
149
|
+
range.range_begin = range_end
|
150
|
+
when :inccur
|
151
|
+
range.destroy
|
152
|
+
end
|
153
|
+
range.save_changes
|
154
|
+
}
|
155
|
+
|
156
|
+
self.add_dhcp_range(:range_begin=>range_begin.to_s, :range_end=>range_end.to_s)
|
157
|
+
|
158
|
+
self
|
159
|
+
end
|
160
|
+
|
161
|
+
def del_ipv4_dynamic_range(range_begin, range_end)
|
162
|
+
test_inclusion(*validate_range_args(range_begin, range_end)) { |range, op|
|
163
|
+
case op
|
164
|
+
when :coverbegin
|
165
|
+
range.range_end = range_begin
|
166
|
+
when :coverend
|
167
|
+
range.range_begin = range_end
|
168
|
+
when :inccur
|
169
|
+
range.destroy
|
170
|
+
when :incnew
|
171
|
+
t = range.range_end
|
172
|
+
range.range_end = range_begin
|
173
|
+
self.add_dhcp_range(:range_begin=>range_end, :range_end=>t)
|
174
|
+
end
|
175
|
+
range.save_changes
|
176
|
+
}
|
177
|
+
|
178
|
+
self
|
179
|
+
end
|
180
|
+
|
181
|
+
private
|
182
|
+
def validate_range_args(range_begin, range_end)
|
183
|
+
if range_begin.is_a?(IPAddress::IPv4)
|
184
|
+
raise "Different prefix length: range_begin" if range_begin.prefix != self.prefix
|
185
|
+
else
|
186
|
+
range_begin = IPAddress::IPv4.new("#{range_begin}/#{self.prefix}")
|
187
|
+
end
|
188
|
+
if range_end.is_a?(IPAddress::IPv4)
|
189
|
+
raise "Different prefix length: range_end" if range_end.prefix != self.prefix
|
190
|
+
else
|
191
|
+
range_end = IPAddress::IPv4.new("#{range_end}/#{self.prefix}")
|
192
|
+
end
|
193
|
+
if !(self.ipv4_ipaddress.include?(range_begin) && self.ipv4_ipaddress.include?(range_end))
|
194
|
+
raise "Given address range is out of the subnet: #{self.ipv4_ipaddress} #{range_begin}-#{range_end}"
|
195
|
+
end
|
196
|
+
if range_begin > range_end
|
197
|
+
t = range_begin
|
198
|
+
range_begin = range_end
|
199
|
+
range_end = t
|
200
|
+
end
|
201
|
+
[range_begin, range_end]
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
def test_inclusion(range_begin, range_end, &blk)
|
206
|
+
dhcp_range_dataset.each { |r|
|
207
|
+
op = :outrange
|
208
|
+
if r.range_begin < range_begin && r.range_end > range_begin
|
209
|
+
# range_begin is in the range.
|
210
|
+
if r.range_end < range_end
|
211
|
+
op = :coverbegin
|
212
|
+
else
|
213
|
+
# new range is included in current range.
|
214
|
+
op = :incnew
|
215
|
+
end
|
216
|
+
elsif r.range_begin < range_end && r.range_end > range_end
|
217
|
+
# range_end is in the range.
|
218
|
+
if r.range_begin > range_begin
|
219
|
+
op = :coverend
|
220
|
+
end
|
221
|
+
elsif r.range_begin >= range_begin && r.range_end <= range_end
|
222
|
+
# current range is included in new range.
|
223
|
+
op = :inccur
|
224
|
+
end
|
225
|
+
blk.call(r, op)
|
226
|
+
}
|
106
227
|
end
|
107
228
|
end
|
108
229
|
end
|