wakame-vdc-agents 10.11.0 → 10.12.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +2 -2
- data/bin/hva +854 -449
- data/bin/nsa +56 -26
- data/bin/sta +11 -4
- data/config/hva.conf.example +9 -0
- data/config/nsa.conf.example +2 -2
- data/lib/dcmgr.rb +15 -2
- data/lib/dcmgr/endpoints/core_api.rb +281 -119
- data/lib/dcmgr/endpoints/errors.rb +4 -0
- data/lib/dcmgr/helpers/cli_helper.rb +79 -0
- data/lib/dcmgr/models/account.rb +19 -12
- data/lib/dcmgr/models/base_new.rb +154 -18
- data/lib/dcmgr/models/history.rb +21 -0
- data/lib/dcmgr/models/host_pool.rb +7 -7
- data/lib/dcmgr/models/hostname_lease.rb +15 -0
- data/lib/dcmgr/models/instance.rb +114 -25
- data/lib/dcmgr/models/instance_nic.rb +24 -19
- data/lib/dcmgr/models/instance_spec.rb +21 -1
- data/lib/dcmgr/models/ip_lease.rb +27 -14
- data/lib/dcmgr/models/mac_lease.rb +22 -0
- data/lib/dcmgr/models/netfilter_group.rb +3 -2
- data/lib/dcmgr/models/network.rb +47 -10
- data/lib/dcmgr/models/storage_pool.rb +2 -6
- data/lib/dcmgr/models/tag.rb +104 -66
- data/lib/dcmgr/models/tag_mapping.rb +1 -13
- data/lib/dcmgr/models/vlan_lease.rb +17 -0
- data/lib/dcmgr/models/volume.rb +26 -9
- data/lib/dcmgr/models/volume_snapshot.rb +21 -8
- data/lib/dcmgr/node_modules/hva_collector.rb +88 -38
- data/lib/dcmgr/node_modules/instance_ha.rb +65 -0
- data/lib/dcmgr/node_modules/sta_collector.rb +1 -1
- data/lib/dcmgr/tags.rb +54 -0
- metadata +10 -3
data/bin/nsa
CHANGED
@@ -14,7 +14,7 @@ end
|
|
14
14
|
|
15
15
|
require File.expand_path('../../config/path_resolver', __FILE__)
|
16
16
|
|
17
|
-
|
17
|
+
require 'erb'
|
18
18
|
require 'eventmachine'
|
19
19
|
|
20
20
|
class SuperviseDnsmasq < Isono::NodeModules::Base
|
@@ -29,8 +29,22 @@ class SuperviseDnsmasq < Isono::NodeModules::Base
|
|
29
29
|
if manifest.config.network_name.nil?
|
30
30
|
abort("network_name is not set yet in nsa.conf")
|
31
31
|
end
|
32
|
+
|
33
|
+
# check the dnsmasq binary version
|
34
|
+
@conf_ver_253 = false
|
35
|
+
if `#{manifest.config.dnsmasq_bin_path} -version`.split("\n").first =~ /Dnsmasq version ([\d\.]+)/
|
36
|
+
verstr = $1.split('.')
|
37
|
+
if verstr[0].to_i == 2 && verstr[1].to_i >= 53
|
38
|
+
@conf_ver_253 = true
|
39
|
+
end
|
40
|
+
logger.info("Using dnsmasq v#{verstr}: configuration version #{@conf_ver_253 ? '>= 2.53' : '< 2.53'}")
|
41
|
+
else
|
42
|
+
logger.warn("Failed to detect dnsmasq binary version")
|
43
|
+
end
|
44
|
+
|
32
45
|
|
33
|
-
opts = sprintf("-k --no-hosts --no-resolv --
|
46
|
+
opts = sprintf("-k --no-hosts --no-resolv --leasefile-ro --dhcp-leasefile=/dev/null " +
|
47
|
+
"--addn-hosts=%s --dhcp-hostsfile=%s --conf-file=%s",
|
34
48
|
config_section.dhcp_hosts_conf + ".hosts",
|
35
49
|
config_section.dhcp_hosts_conf + ".dhcp",
|
36
50
|
config_section.dhcp_hosts_conf
|
@@ -85,42 +99,58 @@ class SuperviseDnsmasq < Isono::NodeModules::Base
|
|
85
99
|
# load entier macaddr,ipaddr pairs for all instances from collector.
|
86
100
|
confdata = rpc.request('hva-collector', 'get_dhcp_conf', manifest.config.network_name)
|
87
101
|
|
88
|
-
|
89
|
-
|
90
|
-
File.open(config_section.dhcp_hosts_conf, 'w') { |f|
|
91
|
-
f << ERB.new(<<'_EOS_', nil, '-').result(binding)
|
92
|
-
#interface=eth0
|
102
|
+
render_conf(config_section.dhcp_hosts_conf, binding, <<'_EOS_')
|
93
103
|
server=8.8.8.8
|
94
|
-
|
95
|
-
|
96
|
-
dhcp
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
104
|
+
log-facility=/var/log/dnsmasq.log
|
105
|
+
#log-queries
|
106
|
+
log-dhcp
|
107
|
+
<%- confdata.each { |nwid, v| -%>
|
108
|
+
<%- if @conf_ver_253 -%>
|
109
|
+
dhcp-range=set:<%= nwid %>,<%= v[:ipv4_first] %>,static,<%= v[:netmask] %>
|
110
|
+
dhcp-option=tag:<%= nwid %>,option:netmask,<%= v[:netmask] %>
|
111
|
+
dhcp-option=tag:<%= nwid %>,option:router,<%= v[:ipv4_gw] %>
|
112
|
+
dhcp-option=tag:<%= nwid %>,option:dns-server,<%= v[:dns_server] %>
|
113
|
+
dhcp-option=tag:<%= nwid %>,option:domain-name,<%= v[:domain_name] %>
|
114
|
+
#dhcp-option=tag:<%= nwid %>,option:domain-search,<%= v[:domain_name] %>
|
115
|
+
<%- else # if @conf_ver_253 -%>
|
116
|
+
dhcp-range=net:<%= nwid %>,<%= v[:ipv4_first] %>,static,<%= v[:netmask] %>
|
117
|
+
dhcp-option=<%= nwid %>,option:netmask,<%= v[:netmask] %>
|
118
|
+
dhcp-option=<%= nwid %>,option:router,<%= v[:ipv4_gw] %>
|
119
|
+
dhcp-option=<%= nwid %>,option:dns-server,<%= v[:dns_server] %>
|
120
|
+
dhcp-option=<%= nwid %>,option:domain-name,<%= v[:domain_name] %>
|
121
|
+
#dhcp-option=<%= nwid %>,option:domain-search,<%= v[:domain_name] %>
|
122
|
+
<%- end # if @conf_ver_253 -%>
|
123
|
+
<%- v[:mac2addr].each { |i| -%>
|
124
|
+
#dhcp-host=<%= i[:mac_addr] %>,net:<%= nwid %>,<%= i[:ipaddr] %>
|
102
125
|
<%- } -%>
|
103
|
-
<%-
|
126
|
+
<%- v[:addr2host].each { |i| -%>
|
104
127
|
#address=/<%= i[:hostname] %>/<%= i[:ipaddr] %>
|
105
128
|
<%- } -%>
|
129
|
+
<%- } -%>
|
106
130
|
_EOS_
|
107
|
-
}
|
108
131
|
|
109
|
-
|
110
|
-
|
111
|
-
<%-
|
112
|
-
<%= i[:mac_addr] %>,<%= i[:ipaddr]
|
132
|
+
render_conf(config_section.dhcp_hosts_conf + ".dhcp", binding, <<'_EOS_')
|
133
|
+
<%- confdata.each { |nwid, v| -%>
|
134
|
+
<%- v[:mac2addr].each { |i| -%>
|
135
|
+
<%= i[:mac_addr] %>,net:<%= nwid %>,<%= i[:ipaddr] %>,infinite
|
136
|
+
<%- } -%>
|
113
137
|
<%- } -%>
|
114
138
|
_EOS_
|
115
|
-
}
|
116
139
|
|
117
|
-
|
118
|
-
|
119
|
-
<%-
|
140
|
+
render_conf(config_section.dhcp_hosts_conf + ".hosts", binding, <<'_EOS_')
|
141
|
+
<%- confdata.each { |nwid, v| -%>
|
142
|
+
<%- v[:addr2host].each { |i| -%>
|
120
143
|
<%= i[:ipaddr] %> <%= i[:hostname] %>
|
144
|
+
<%- } -%>
|
121
145
|
<%- } -%>
|
122
146
|
_EOS_
|
123
|
-
|
147
|
+
end
|
148
|
+
|
149
|
+
private
|
150
|
+
def render_conf(file, bind, templ)
|
151
|
+
File.open(file, 'w') { |f|
|
152
|
+
f << ERB.new(templ, nil, '-').result(bind)
|
153
|
+
}
|
124
154
|
end
|
125
155
|
end
|
126
156
|
|
data/bin/sta
CHANGED
@@ -19,9 +19,13 @@ class ZfsHandler < EndpointBuilder
|
|
19
19
|
volume_id = request.args[0]
|
20
20
|
job = Dcmgr::Stm::VolumeContext.new(volume_id)
|
21
21
|
data = rpc.request('sta-collector', 'get_volume', volume_id)
|
22
|
-
sdata = rpc.request('sta-collector', 'get_snapshot', data[:snapshot_id]) unless data[:snapshot_id].nil?
|
23
|
-
logger.info("creating new volume #{volume_id}")
|
24
22
|
raise "Invalid volume state: #{data[:state]}" unless data[:state].to_s == 'registering'
|
23
|
+
|
24
|
+
unless data[:snapshot_id].nil?
|
25
|
+
sdata = rpc.request('sta-collector', 'get_snapshot', data[:snapshot_id])
|
26
|
+
raise "Invalid snapshot state: #{sdata[:state]}" unless sdata[:state].to_s == 'available'
|
27
|
+
end
|
28
|
+
logger.info("creating new volume #{volume_id}")
|
25
29
|
job.stm.state=data[:state].to_sym
|
26
30
|
job.stm.on_create
|
27
31
|
|
@@ -119,6 +123,7 @@ class ZfsHandler < EndpointBuilder
|
|
119
123
|
sdata = rpc.request('sta-collector', 'get_snapshot', snapshot_id) unless snapshot_id.nil?
|
120
124
|
data = rpc.request('sta-collector', 'get_volume', sdata[:origin_volume_id])
|
121
125
|
logger.info("create new snapshot: #{snapshot_id}")
|
126
|
+
raise "Invalid volume state: #{data[:state]}" unless data[:state].to_s == 'available'
|
122
127
|
job.stm.state=sdata[:state].to_sym
|
123
128
|
job.stm.on_create
|
124
129
|
|
@@ -144,14 +149,16 @@ class ZfsHandler < EndpointBuilder
|
|
144
149
|
job :delete_snapshot do
|
145
150
|
snapshot_id = request.args[0]
|
146
151
|
job = Dcmgr::Stm::SnapshotContext.new(snapshot_id)
|
147
|
-
sdata = rpc.request('sta-collector', 'get_snapshot', snapshot_id)
|
152
|
+
sdata = rpc.request('sta-collector', 'get_snapshot', snapshot_id)
|
148
153
|
data = rpc.request('sta-collector', 'get_volume', sdata[:origin_volume_id])
|
149
154
|
logger.info("deleting snapshot: #{snapshot_id}")
|
150
155
|
raise "Invalid snapshot state: #{sdata[:state]}" unless sdata[:state].to_s == 'deleting'
|
151
156
|
job.stm.state=sdata[:state].to_sym
|
152
157
|
job.stm.on_delete
|
153
158
|
|
154
|
-
|
159
|
+
system("rm -rf #{data[:storage_pool][:snapshot_base_path]}/#{sdata[:account_id]}/#{sdata[:uuid]}.zsnap")
|
160
|
+
raise "snapshot has not be deleted" if $?.exitstatus != 0
|
161
|
+
|
155
162
|
rpc.request('sta-collector', 'update_snapshot', job.to_hash)
|
156
163
|
logger.info("deleted snapshot: #{snapshot_id}")
|
157
164
|
end
|
data/config/hva.conf.example
CHANGED
@@ -8,3 +8,12 @@ config.vm_data_dir = "/home/demo/vm"
|
|
8
8
|
# netfilter
|
9
9
|
config.enable_ebtables = true
|
10
10
|
config.enable_iptables = true
|
11
|
+
|
12
|
+
# physical nic index
|
13
|
+
config.hv_ifindex = 2 # ex. /sys/class/net/eth0/ifindex => 2
|
14
|
+
|
15
|
+
# bridge device name prefix
|
16
|
+
config.bridge_prefix = 'br'
|
17
|
+
|
18
|
+
# bridge device name novlan
|
19
|
+
config.bridge_novlan = 'br0'
|
data/config/nsa.conf.example
CHANGED
data/lib/dcmgr.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
module Dcmgr
|
4
|
-
VERSION='10.
|
4
|
+
VERSION='10.12.0'
|
5
5
|
|
6
6
|
class << self
|
7
7
|
def conf
|
@@ -73,7 +73,9 @@ module Dcmgr
|
|
73
73
|
:StoragePool,:Volume,:VolumeSnapshot,
|
74
74
|
:InstanceNetfilterGroup,
|
75
75
|
:InstanceSpec, :InstanceNic, :Network, :IpLease,
|
76
|
-
:SshKeyPair
|
76
|
+
:SshKeyPair, :History, :HostnameLease, :MacLease,
|
77
|
+
:VlanLease,
|
78
|
+
].freeze
|
77
79
|
autoload :BaseNew, 'dcmgr/models/base_new'
|
78
80
|
autoload :Account, 'dcmgr/models/account'
|
79
81
|
autoload :Tag, 'dcmgr/models/tag'
|
@@ -95,6 +97,10 @@ module Dcmgr
|
|
95
97
|
autoload :IpLease, 'dcmgr/models/ip_lease'
|
96
98
|
autoload :InstanceNetfilterGroup, 'dcmgr/models/instance_netfilter_group'
|
97
99
|
autoload :SshKeyPair, 'dcmgr/models/ssh_key_pair'
|
100
|
+
autoload :History, 'dcmgr/models/history'
|
101
|
+
autoload :HostnameLease, 'dcmgr/models/hostname_lease'
|
102
|
+
autoload :MacLease, 'dcmgr/models/mac_lease'
|
103
|
+
autoload :VlanLease, 'dcmgr/models/vlan_lease'
|
98
104
|
end
|
99
105
|
|
100
106
|
module Endpoints
|
@@ -105,6 +111,7 @@ module Dcmgr
|
|
105
111
|
module NodeModules
|
106
112
|
autoload :StaCollector, 'dcmgr/node_modules/sta_collector'
|
107
113
|
autoload :HvaCollector, 'dcmgr/node_modules/hva_collector'
|
114
|
+
autoload :InstanceHA, 'dcmgr/node_modules/instance_ha'
|
108
115
|
end
|
109
116
|
|
110
117
|
module Stm
|
@@ -112,4 +119,10 @@ module Dcmgr
|
|
112
119
|
autoload :SnapshotContext, 'dcmgr/stm/snapshot_context'
|
113
120
|
autoload :Instance, 'dcmgr/stm/instance'
|
114
121
|
end
|
122
|
+
|
123
|
+
module Helpers
|
124
|
+
autoload :CliHelper, 'dcmgr/helpers/cli_helper'
|
125
|
+
end
|
126
|
+
|
127
|
+
autoload :Tags, 'dcmgr/tags'
|
115
128
|
end
|
@@ -110,6 +110,7 @@ module Dcmgr
|
|
110
110
|
def create_volume_from_snapshot(account_id, snapshot_id)
|
111
111
|
vs = find_by_uuid(:VolumeSnapshot, snapshot_id)
|
112
112
|
raise UnknownVolumeSnapshot if vs.nil?
|
113
|
+
raise InvalidRequestCredentials unless vs.state.to_s == 'available'
|
113
114
|
vs.create_volume(account_id)
|
114
115
|
end
|
115
116
|
|
@@ -131,9 +132,7 @@ module Dcmgr
|
|
131
132
|
operation :show do
|
132
133
|
control do
|
133
134
|
a = find_account(params[:id])
|
134
|
-
|
135
|
-
f.json { a.to_hash_document.to_json }
|
136
|
-
}
|
135
|
+
response_to(a.to_hash)
|
137
136
|
end
|
138
137
|
end
|
139
138
|
|
@@ -141,9 +140,7 @@ module Dcmgr
|
|
141
140
|
description 'Register a new account'
|
142
141
|
control do
|
143
142
|
a = Models::Account.create()
|
144
|
-
|
145
|
-
f.json { a.to_hash_document.to_json }
|
146
|
-
}
|
143
|
+
response_to(a.to_hash)
|
147
144
|
end
|
148
145
|
end
|
149
146
|
|
@@ -156,9 +153,7 @@ module Dcmgr
|
|
156
153
|
a = find_account(params[:id])
|
157
154
|
a.destroy
|
158
155
|
|
159
|
-
|
160
|
-
f.json { {} }
|
161
|
-
}
|
156
|
+
response_to([a.canonical_uuid])
|
162
157
|
end
|
163
158
|
end
|
164
159
|
|
@@ -271,9 +266,7 @@ module Dcmgr
|
|
271
266
|
:results=> partial_ds.all.map {|i| i.to_api_document }
|
272
267
|
}]
|
273
268
|
|
274
|
-
|
275
|
-
f.json {res.to_json}
|
276
|
-
}
|
269
|
+
response_to(res)
|
277
270
|
end
|
278
271
|
end
|
279
272
|
|
@@ -281,30 +274,94 @@ module Dcmgr
|
|
281
274
|
description 'Runs a new VM instance'
|
282
275
|
# param :image_id, string, :required
|
283
276
|
# param :instance_spec_id, string, :required
|
284
|
-
# param :
|
277
|
+
# param :host_id, string, :optional
|
285
278
|
# param :host_name, string, :optional
|
286
279
|
# param :user_data, string, :optional
|
287
280
|
# param :nf_group, array, :optional
|
288
281
|
# param :ssh_key, string, :optional
|
282
|
+
# param :network_id, string, :optional
|
283
|
+
# param :ha_enabled, string, :optional
|
289
284
|
control do
|
290
285
|
Models::Instance.lock!
|
291
286
|
|
292
287
|
wmi = find_by_uuid(:Image, params[:image_id])
|
293
288
|
spec = find_by_uuid(:InstanceSpec, (params[:instance_spec_id] || 'is-kpf0pasc'))
|
294
289
|
|
295
|
-
|
296
|
-
|
297
|
-
|
290
|
+
# look up params[:host_id] in following order:
|
291
|
+
# 1. assume the host pool name.
|
292
|
+
# 2. assume hp-xxxxx or tag-xxxxx style uuid
|
293
|
+
# 3. assign default shared host pool.
|
294
|
+
params[:host_id] ||= params[:host_pool_id]
|
295
|
+
hostnode = pool = nil
|
296
|
+
if params[:host_id]
|
297
|
+
# TODO: smart way to preload model libs.
|
298
|
+
Models::HostPool; Tags::HostPool;
|
299
|
+
if pool = Tags::HostPool.find(:account_id=>@account.canonical_uuid,
|
300
|
+
:name=>params[:host_id])
|
301
|
+
# Pattern 1st
|
302
|
+
elsif hostnode = Models::Taggable.find(params[:host_id])
|
303
|
+
# Pattern 2nd
|
304
|
+
case hostnode
|
305
|
+
when Models::HostPool
|
306
|
+
when Tags::HostPool
|
307
|
+
hostnode = hostnode.pick(spec)
|
308
|
+
else
|
309
|
+
raise UnknownHostPool, "Could not find the host: #{params[:host_id]}"
|
310
|
+
end
|
311
|
+
end
|
298
312
|
else
|
299
|
-
#
|
313
|
+
# Pattern 3rd
|
314
|
+
pool = Tags::HostPool[Dcmgr.conf.default_shared_host_pool]
|
315
|
+
hostnode = pool.pick(spec)
|
300
316
|
end
|
301
|
-
|
302
|
-
raise
|
317
|
+
raise UnknownHostPool, "Could not find host pool: #{params[:host_id]}" if hostnode.nil?
|
318
|
+
raise OutOfHostCapacity unless hostnode.check_capacity(spec)
|
319
|
+
|
320
|
+
# look up params[:network_id] in following order:
|
321
|
+
# 1. assume the network pool name.
|
322
|
+
# 2. assume nw-xxxxx or tag-xxxxx style uuid
|
323
|
+
# 3. assign default shared network pool.
|
324
|
+
# then randomly choose one network from the pool object.
|
325
|
+
network = pool = nil
|
326
|
+
if params[:network_id]
|
327
|
+
# TODO: smart way to preload model libs.
|
328
|
+
Models::Network; Tags::NetworkPool;
|
329
|
+
if pool = Tags::NetworkPool.find(:account_id=>@account.canonical_uuid,
|
330
|
+
:name=>params[:network_id])
|
331
|
+
# Pattern 1st
|
332
|
+
network = pool.pick
|
333
|
+
elsif network = Models::Taggable.find(params[:network_id])
|
334
|
+
# Pattern 2nd
|
335
|
+
case network
|
336
|
+
when Models::Network
|
337
|
+
when Tags::NetworkPool
|
338
|
+
network = network.pick
|
339
|
+
else
|
340
|
+
raise "Unknown network uuid: #{params[:network_id]}"
|
341
|
+
end
|
342
|
+
end
|
343
|
+
else
|
344
|
+
# Pattern 3rd
|
345
|
+
pool = Tags::NetworkPool[Dcmgr.conf.default_shared_network_pool]
|
346
|
+
network = pool.pick
|
347
|
+
end
|
348
|
+
raise "Can not find the network" if network.nil?
|
349
|
+
raise "Out of IP addresses in the network" unless network.available_ip_nums > 0
|
303
350
|
|
304
|
-
inst =
|
351
|
+
inst = hostnode.create_instance(@account, wmi, spec, network) do |i|
|
305
352
|
# TODO: do not use rand() to decide vnc port.
|
306
353
|
i.runtime_config = {:vnc_port=>rand(2000), :telnet_port=> (rand(2000) + 2000)}
|
307
354
|
i.user_data = params[:user_data] || ''
|
355
|
+
# set only when not nil as the table column has not null
|
356
|
+
# condition.
|
357
|
+
if params[:hostname]
|
358
|
+
if Models::Instance::ValidationMethods.hostname_uniqueness(@account.canonical_uuid,
|
359
|
+
params[:hostname])
|
360
|
+
i.hostname = params[:hostname]
|
361
|
+
else
|
362
|
+
raise DuplicateHostname
|
363
|
+
end
|
364
|
+
end
|
308
365
|
|
309
366
|
if params[:ssh_key]
|
310
367
|
ssh_key_pair = Models::SshKeyPair.find(:account_id=>@account.canonical_uuid,
|
@@ -315,6 +372,10 @@ module Dcmgr
|
|
315
372
|
i.ssh_key_pair_id = ssh_key_pair.canonical_uuid
|
316
373
|
end
|
317
374
|
end
|
375
|
+
|
376
|
+
if params[:ha_enabled] == 'true'
|
377
|
+
i.ha_enabled = 1
|
378
|
+
end
|
318
379
|
end
|
319
380
|
|
320
381
|
unless params[:nf_group].is_a?(Array)
|
@@ -328,17 +389,17 @@ module Dcmgr
|
|
328
389
|
snapshot_id = wmi.source[:snapshot_id]
|
329
390
|
vol = create_volume_from_snapshot(@account.canonical_uuid, snapshot_id)
|
330
391
|
|
392
|
+
vol.boot_dev = 1
|
331
393
|
vol.instance = inst
|
332
394
|
vol.save
|
333
|
-
res = Dcmgr.messaging.submit("kvm-handle.#{
|
395
|
+
res = Dcmgr.messaging.submit("kvm-handle.#{hostnode.node_id}", 'run_vol_store', inst.canonical_uuid, vol.canonical_uuid)
|
334
396
|
when Models::Image::BOOT_DEV_LOCAL
|
335
|
-
res = Dcmgr.messaging.submit("kvm-handle.#{
|
397
|
+
res = Dcmgr.messaging.submit("kvm-handle.#{hostnode.node_id}", 'run_local_store', inst.canonical_uuid)
|
336
398
|
else
|
337
399
|
raise "Unknown boot type"
|
338
400
|
end
|
339
|
-
|
340
|
-
|
341
|
-
}
|
401
|
+
|
402
|
+
response_to(inst.to_api_document)
|
342
403
|
end
|
343
404
|
end
|
344
405
|
|
@@ -348,9 +409,7 @@ module Dcmgr
|
|
348
409
|
i = find_by_uuid(:Instance, params[:id])
|
349
410
|
raise UnknownInstance if i.nil?
|
350
411
|
|
351
|
-
|
352
|
-
f.json { i.to_api_document.to_json }
|
353
|
-
}
|
412
|
+
response_to(i.to_api_document)
|
354
413
|
end
|
355
414
|
end
|
356
415
|
|
@@ -364,9 +423,7 @@ module Dcmgr
|
|
364
423
|
raise OperationNotPermitted
|
365
424
|
end
|
366
425
|
res = Dcmgr.messaging.submit("kvm-handle.#{i.host_pool.node_id}", 'terminate', i.canonical_uuid)
|
367
|
-
|
368
|
-
f.json { i.canonical_uuid }
|
369
|
-
}
|
426
|
+
response_to([i.canonical_uuid])
|
370
427
|
end
|
371
428
|
end
|
372
429
|
|
@@ -407,9 +464,7 @@ module Dcmgr
|
|
407
464
|
:results=> partial_ds.all.map {|i| i.to_hash }
|
408
465
|
}]
|
409
466
|
|
410
|
-
|
411
|
-
f.json {res.to_json}
|
412
|
-
}
|
467
|
+
response_to(res)
|
413
468
|
end
|
414
469
|
end
|
415
470
|
|
@@ -421,9 +476,7 @@ module Dcmgr
|
|
421
476
|
unless examine_owner(i)
|
422
477
|
raise OperationNotPermitted
|
423
478
|
end
|
424
|
-
|
425
|
-
f.json { i.to_hash.to_json }
|
426
|
-
}
|
479
|
+
response_to(i.to_hash)
|
427
480
|
end
|
428
481
|
end
|
429
482
|
|
@@ -437,6 +490,7 @@ module Dcmgr
|
|
437
490
|
else
|
438
491
|
raise OperationNotPermitted
|
439
492
|
end
|
493
|
+
response_to([i.canonical_uuid])
|
440
494
|
end
|
441
495
|
end
|
442
496
|
end
|
@@ -461,9 +515,7 @@ module Dcmgr
|
|
461
515
|
:results=> partial_ds.all.map {|i| i.to_hash }
|
462
516
|
}]
|
463
517
|
|
464
|
-
|
465
|
-
f.json {res.to_json}
|
466
|
-
}
|
518
|
+
response_to(res)
|
467
519
|
end
|
468
520
|
end
|
469
521
|
|
@@ -474,9 +526,7 @@ module Dcmgr
|
|
474
526
|
hp = find_by_uuid(:HostPool, params[:id])
|
475
527
|
raise OperationNotPermitted unless examine_owner(hp)
|
476
528
|
|
477
|
-
|
478
|
-
f.json { hp.to_hash.to_json }
|
479
|
-
}
|
529
|
+
response_to(hp.to_hash)
|
480
530
|
end
|
481
531
|
end
|
482
532
|
end
|
@@ -499,11 +549,9 @@ module Dcmgr
|
|
499
549
|
:owner_total => total_v.count,
|
500
550
|
:start => start,
|
501
551
|
:limit => limit,
|
502
|
-
:results => partial_v.all.map { |v| v.
|
552
|
+
:results => partial_v.all.map { |v| v.to_api_document}
|
503
553
|
}]
|
504
|
-
|
505
|
-
f.json { res.to_json}
|
506
|
-
}
|
554
|
+
response_to(res)
|
507
555
|
end
|
508
556
|
end
|
509
557
|
|
@@ -514,9 +562,7 @@ module Dcmgr
|
|
514
562
|
volume_id = params[:id]
|
515
563
|
raise UndefinedVolumeID if volume_id.nil?
|
516
564
|
v = find_by_uuid(:Volume, volume_id)
|
517
|
-
|
518
|
-
f.json { v.to_hash_document.to_json}
|
519
|
-
}
|
565
|
+
response_to(v.to_api_document)
|
520
566
|
end
|
521
567
|
end
|
522
568
|
|
@@ -531,8 +577,10 @@ module Dcmgr
|
|
531
577
|
v = create_volume_from_snapshot(@account.canonical_uuid, params[:snapshot_id])
|
532
578
|
sp = v.storage_pool
|
533
579
|
elsif params[:volume_size]
|
534
|
-
|
535
|
-
].to_i >= Dcmgr.conf.create_volume_min_size.to_i)
|
580
|
+
if !(Dcmgr.conf.create_volume_max_size.to_i >= params[:volume_size].to_i) ||
|
581
|
+
!(params[:volume_size].to_i >= Dcmgr.conf.create_volume_min_size.to_i)
|
582
|
+
raise InvalidVolumeSize
|
583
|
+
end
|
536
584
|
if params[:storage_pool_id]
|
537
585
|
sp = find_by_uuid(:StoragePool, params[:storage_pool_id])
|
538
586
|
raise StoragePoolNotPermitted if sp.account_id != @account.canonical_uuid
|
@@ -552,9 +600,7 @@ module Dcmgr
|
|
552
600
|
end
|
553
601
|
|
554
602
|
res = Dcmgr.messaging.submit("zfs-handle.#{sp.values[:node_id]}", 'create_volume', v.canonical_uuid)
|
555
|
-
|
556
|
-
f.json { v.to_hash_document.to_json}
|
557
|
-
}
|
603
|
+
response_to(v.to_api_document)
|
558
604
|
end
|
559
605
|
end
|
560
606
|
|
@@ -576,9 +622,7 @@ module Dcmgr
|
|
576
622
|
sp = v.storage_pool
|
577
623
|
|
578
624
|
res = Dcmgr.messaging.submit("zfs-handle.#{sp.values[:node_id]}", 'delete_volume', v.canonical_uuid)
|
579
|
-
|
580
|
-
f.json { v.to_hash_document.to_json}
|
581
|
-
}
|
625
|
+
response_to([v.canonical_uuid])
|
582
626
|
end
|
583
627
|
end
|
584
628
|
|
@@ -592,17 +636,17 @@ module Dcmgr
|
|
592
636
|
|
593
637
|
i = find_by_uuid(:Instance, params[:instance_id])
|
594
638
|
raise UnknownInstance if i.nil?
|
639
|
+
raise InvalidInstanceState unless i.live? && i.state == 'running'
|
595
640
|
|
596
641
|
v = find_by_uuid(:Volume, params[:id])
|
597
642
|
raise UnknownVolume if v.nil?
|
643
|
+
raise AttachVolumeFailure, "Volume is attached to running instance." if v.instance
|
598
644
|
|
599
645
|
v.instance = i
|
600
646
|
v.save
|
601
647
|
res = Dcmgr.messaging.submit("kvm-handle.#{i.host_pool.node_id}", 'attach', i.canonical_uuid, v.canonical_uuid)
|
602
648
|
|
603
|
-
|
604
|
-
f.json { v.to_hash_document.to_json}
|
605
|
-
}
|
649
|
+
response_to(v.to_api_document)
|
606
650
|
end
|
607
651
|
end
|
608
652
|
|
@@ -614,11 +658,13 @@ module Dcmgr
|
|
614
658
|
|
615
659
|
v = find_by_uuid(:Volume, params[:id])
|
616
660
|
raise UnknownVolume if v.nil?
|
661
|
+
raise DetachVolumeFailure, "Volume is not attached to any instance." if v.instance.nil?
|
662
|
+
# the volume as the boot device can not be detached.
|
663
|
+
raise DetachVolumeFailure, "boot device can not be detached" if v.boot_dev == 1
|
617
664
|
i = v.instance
|
665
|
+
raise InvalidInstanceState unless i.live? && i.state == 'running'
|
618
666
|
res = Dcmgr.messaging.submit("kvm-handle.#{i.host_pool.node_id}", 'detach', i.canonical_uuid, v.canonical_uuid)
|
619
|
-
|
620
|
-
f.json {v.to_hash_document.to_json}
|
621
|
-
}
|
667
|
+
response_to(v.to_api_document)
|
622
668
|
end
|
623
669
|
end
|
624
670
|
|
@@ -655,11 +701,9 @@ module Dcmgr
|
|
655
701
|
:owner_total => total_vs.count,
|
656
702
|
:start => start,
|
657
703
|
:limit => limit,
|
658
|
-
:results => partial_vs.all.map { |vs| vs.
|
704
|
+
:results => partial_vs.all.map { |vs| vs.to_api_document}
|
659
705
|
}]
|
660
|
-
|
661
|
-
f.json { res.to_json}
|
662
|
-
}
|
706
|
+
response_to(res)
|
663
707
|
end
|
664
708
|
end
|
665
709
|
|
@@ -670,9 +714,7 @@ module Dcmgr
|
|
670
714
|
snapshot_id = params[:id]
|
671
715
|
raise UndefinedVolumeSnapshotID if snapshot_id.nil?
|
672
716
|
vs = find_by_uuid(:VolumeSnapshot, snapshot_id)
|
673
|
-
|
674
|
-
f.json { vs.to_hash_document.to_json}
|
675
|
-
}
|
717
|
+
response_to(vs.to_api_document)
|
676
718
|
end
|
677
719
|
end
|
678
720
|
|
@@ -686,14 +728,13 @@ module Dcmgr
|
|
686
728
|
|
687
729
|
v = find_by_uuid(:Volume, params[:volume_id])
|
688
730
|
raise UnknownVolume if v.nil?
|
731
|
+
raise InvalidRequestCredentials unless v.state == "available"
|
689
732
|
|
690
733
|
vs = v.create_snapshot(@account.canonical_uuid)
|
691
734
|
sp = vs.storage_pool
|
692
735
|
|
693
736
|
res = Dcmgr.messaging.submit("zfs-handle.#{sp.node_id}", 'create_snapshot', vs.canonical_uuid)
|
694
|
-
|
695
|
-
f.json { vs.to_hash_document.to_json}
|
696
|
-
}
|
737
|
+
response_to(vs.to_api_document)
|
697
738
|
end
|
698
739
|
end
|
699
740
|
|
@@ -705,15 +746,17 @@ module Dcmgr
|
|
705
746
|
snapshot_id = params[:id]
|
706
747
|
raise UndefindVolumeSnapshotID if snapshot_id.nil?
|
707
748
|
|
708
|
-
|
749
|
+
begin
|
750
|
+
vs = Models::VolumeSnapshot.delete_snapshot(@account.canonical_uuid, snapshot_id)
|
751
|
+
rescue Models::VolumeSnapshot::RequestError => e
|
752
|
+
logger.error(e)
|
753
|
+
raise InvalidDeleteRequest
|
754
|
+
end
|
709
755
|
raise UnknownVolumeSnapshot if vs.nil?
|
710
|
-
vs = vs.delete_snapshot
|
711
756
|
sp = vs.storage_pool
|
712
757
|
|
713
758
|
res = Dcmgr.messaging.submit("zfs-handle.#{sp.node_id}", 'delete_snapshot', vs.canonical_uuid)
|
714
|
-
|
715
|
-
f.json { vs.to_hash_document.to_json }
|
716
|
-
}
|
759
|
+
response_to([vs.canonical_uuid])
|
717
760
|
end
|
718
761
|
end
|
719
762
|
|
@@ -752,9 +795,7 @@ module Dcmgr
|
|
752
795
|
:results=> partial_ds.all.map {|i| i.to_hash }
|
753
796
|
}]
|
754
797
|
|
755
|
-
|
756
|
-
f.json {res.to_json}
|
757
|
-
}
|
798
|
+
response_to(res)
|
758
799
|
end
|
759
800
|
end
|
760
801
|
|
@@ -762,12 +803,9 @@ module Dcmgr
|
|
762
803
|
description 'Show the netfilter_groups'
|
763
804
|
control do
|
764
805
|
g = find_by_uuid(:NetfilterGroup, params[:id])
|
765
|
-
p params[:id]
|
766
806
|
raise OperationNotPermitted unless examine_owner(g)
|
767
807
|
|
768
|
-
|
769
|
-
f.json { g.to_hash.to_json }
|
770
|
-
}
|
808
|
+
response_to(g.to_hash)
|
771
809
|
end
|
772
810
|
end
|
773
811
|
|
@@ -788,9 +826,7 @@ module Dcmgr
|
|
788
826
|
raise DuplicatedNetfilterGroup unless g.nil?
|
789
827
|
|
790
828
|
g = Models::NetfilterGroup.create_group(@account.canonical_uuid, params)
|
791
|
-
|
792
|
-
f.json { g.to_hash.to_json }
|
793
|
-
}
|
829
|
+
response_to(g.to_hash)
|
794
830
|
end
|
795
831
|
end
|
796
832
|
|
@@ -816,9 +852,7 @@ module Dcmgr
|
|
816
852
|
# refresh netfilter_rules
|
817
853
|
Dcmgr.messaging.event_publish('hva/netfilter_updated', :args=>[g.canonical_uuid])
|
818
854
|
|
819
|
-
|
820
|
-
f.json { g.to_hash.to_json }
|
821
|
-
}
|
855
|
+
response_to(g.to_hash)
|
822
856
|
end
|
823
857
|
end
|
824
858
|
|
@@ -833,9 +867,8 @@ module Dcmgr
|
|
833
867
|
raise UnknownNetfilterGroup if g.nil?
|
834
868
|
raise NetfilterGroupNotPermitted if g.account_id != @account.canonical_uuid
|
835
869
|
|
836
|
-
|
837
|
-
|
838
|
-
}
|
870
|
+
g.destroy
|
871
|
+
response_to([g.canonical_uuid])
|
839
872
|
end
|
840
873
|
end
|
841
874
|
|
@@ -861,9 +894,7 @@ module Dcmgr
|
|
861
894
|
}
|
862
895
|
end
|
863
896
|
|
864
|
-
|
865
|
-
f.json { rules.to_json }
|
866
|
-
}
|
897
|
+
response_to(rules)
|
867
898
|
end
|
868
899
|
end
|
869
900
|
end
|
@@ -887,12 +918,10 @@ module Dcmgr
|
|
887
918
|
:owner_total => total_ds.count,
|
888
919
|
:start => start,
|
889
920
|
:limit => limit,
|
890
|
-
:results=> partial_ds.all.map {|sp| sp.
|
921
|
+
:results=> partial_ds.all.map {|sp| sp.to_hash }
|
891
922
|
}]
|
892
923
|
|
893
|
-
|
894
|
-
f.json { res.to_json}
|
895
|
-
}
|
924
|
+
response_to(res)
|
896
925
|
end
|
897
926
|
end
|
898
927
|
|
@@ -904,9 +933,7 @@ module Dcmgr
|
|
904
933
|
raise UndefinedStoragePoolID if pool_id.nil?
|
905
934
|
vs = find_by_uuid(:StoragePool, pool_id)
|
906
935
|
raise UnknownStoragePool if vs.nil?
|
907
|
-
|
908
|
-
f.json { vs.to_hash_document.to_json}
|
909
|
-
}
|
936
|
+
response_to(vs.to_hash)
|
910
937
|
end
|
911
938
|
end
|
912
939
|
end
|
@@ -934,9 +961,7 @@ module Dcmgr
|
|
934
961
|
:results=> partial_ds.all.map {|i| i.to_hash }
|
935
962
|
}]
|
936
963
|
|
937
|
-
|
938
|
-
f.json {res.to_json}
|
939
|
-
}
|
964
|
+
response_to(res)
|
940
965
|
end
|
941
966
|
end
|
942
967
|
|
@@ -947,9 +972,7 @@ module Dcmgr
|
|
947
972
|
control do
|
948
973
|
ssh = find_by_uuid(:SshKeyPair, params[:id])
|
949
974
|
|
950
|
-
|
951
|
-
f.json {ssh.to_hash.to_json}
|
952
|
-
}
|
975
|
+
response_to(ssh.to_hash)
|
953
976
|
end
|
954
977
|
end
|
955
978
|
|
@@ -971,11 +994,9 @@ module Dcmgr
|
|
971
994
|
end
|
972
995
|
ssh = Models::SshKeyPair.create(savedata)
|
973
996
|
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
f.json {ssh.to_hash.merge(:private_key=>keydata[:private_key]).to_json}
|
978
|
-
}
|
997
|
+
# include private_key data in response even if
|
998
|
+
# it's not going to be stored on DB.
|
999
|
+
response_to(ssh.to_hash.merge(:private_key=>keydata[:private_key]))
|
979
1000
|
end
|
980
1001
|
end
|
981
1002
|
|
@@ -991,14 +1012,155 @@ module Dcmgr
|
|
991
1012
|
raise OperationNotPermitted
|
992
1013
|
end
|
993
1014
|
|
994
|
-
|
995
|
-
f.json {ssh.to_hash.to_json}
|
996
|
-
}
|
1015
|
+
response_to([ssh.canonical_uuid])
|
997
1016
|
end
|
998
1017
|
end
|
999
1018
|
|
1000
1019
|
end
|
1001
1020
|
|
1021
|
+
collection :networks do
|
1022
|
+
description "Networks for account"
|
1023
|
+
operation :index do
|
1024
|
+
description "List networks in account"
|
1025
|
+
# params start, fixnum, optional
|
1026
|
+
# params limit, fixnum, optional
|
1027
|
+
control do
|
1028
|
+
start = params[:start].to_i
|
1029
|
+
start = start < 1 ? 0 : start
|
1030
|
+
limit = params[:limit].to_i
|
1031
|
+
limit = limit < 1 ? nil : limit
|
1032
|
+
|
1033
|
+
total_ds = Models::Network.where(:account_id=>@account.canonical_uuid)
|
1034
|
+
partial_ds = total_ds.dup.order(:id)
|
1035
|
+
partial_ds = partial_ds.limit(limit, start) if limit.is_a?(Integer)
|
1036
|
+
|
1037
|
+
res = [{
|
1038
|
+
:owner_total => total_ds.count,
|
1039
|
+
:filter_total => total_ds.count,
|
1040
|
+
:start => start,
|
1041
|
+
:limit => limit,
|
1042
|
+
:results=> partial_ds.all.map {|i| i.to_hash }
|
1043
|
+
}]
|
1044
|
+
|
1045
|
+
response_to(res)
|
1046
|
+
end
|
1047
|
+
end
|
1048
|
+
|
1049
|
+
operation :show do
|
1050
|
+
description "Retrieve details about a network"
|
1051
|
+
# params :id required
|
1052
|
+
control do
|
1053
|
+
nw = find_by_uuid(:Network, params[:id])
|
1054
|
+
examine_owner(nw) || raise(OperationNotPermitted)
|
1055
|
+
|
1056
|
+
response_to(nw.to_hash)
|
1057
|
+
end
|
1058
|
+
end
|
1059
|
+
|
1060
|
+
operation :create do
|
1061
|
+
description "Create new network"
|
1062
|
+
# params :gw required default gateway address of the network
|
1063
|
+
# params :prefix optional netmask bit length. it will be
|
1064
|
+
# set 24 if none.
|
1065
|
+
# params :description optional description for the network
|
1066
|
+
control do
|
1067
|
+
Models::Network.lock!
|
1068
|
+
savedata = {
|
1069
|
+
:account_id=>@account.canonical_uuid,
|
1070
|
+
:ipv4_gw => params[:gw],
|
1071
|
+
:prefix => params[:prefix].to_i,
|
1072
|
+
:description => params[:description],
|
1073
|
+
}
|
1074
|
+
nw = Models::Network.create(savedata)
|
1075
|
+
|
1076
|
+
response_to(nw.to_hash)
|
1077
|
+
end
|
1078
|
+
end
|
1079
|
+
|
1080
|
+
operation :destroy do
|
1081
|
+
description "Remove network information"
|
1082
|
+
# params :id required
|
1083
|
+
control do
|
1084
|
+
Models::Network.lock!
|
1085
|
+
nw = find_by_uuid(:Network, params[:id])
|
1086
|
+
examine_owner(nw) || raise(OperationNotPermitted)
|
1087
|
+
nw.destroy
|
1088
|
+
|
1089
|
+
response_to([nw.canonical_uuid])
|
1090
|
+
end
|
1091
|
+
end
|
1092
|
+
|
1093
|
+
operation :reserve, :method =>:put, :member=>true do
|
1094
|
+
description 'Register reserved IP address to the network'
|
1095
|
+
# params id, string, required
|
1096
|
+
# params ipaddr, [String,Array], required
|
1097
|
+
control do
|
1098
|
+
Models::IpLease.lock!
|
1099
|
+
nw = find_by_uuid(:Network, params[:id])
|
1100
|
+
examine_owner(nw) || raise(OperationNotPermitted)
|
1101
|
+
|
1102
|
+
(ipaddr.is_a?(Array) ? params[:ipaddr] : Array(params[:ipaddr])).each { |ip|
|
1103
|
+
nw.add_reserved(ip)
|
1104
|
+
}
|
1105
|
+
response_to({})
|
1106
|
+
end
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
operation :release, :method =>:put, :member=>true do
|
1110
|
+
description 'Unregister reserved IP address from the network'
|
1111
|
+
# params id, string, required
|
1112
|
+
# params ipaddr, [String,Array], required
|
1113
|
+
control do
|
1114
|
+
Models::IpLease.lock!
|
1115
|
+
nw = find_by_uuid(:Network, params[:id])
|
1116
|
+
examine_owner(nw) || raise(OperationNotPermitted)
|
1117
|
+
|
1118
|
+
(ipaddr.is_a?(Array) ? params[:ipaddr] : Array(params[:ipaddr])).each { |ip|
|
1119
|
+
nw.delete_reserved(ip)
|
1120
|
+
}
|
1121
|
+
response_to({})
|
1122
|
+
end
|
1123
|
+
end
|
1124
|
+
|
1125
|
+
operation :add_pool, :method=>:put, :member=>true do
|
1126
|
+
description 'Label network pool name'
|
1127
|
+
# param :name required
|
1128
|
+
control do
|
1129
|
+
Models::Tag.lock!
|
1130
|
+
nw = find_by_uuid(:Network, params[:id])
|
1131
|
+
examine_owner(nw) || raise(OperationNotPermitted)
|
1132
|
+
nw.label_tag(:NetworkPool, params[:name], @account.canonical_uuid)
|
1133
|
+
response_to({})
|
1134
|
+
end
|
1135
|
+
end
|
1136
|
+
|
1137
|
+
operation :del_pool, :method=>:put, :member=>true do
|
1138
|
+
description 'Unlabel network pool name'
|
1139
|
+
# param :name required
|
1140
|
+
control do
|
1141
|
+
Models::Tag.lock!
|
1142
|
+
nw = find_by_uuid(:Network, params[:id])
|
1143
|
+
examine_owner(nw) || raise(OperationNotPermitted)
|
1144
|
+
|
1145
|
+
nw.unlabel_tag(:NetworkPool, params[:name], @account.canonical_uuid)
|
1146
|
+
response_to({})
|
1147
|
+
end
|
1148
|
+
end
|
1149
|
+
|
1150
|
+
operation :get_pool, :method=>:get, :member=>true do
|
1151
|
+
description 'List network pool name'
|
1152
|
+
# param :name required
|
1153
|
+
control do
|
1154
|
+
Models::Tag.lock!
|
1155
|
+
nw = find_by_uuid(:Network, params[:id])
|
1156
|
+
examine_owner(nw) || raise(OperationNotPermitted)
|
1157
|
+
|
1158
|
+
res = nw.tags_dataset.filter(:type_id=>Tags.type_id(:NetworkPool)).all.map{|i| i.to_api_document }
|
1159
|
+
response_to(res)
|
1160
|
+
end
|
1161
|
+
end
|
1162
|
+
end
|
1163
|
+
|
1002
1164
|
end
|
1003
1165
|
end
|
1004
1166
|
end
|