deltacloud-core 1.0.4 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +2 -2
- data/config/drivers/aruba.yaml +3 -3
- data/deltacloud-core.gemspec +2 -2
- data/lib/cimi/collections/address_templates.rb +1 -2
- data/lib/cimi/collections/addresses.rb +1 -2
- data/lib/cimi/collections/base.rb +1 -1
- data/lib/cimi/collections/credentials.rb +2 -3
- data/lib/cimi/collections/forwarding_group_templates.rb +1 -2
- data/lib/cimi/collections/forwarding_groups.rb +1 -2
- data/lib/cimi/collections/machine_configurations.rb +1 -2
- data/lib/cimi/collections/machine_images.rb +1 -2
- data/lib/cimi/collections/machines.rb +9 -9
- data/lib/cimi/collections/network_configurations.rb +1 -2
- data/lib/cimi/collections/network_port_configurations.rb +1 -2
- data/lib/cimi/collections/network_port_templates.rb +1 -2
- data/lib/cimi/collections/network_ports.rb +1 -2
- data/lib/cimi/collections/network_templates.rb +1 -2
- data/lib/cimi/collections/networks.rb +2 -3
- data/lib/cimi/collections/volume_configurations.rb +1 -2
- data/lib/cimi/collections/volume_images.rb +1 -2
- data/lib/cimi/collections/volumes.rb +3 -4
- data/lib/cimi/helpers/cimi_helper.rb +7 -2
- data/lib/cimi/models.rb +6 -10
- data/lib/cimi/models/base.rb +48 -35
- data/lib/cimi/models/cloud_entry_point.rb +22 -1
- data/lib/cimi/models/collection.rb +42 -5
- data/lib/cimi/models/credential.rb +1 -1
- data/lib/cimi/models/disk.rb +39 -10
- data/lib/cimi/models/machine.rb +39 -22
- data/lib/cimi/models/machine_configuration.rb +4 -5
- data/lib/cimi/models/machine_image.rb +1 -1
- data/lib/cimi/models/machine_volume.rb +1 -1
- data/lib/cimi/models/network.rb +6 -3
- data/lib/cimi/models/network_port.rb +13 -2
- data/lib/cimi/models/schema.rb +66 -5
- data/lib/cimi/models/volume.rb +17 -16
- data/lib/cimi/models/volume_configuration.rb +7 -10
- data/lib/cimi/models/volume_image.rb +1 -1
- data/lib/deltacloud/collections/base.rb +1 -1
- data/lib/deltacloud/collections/firewalls.rb +2 -2
- data/lib/deltacloud/collections/load_balancers.rb +8 -2
- data/lib/deltacloud/core_ext.rb +1 -0
- data/lib/deltacloud/core_ext/base.rb +30 -0
- data/lib/deltacloud/drivers.rb +1 -1
- data/lib/deltacloud/drivers/base_driver.rb +1 -1
- data/lib/deltacloud/drivers/condor/condor_driver.rb +1 -1
- data/lib/deltacloud/drivers/exceptions.rb +24 -14
- data/lib/deltacloud/drivers/features.rb +3 -3
- data/lib/deltacloud/drivers/fgcp/fgcp_driver.rb +163 -92
- data/lib/deltacloud/drivers/mock/data/images/img1.yml +1 -0
- data/lib/deltacloud/drivers/mock/data/images/img2.yml +1 -0
- data/lib/deltacloud/drivers/mock/data/images/img3.yml +1 -0
- data/lib/deltacloud/drivers/mock/mock_client.rb +4 -4
- data/lib/deltacloud/drivers/mock/mock_driver.rb +16 -16
- data/lib/deltacloud/drivers/openstack/openstack_driver.rb +25 -9
- data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +2 -1
- data/lib/deltacloud/drivers/terremark/terremark_driver.rb +1 -1
- data/lib/deltacloud/drivers/vsphere/vsphere_driver.rb +2 -0
- data/lib/deltacloud/helpers/deltacloud_helper.rb +29 -8
- data/lib/deltacloud/models/image.rb +1 -0
- data/lib/deltacloud/models/instance_profile.rb +4 -0
- data/lib/deltacloud/version.rb +1 -1
- data/lib/ec2/query_parser.rb +1 -1
- data/lib/sinatra/rack_accept.rb +5 -1
- data/lib/sinatra/rack_logger.rb +9 -2
- data/tests/cimi/collections/machine_images_test.rb +23 -6
- data/tests/cimi/collections/machines_test.rb +39 -0
- data/tests/cimi/model/collection_spec.rb +109 -0
- data/tests/cimi/{spec/cimi/model → model}/credential_spec.rb +1 -1
- data/tests/cimi/{spec/cimi/model → model}/machine_configuration_spec.rb +1 -1
- data/tests/cimi/{spec/cimi/model → model}/machine_image_spec.rb +1 -1
- data/tests/cimi/{spec/cimi/model → model}/machine_spec.rb +1 -1
- data/tests/cimi/{spec/cimi/model → model}/machine_template_spec.rb +1 -1
- data/tests/cimi/{spec/cimi/model → model}/schema_spec.rb +1 -1
- data/tests/cimi/{spec/cimi/model → model}/volume_configuration_spec.rb +1 -1
- data/tests/cimi/{spec/cimi/model → model}/volume_image_spec.rb +1 -1
- data/tests/cimi/{spec/cimi/model → model}/volume_spec.rb +1 -1
- data/tests/cimi/{spec/cimi/model → model}/volume_template_spec.rb +1 -1
- data/tests/cimi/{spec/spec_helper.rb → spec_helper.rb} +7 -4
- data/tests/drivers/base/exceptions_test.rb +8 -8
- data/tests/drivers/ec2/buckets_test.rb +1 -1
- data/tests/drivers/ec2/images_test.rb +1 -1
- data/tests/drivers/ec2/instance_test.rb +1 -1
- data/tests/drivers/ec2/keys_test.rb +2 -2
- data/tests/drivers/ec2/realms_test.rb +1 -1
- data/tests/drivers/ec2/storage_snapshots_test.rb +1 -1
- data/tests/drivers/gogrid/hardware_profiles_test.rb +1 -1
- data/tests/drivers/gogrid/images_test.rb +1 -1
- data/tests/drivers/gogrid/instances_test.rb +1 -1
- data/tests/drivers/gogrid/realms_test.rb +1 -1
- data/tests/drivers/mock/images_test.rb +7 -2
- data/tests/drivers/mock/instances_test.rb +1 -1
- data/tests/drivers/mock/keys_test.rb +2 -2
- data/tests/drivers/mock/realms_test.rb +1 -1
- data/tests/drivers/mock/storage_snapshots_test.rb +1 -1
- data/tests/drivers/mock/storage_volumes_test.rb +1 -1
- data/tests/drivers/openstack/hardware_profiles_test.rb +3 -3
- data/tests/drivers/openstack/images_test.rb +1 -1
- data/tests/drivers/openstack/instances_test.rb +1 -1
- data/tests/drivers/openstack/keys_test.rb +2 -2
- data/tests/drivers/openstack/realms_test.rb +1 -1
- data/tests/drivers/rhevm/common.rb +3 -3
- data/tests/drivers/rhevm/images_test.rb +13 -13
- data/tests/drivers/rhevm/instance_test.rb +22 -22
- data/tests/drivers/rhevm/provider_test.rb +3 -3
- data/tests/drivers/rhevm/realms_test.rb +7 -7
- data/tests/test_helper.rb +0 -5
- data/views/api/show.xml.haml +6 -3
- data/views/errors/401.html.haml +0 -16
- data/views/errors/404.html.haml +2 -3
- data/views/errors/500.html.haml +6 -5
- data/views/images/show.html.haml +5 -1
- data/views/images/show.xml.haml +8 -3
- data/views/instances/new.html.haml +1 -1
- data/views/instances/show.xml.haml +1 -1
- data/views/load_balancers/show.html.haml +1 -1
- metadata +761 -778
- data/lib/cimi/models/disk_collection.rb +0 -37
- data/lib/cimi/models/machine_volume_collection.rb +0 -34
- data/lib/cimi/models/network_port_collection.rb +0 -51
- data/lib/cimi/models/network_port_configuration_collection.rb +0 -35
- data/lib/cimi/models/network_port_template_collection.rb +0 -37
data/lib/cimi/models/volume.rb
CHANGED
@@ -17,20 +17,22 @@ class CIMI::Model::Volume < CIMI::Model::Base
|
|
17
17
|
|
18
18
|
acts_as_root_entity
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
text :state
|
21
|
+
|
22
|
+
text :type
|
23
|
+
|
24
|
+
text :capacity
|
25
|
+
|
24
26
|
text :bootable
|
25
|
-
|
27
|
+
|
26
28
|
array :snapshots do
|
27
29
|
scalar :ref
|
28
30
|
end
|
29
|
-
|
31
|
+
|
30
32
|
array :meters do
|
31
33
|
scalar :ref
|
32
34
|
end
|
33
|
-
|
35
|
+
|
34
36
|
array :operations do
|
35
37
|
scalar :rel, :href
|
36
38
|
end
|
@@ -40,7 +42,7 @@ class CIMI::Model::Volume < CIMI::Model::Base
|
|
40
42
|
opts = ( id == :all ) ? {} : { :id => id }
|
41
43
|
volumes = context.driver.storage_volumes(context.credentials, opts)
|
42
44
|
volumes.collect!{ |volume| from_storage_volume(volume, context) }
|
43
|
-
return volumes.first unless volumes.length > 1
|
45
|
+
return volumes.first unless volumes.length > 1 || volumes.length == 0
|
44
46
|
return volumes
|
45
47
|
end
|
46
48
|
|
@@ -68,14 +70,14 @@ class CIMI::Model::Volume < CIMI::Model::Base
|
|
68
70
|
|
69
71
|
def self.find_to_attach_from_json(json_in, context)
|
70
72
|
json = JSON.parse(json_in)
|
71
|
-
|
72
|
-
|
73
|
+
json["volumes"].map{|v| {:volume=>self.find(v["volume"]["href"].split("/volumes/").last, context),
|
74
|
+
:attachment_point=>v["attachmentPoint"] }}
|
73
75
|
end
|
74
76
|
|
75
77
|
def self.find_to_attach_from_xml(xml_in, context)
|
76
78
|
xml = XmlSimple.xml_in(xml_in)
|
77
|
-
|
78
|
-
|
79
|
+
xml["volume"].map{|v| {:volume => self.find(v["href"].split("/volumes/").last, context),
|
80
|
+
:attachment_point=>v["attachmentPoint"] }}
|
79
81
|
end
|
80
82
|
|
81
83
|
private
|
@@ -90,14 +92,13 @@ class CIMI::Model::Volume < CIMI::Model::Base
|
|
90
92
|
def self.from_storage_volume(volume, context)
|
91
93
|
self.new( { :name => volume.id,
|
92
94
|
:description => volume.id,
|
93
|
-
:created => volume.created,
|
95
|
+
:created => Time.parse(volume.created).xmlschema,
|
94
96
|
:id => context.volume_url(volume.id),
|
95
97
|
:capacity => { :quantity=>volume.capacity, :units=>"gibibyte" }, #FIXME... units will vary
|
96
98
|
:bootable => "false", #fixme ... will vary... ec2 doesn't expose this
|
97
|
-
:supports_snapshots => "true", #fixme, will vary (true for ec2)
|
98
99
|
:snapshots => [], #fixme...
|
99
|
-
:
|
100
|
-
:
|
100
|
+
:type => 'http://schemas.dmtf.org/cimi/1/mapped',
|
101
|
+
:state => volume.state,
|
101
102
|
:meters => []
|
102
103
|
} )
|
103
104
|
end
|
@@ -18,12 +18,9 @@ class CIMI::Model::VolumeConfiguration < CIMI::Model::Base
|
|
18
18
|
acts_as_root_entity :as => "volumeConfigs"
|
19
19
|
|
20
20
|
text :format
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
text :supports_snapshots
|
26
|
-
text :guest_interface
|
21
|
+
|
22
|
+
text :capacity
|
23
|
+
|
27
24
|
array :operations do
|
28
25
|
scalar :rel, :href
|
29
26
|
end
|
@@ -50,10 +47,10 @@ class CIMI::Model::VolumeConfiguration < CIMI::Model::Base
|
|
50
47
|
def self.create(size, context)
|
51
48
|
self.new( {
|
52
49
|
:id => context.volume_configuration_url(size),
|
53
|
-
:name => size,
|
54
|
-
:description => "
|
55
|
-
:created => Time.now.
|
56
|
-
:capacity =>
|
50
|
+
:name => "volume-#{size}",
|
51
|
+
:description => "Volume configuration with #{size} kilobytes",
|
52
|
+
:created => Time.now.xmlschema,
|
53
|
+
:capacity => context.to_kibibyte(size, "MB"),
|
57
54
|
:supports_snapshots => "true"
|
58
55
|
# FIXME :guest_interface => "NFS"
|
59
56
|
} )
|
@@ -41,7 +41,7 @@ class CIMI::Model::VolumeImage < CIMI::Model::Base
|
|
41
41
|
self.new( {
|
42
42
|
:name => snapshot.id,
|
43
43
|
:description => snapshot.id,
|
44
|
-
:created => snapshot.created,
|
44
|
+
:created => Time.parse(snapshot.created).xmlschema,
|
45
45
|
:id => context.volume_image_url(snapshot.id),
|
46
46
|
:image_location => {:href=>context.volume_url(snapshot.storage_volume_id)},
|
47
47
|
:bootable => "false" #FIXME
|
@@ -99,8 +99,8 @@ module Deltacloud::Collections
|
|
99
99
|
params['addresses'] = addresses
|
100
100
|
params['groups'] = groups
|
101
101
|
if addresses.empty? && groups.empty?
|
102
|
-
raise Deltacloud::
|
103
|
-
|
102
|
+
raise Deltacloud::Exceptions.exception_from_status(
|
103
|
+
400, 'No sources. Specify at least one source ip address or group.'
|
104
104
|
)
|
105
105
|
end
|
106
106
|
driver.create_firewall_rule(credentials, params)
|
@@ -23,7 +23,7 @@ module Deltacloud::Collections
|
|
23
23
|
end
|
24
24
|
|
25
25
|
collection :load_balancers do
|
26
|
-
description "Load balancers are used distribute workload across multiple instances"
|
26
|
+
description "Load balancers are used to distribute workload across multiple instances"
|
27
27
|
|
28
28
|
standard_index_operation
|
29
29
|
|
@@ -32,7 +32,13 @@ module Deltacloud::Collections
|
|
32
32
|
control do
|
33
33
|
@load_balancer = driver.load_balancer(credentials, params)
|
34
34
|
@registered_instances = @load_balancer.instances.collect{|i| {:id => i.id, :name=> i.name}}
|
35
|
-
|
35
|
+
# if provider supports realm_filter and load balancer has only one realm (which is mostly the case), use optimization:
|
36
|
+
if @load_balancer.realms.size == 1 and driver.class.has_feature?(:instances, :realm_filter)
|
37
|
+
all_instances = driver.instances(credentials, :realm_id => @load_balancer.realms.first.id).collect{|i| {:id => i.id, :name => i.name}}
|
38
|
+
elsif
|
39
|
+
all_instances = driver.instances(credentials).collect{|i| {:id => i.id, :name => i.name} }
|
40
|
+
end
|
41
|
+
@unregistered_instances = all_instances - @registered_instances
|
36
42
|
respond_to do |format|
|
37
43
|
format.xml { haml :'load_balancers/show' }
|
38
44
|
format.json { xml_to_json('load_balancers/show') }
|
data/lib/deltacloud/core_ext.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one or more
|
2
|
+
# contributor license agreements. See the NOTICE file distributed with
|
3
|
+
# this work for additional information regarding copyright ownership. The
|
4
|
+
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
5
|
+
# "License"); you may not use this file except in compliance with the
|
6
|
+
# License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
12
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
13
|
+
# License for the specific language governing permissions and limitations
|
14
|
+
# under the License.
|
15
|
+
|
16
|
+
def get_current_memory_usage
|
17
|
+
`ps -o rss= -p #{Process.pid}`.to_i
|
18
|
+
end
|
19
|
+
|
20
|
+
def profile_memory(&block)
|
21
|
+
before = get_current_memory_usage
|
22
|
+
file, line, _ = caller[0].split(':')
|
23
|
+
if block_given?
|
24
|
+
instance_eval(&block)
|
25
|
+
puts "[#{file}:#{line}: #{(get_current_memory_usage - before) / 1024} MB (consumed)]"
|
26
|
+
else
|
27
|
+
before = 0
|
28
|
+
puts "[#{file}:#{line}: #{(get_current_memory_usage - before) / 1024} MB (all)]"
|
29
|
+
end
|
30
|
+
end
|
data/lib/deltacloud/drivers.rb
CHANGED
@@ -26,7 +26,7 @@ module Deltacloud
|
|
26
26
|
Thread::current[:drivers] = {}
|
27
27
|
top_srcdir = File.join(File.dirname(__FILE__), '..', '..')
|
28
28
|
Dir[File.join(top_srcdir, 'config', 'drivers', '*.yaml')].each do |driver_file|
|
29
|
-
Thread::current[:drivers].merge!(YAML::
|
29
|
+
Thread::current[:drivers].merge!(YAML::load_file(driver_file))
|
30
30
|
end
|
31
31
|
end
|
32
32
|
Thread::current[:drivers]
|
@@ -192,7 +192,7 @@ module Deltacloud
|
|
192
192
|
|
193
193
|
def new_client(credentials)
|
194
194
|
if ( credentials.user != 'condor' ) or ( credentials.password != 'deltacloud' )
|
195
|
-
raise Deltacloud::
|
195
|
+
raise Deltacloud::Exceptions::AuthenticationFailure.new
|
196
196
|
end
|
197
197
|
safely do
|
198
198
|
yield CondorCloud::DefaultExecutor.new
|
@@ -15,7 +15,7 @@
|
|
15
15
|
#
|
16
16
|
|
17
17
|
module Deltacloud
|
18
|
-
module
|
18
|
+
module Exceptions
|
19
19
|
|
20
20
|
class DeltacloudException < StandardError
|
21
21
|
|
@@ -30,6 +30,13 @@ module Deltacloud
|
|
30
30
|
|
31
31
|
end
|
32
32
|
|
33
|
+
class AcceptedButNotCompletedError < DeltacloudException
|
34
|
+
def initialize(e, message=nil)
|
35
|
+
message ||= e.message
|
36
|
+
super(202, e.class.name, message, e.backtrace)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
33
40
|
class AuthenticationFailure < DeltacloudException
|
34
41
|
def initialize(e, message=nil)
|
35
42
|
message ||= e.message
|
@@ -115,6 +122,7 @@ module Deltacloud
|
|
115
122
|
def initialize(conditions, &block)
|
116
123
|
@conditions = conditions
|
117
124
|
instance_eval(&block) if block_given?
|
125
|
+
self
|
118
126
|
end
|
119
127
|
|
120
128
|
def status(code)
|
@@ -142,21 +150,26 @@ module Deltacloud
|
|
142
150
|
def handler(e)
|
143
151
|
return @handler if @handler
|
144
152
|
case @status
|
145
|
-
when
|
146
|
-
when
|
147
|
-
when
|
148
|
-
when
|
149
|
-
when
|
150
|
-
when
|
151
|
-
when
|
152
|
-
when
|
153
|
-
when
|
154
|
-
when
|
153
|
+
when 202 then AcceptedButNotCompletedError.new(e, @message)
|
154
|
+
when 401 then AuthenticationFailure.new(e, @message)
|
155
|
+
when 403 then ForbiddenError.new(e, @message)
|
156
|
+
when 404 then ObjectNotFound.new(e, @message)
|
157
|
+
when 406 then UnknownMediaTypeError.new(e, @message)
|
158
|
+
when 405 then MethodNotAllowed.new(e, @message)
|
159
|
+
when 400 then ValidationFailure.new(e, @message)
|
160
|
+
when 500 then BackendError.new(e, @message)
|
161
|
+
when 501 then NotImplemented.new(e, @message)
|
162
|
+
when 502 then ProviderError.new(e, @message)
|
163
|
+
when 504 then ProviderTimeout.new(e, @message)
|
155
164
|
end
|
156
165
|
end
|
157
166
|
|
158
167
|
end
|
159
168
|
|
169
|
+
def self.exception_from_status(code, message)
|
170
|
+
ExceptionDef.new(nil) { status code}.handler(StandardError.new(message))
|
171
|
+
end
|
172
|
+
|
160
173
|
class Exceptions
|
161
174
|
attr_reader :exception_definitions
|
162
175
|
|
@@ -198,17 +211,14 @@ module Deltacloud
|
|
198
211
|
begin
|
199
212
|
block.call
|
200
213
|
rescue => e
|
201
|
-
log = ExceptionHandler.logger
|
202
214
|
self.class.exceptions.each do |definitions|
|
203
215
|
next unless definitions.any? e
|
204
216
|
if (new_exception = definitions.handler(e)) and new_exception.message
|
205
217
|
message = new_exception.message
|
206
218
|
end
|
207
219
|
message ||= e.message
|
208
|
-
log.error "#{[e.class.to_s, message].join(':')}\n#{e.backtrace[0..10].join("\n")}" unless ENV['RACK_ENV'] == 'test'
|
209
220
|
raise definitions.handler(e) unless new_exception.nil?
|
210
221
|
end
|
211
|
-
log.error "[NO HANDLED] #{[e.class.to_s, e.message].join(': ')}\n#{e.backtrace.join("\n")}" unless ENV['RACK_ENV'] == 'test'
|
212
222
|
raise BackendError.new(e, "Unhandled exception or status code (#{e.message})")
|
213
223
|
end
|
214
224
|
end
|
@@ -135,14 +135,14 @@ module Deltacloud
|
|
135
135
|
end
|
136
136
|
|
137
137
|
feature :instance_count, :for => :instances do
|
138
|
-
description "Number of instances to
|
138
|
+
description "Number of instances to launch at once"
|
139
139
|
operation :create do
|
140
140
|
param :instance_count, :string, :optional
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
144
144
|
feature :attach_snapshot, :for => :instances do
|
145
|
-
description "Attach
|
145
|
+
description "Attach a snapshot to instance on create"
|
146
146
|
operation :create do
|
147
147
|
param :snapshot_id, :string, :optional
|
148
148
|
param :device_name, :string, :optional
|
@@ -150,7 +150,7 @@ module Deltacloud
|
|
150
150
|
end
|
151
151
|
|
152
152
|
feature :sandboxing, :for => :instances do
|
153
|
-
description "Allow
|
153
|
+
description "Allow launching sandbox images"
|
154
154
|
operation :create do
|
155
155
|
param :sandbox, :string, :optional
|
156
156
|
end
|
@@ -29,6 +29,7 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
29
29
|
|
30
30
|
feature :instances, :user_name
|
31
31
|
feature :instances, :metrics
|
32
|
+
feature :instances, :realm_filter
|
32
33
|
feature :images, :user_name
|
33
34
|
feature :images, :user_description
|
34
35
|
|
@@ -168,19 +169,18 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
168
169
|
realms = []
|
169
170
|
safely do
|
170
171
|
client = new_client(credentials)
|
171
|
-
|
172
|
-
# first retrieve list of VSYS ids (and add if scope is not only filtering for network)
|
172
|
+
|
173
173
|
if opts and opts[:id]
|
174
174
|
|
175
|
-
# determine id belongs to
|
175
|
+
# determine id belongs to system or network
|
176
176
|
vsys_id = client.extract_vsys_id(opts[:id])
|
177
177
|
vsys = client.get_vsys_attributes(vsys_id)['vsys'][0]
|
178
178
|
realm_name = vsys['vsysName'][0]
|
179
|
-
limit = '[
|
179
|
+
limit = '[System]'
|
180
180
|
if opts[:id] != vsys_id # network id specified
|
181
181
|
opts[:id] =~ /^.*\b(\w+)$/
|
182
|
-
realm_name += ' [' + $1 + ']' #
|
183
|
-
limit = '[Network
|
182
|
+
realm_name += ' [' + $1 + ']' # system name or system name + network [DMZ/SECURE1/SECURE2]
|
183
|
+
limit = '[Network]'
|
184
184
|
end
|
185
185
|
realms << Realm::new(
|
186
186
|
:id => opts[:id],
|
@@ -188,7 +188,6 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
188
188
|
#:limit => :unlimited,
|
189
189
|
:limit => limit,
|
190
190
|
:state => 'AVAILABLE' # map to state of FW/VSYS (reconfiguring = unavailable)?
|
191
|
-
# :scope => 'system'
|
192
191
|
)
|
193
192
|
elsif xml = client.list_vsys['vsyss']
|
194
193
|
|
@@ -197,11 +196,10 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
197
196
|
|
198
197
|
realms << Realm::new(
|
199
198
|
:id => vsys['vsysId'][0], # vsysId or networkId
|
200
|
-
:name => vsys['vsysName'][0], #
|
199
|
+
:name => vsys['vsysName'][0], # system name or system name + network (DMZ/SECURE1/SECURE2)
|
201
200
|
#:limit => :unlimited,
|
202
|
-
:limit => '[
|
201
|
+
:limit => '[System]',
|
203
202
|
:state => 'AVAILABLE' # map to state of FW/VSYS (reconfiguring = unavailable)?
|
204
|
-
# :scope => 'system'
|
205
203
|
)
|
206
204
|
# then retrieve and add list of network segments
|
207
205
|
client.get_vsys_configuration(vsys['vsysId'][0])['vsys'][0]['vnets'][0]['vnet'].each do |vnet|
|
@@ -212,9 +210,8 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
212
210
|
:id => vnet['networkId'][0], # vsysId or networkId
|
213
211
|
:name => realm_name,
|
214
212
|
#:limit => :unlimited,
|
215
|
-
:limit => '[Network
|
213
|
+
:limit => '[Network]',
|
216
214
|
:state => 'AVAILABLE' # map to state of FW/VSYS (reconfiguring = unavailable)?
|
217
|
-
# :scope => 'network'
|
218
215
|
)
|
219
216
|
end
|
220
217
|
end
|
@@ -232,20 +229,25 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
232
229
|
safely do
|
233
230
|
client = new_client(credentials)
|
234
231
|
|
235
|
-
if opts and opts[:id]
|
236
|
-
vsys_id = client.extract_vsys_id(opts[:id])
|
232
|
+
if opts and opts[:id] or opts[:realm_id]
|
233
|
+
vsys_id = client.extract_vsys_id(opts[:id] || opts[:realm_id])
|
237
234
|
vsys_config = client.get_vsys_configuration(vsys_id)
|
238
235
|
vsys_config['vsys'][0]['vservers'][0]['vserver'].each do |vserver|
|
239
|
-
|
236
|
+
network_id = vserver['vnics'][0]['vnic'][0]['networkId'][0]
|
237
|
+
# :realm_id can point to system or network
|
238
|
+
if vsys_id == opts[:realm_id] or vserver['vserverId'][0] == opts[:id] or network_id == opts[:realm_id]
|
240
239
|
|
241
|
-
#
|
242
|
-
|
243
|
-
|
240
|
+
# skip firewall if filtering by realm
|
241
|
+
unless opts[:realm_id] and determine_server_type(vserver) == 'FW'
|
242
|
+
# check state first as it may be filtered on
|
243
|
+
state_data = instance_state_data(vserver, client)
|
244
|
+
if opts[:state].nil? or opts[:state] == state_data[:state]
|
244
245
|
|
245
|
-
|
246
|
-
|
246
|
+
instance = convert_to_instance(client, vserver, state_data)
|
247
|
+
add_instance_details(instance, client, vserver)
|
247
248
|
|
248
|
-
|
249
|
+
instances << instance
|
250
|
+
end
|
249
251
|
end
|
250
252
|
end
|
251
253
|
end
|
@@ -258,12 +260,16 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
258
260
|
vsys_config = client.get_vsys_configuration(vsys['vsysId'][0])
|
259
261
|
vsys_config['vsys'][0]['vservers'][0]['vserver'].each do |vserver|
|
260
262
|
|
261
|
-
#
|
262
|
-
#
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
263
|
+
# skip firewalls - they probably don't belong here and their new type ('firewall' instead of
|
264
|
+
# 'economy') causes errors when trying to map to available profiles)
|
265
|
+
unless determine_server_type(vserver) == 'FW'
|
266
|
+
# to keep the response time of this method acceptable, retrieve state
|
267
|
+
# only if required because state is filtered on
|
268
|
+
state_data = opts[:state] ? instance_state_data(vserver, client) : nil
|
269
|
+
# filter on state
|
270
|
+
if opts[:state].nil? or opts[:state] == state_data[:state]
|
271
|
+
instances << convert_to_instance(client, vserver, state_data)
|
272
|
+
end
|
267
273
|
end
|
268
274
|
end
|
269
275
|
end
|
@@ -343,6 +349,12 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
343
349
|
network_id = opts[:realm_id]
|
344
350
|
safely do
|
345
351
|
client = new_client(credentials)
|
352
|
+
if not network_id
|
353
|
+
xml = client.list_vsys['vsyss']
|
354
|
+
|
355
|
+
# use first returned system's DMZ as realm
|
356
|
+
network_id = xml ? xml[0]['vsys'][0]['vsysId'][0] + '-N-DMZ' : nil
|
357
|
+
end
|
346
358
|
xml = client.create_vserver(name, hwp, image_id, network_id)
|
347
359
|
# returns vserver details
|
348
360
|
instances(credentials, {:id => xml['vserverId'][0]}).first
|
@@ -404,7 +416,12 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
404
416
|
safely do
|
405
417
|
client = new_client(credentials)
|
406
418
|
if opts and opts[:id]
|
407
|
-
|
419
|
+
begin
|
420
|
+
vdisk = client.get_vdisk_attributes(opts[:id])['vdisk'][0]
|
421
|
+
rescue Exception => ex
|
422
|
+
return [] if ex.message =~ /VALIDATION_ERROR.*t exist./
|
423
|
+
raise
|
424
|
+
end
|
408
425
|
state = client.get_vdisk_status(opts[:id])['vdiskStatus'][0]
|
409
426
|
actions = []
|
410
427
|
if state == 'NORMAL'
|
@@ -474,7 +491,7 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
474
491
|
elsif xml = client.list_vsys['vsyss']
|
475
492
|
|
476
493
|
# use first vsys returned as realm
|
477
|
-
opts[:realm_id] = xml[0]['vsys'][0]['vsysId'][0]
|
494
|
+
opts[:realm_id] = xml[0]['vsys'][0]['vsysId'][0] if xml
|
478
495
|
end
|
479
496
|
|
480
497
|
vdisk_id = client.create_vdisk(opts[:realm_id], opts[:name], opts[:capacity])['vdiskId'][0]
|
@@ -528,18 +545,24 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
528
545
|
if opts and opts[:id]
|
529
546
|
vdisk_id, backup_id = split_snapshot_id(opts[:id])
|
530
547
|
|
531
|
-
|
548
|
+
begin
|
549
|
+
if backups = client.list_vdisk_backup(vdisk_id)['backups']
|
532
550
|
|
533
|
-
|
551
|
+
backups[0]['backup'].each do |backup|
|
534
552
|
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
553
|
+
snapshots << StorageSnapshot.new(
|
554
|
+
:id => opts[:id],
|
555
|
+
#:state => ?,
|
556
|
+
:storage_volume_id => vdisk_id,
|
557
|
+
:created => backup['backupTime'][0]
|
558
|
+
) if backup_id = backup['backupId'][0]
|
559
|
+
end
|
541
560
|
end
|
561
|
+
rescue Exception => ex
|
562
|
+
return [] if ex.message =~ /RESOURCE_NOT_FOUND/
|
563
|
+
raise
|
542
564
|
end
|
565
|
+
|
543
566
|
elsif xml = client.list_vsys['vsyss']
|
544
567
|
|
545
568
|
return [] if xml.nil?
|
@@ -683,8 +706,8 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
683
706
|
opts[:realm_id] = client.extract_vsys_id(opts[:realm_id])
|
684
707
|
else
|
685
708
|
# get first vsys
|
686
|
-
xml = client.list_vsys
|
687
|
-
opts[:realm_id] = xml[
|
709
|
+
xml = client.list_vsys['vsyss']
|
710
|
+
opts[:realm_id] = xml[0]['vsys'][0]['vsysId'][0] if xml
|
688
711
|
end
|
689
712
|
|
690
713
|
client.allocate_public_ip(opts[:realm_id])
|
@@ -834,49 +857,56 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
834
857
|
</Request>
|
835
858
|
eofwpxml
|
836
859
|
|
837
|
-
|
860
|
+
begin
|
861
|
+
fw = client.get_efm_configuration(opts[:id], 'FW_POLICY', configuration_xml)
|
862
|
+
rescue Exception => ex
|
863
|
+
return [] if ex.message =~ /RESOURCE_NOT_FOUND/
|
864
|
+
raise
|
865
|
+
end
|
838
866
|
fw_name = fw['efm'][0]['efmName'][0] # currently always 'Firewall'
|
839
867
|
fw_owner_id = fw['efm'][0]['creator'][0]
|
840
868
|
rule50000_log = true
|
841
869
|
|
842
|
-
fw['efm'][0]['firewall'][0]['directions'][0]['direction']
|
870
|
+
if fw['efm'][0]['firewall'][0]['directions'] and fw['efm'][0]['firewall'][0]['directions'][0]['direction']
|
871
|
+
fw['efm'][0]['firewall'][0]['directions'][0]['direction'].each do |direction|
|
843
872
|
|
844
|
-
|
873
|
+
direction['policies'][0]['policy'].each do |policy|
|
845
874
|
|
846
|
-
|
847
|
-
|
875
|
+
sources = []
|
876
|
+
['src', 'dst'].each do |e|
|
848
877
|
|
849
|
-
|
878
|
+
if policy[e] and policy[e][0] and not policy[e][0].empty?
|
850
879
|
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
880
|
+
ip_address_type = policy["#{e}Type"][0]
|
881
|
+
address = policy[e][0]
|
882
|
+
address.sub!('any', '0.0.0.0/0') if ip_address_type == 'IP'
|
883
|
+
address += '/32' if ip_address_type == 'IP' and not address =~ /.*\/.*/
|
855
884
|
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
885
|
+
sources << {
|
886
|
+
:type => 'address',
|
887
|
+
:family => 'ipv4',
|
888
|
+
:address => address.split('/').first,
|
889
|
+
:prefix => ip_address_type == 'IP' ? address.split('/').last : nil
|
890
|
+
}
|
891
|
+
end
|
862
892
|
end
|
863
|
-
end
|
864
893
|
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
894
|
+
# defining ingress as access going from Internet/Intranet -> DMZ -> SECURE1 -> SECURE2
|
895
|
+
ingress = policy['id'][0] =~ /[13].*/ ? 'ingress' : 'egress'
|
896
|
+
|
897
|
+
rules << FirewallRule.new({
|
898
|
+
:id => policy['id'][0],
|
899
|
+
:rule_action => policy['action'][0].downcase,
|
900
|
+
:log_rule => policy['log'][0] == 'On',
|
901
|
+
:allow_protocol => policy['protocol'][0],
|
902
|
+
:port_from => policy['srcPort'] ? policy['srcPort'][0] : nil, # not set for e.g. ICMP
|
903
|
+
:port_to => policy['dstPort'] ? policy['dstPort'][0] : nil, # not set for e.g. ICMP
|
904
|
+
:direction => ingress,
|
905
|
+
:sources => sources
|
906
|
+
}) unless policy['id'][0] == '50000' # special case added later
|
907
|
+
|
908
|
+
rule50000_log = (policy['log'][0] == 'On') if policy['id'][0] == '50000'
|
909
|
+
end
|
880
910
|
end
|
881
911
|
end
|
882
912
|
|
@@ -947,7 +977,31 @@ eofwpxml
|
|
947
977
|
def delete_firewall(credentials, opts={})
|
948
978
|
safely do
|
949
979
|
client = new_client(credentials)
|
950
|
-
|
980
|
+
begin
|
981
|
+
# try to stop FW first
|
982
|
+
opts[:id] =~ /^(.*-S-)\d\d\d\d/
|
983
|
+
fw_id = $1 + '0001'
|
984
|
+
client.stop_efm(fw_id)
|
985
|
+
rescue Exception => ex
|
986
|
+
raise ex if not ex.message =~ /ALREADY_STOPPED.*/
|
987
|
+
client.destroy_vsys(client.extract_vsys_id(opts[:id]))
|
988
|
+
return
|
989
|
+
end
|
990
|
+
|
991
|
+
Thread.new {
|
992
|
+
attempts = 0
|
993
|
+
begin
|
994
|
+
sleep 30
|
995
|
+
# this may fail if the FW is still stopping
|
996
|
+
client.destroy_vsys(client.extract_vsys_id(opts[:id]))
|
997
|
+
rescue Exception => ex
|
998
|
+
raise unless attempts < 20 and ex.message =~ /SERVER_RUNNING.*/
|
999
|
+
# Stopping takes a few minutes, so keep trying for a while
|
1000
|
+
attempts += 1
|
1001
|
+
retry
|
1002
|
+
end
|
1003
|
+
}
|
1004
|
+
raise 'Firewall will be deleted once it has stopped'
|
951
1005
|
end
|
952
1006
|
end
|
953
1007
|
|
@@ -1050,7 +1104,7 @@ eofwopxml
|
|
1050
1104
|
realm = Realm::new(
|
1051
1105
|
:id => vserver['vnics'][0]['vnic'][0]['networkId'][0],
|
1052
1106
|
:name => realm_name,
|
1053
|
-
:limit => '[Network
|
1107
|
+
:limit => '[Network]',
|
1054
1108
|
:state => 'AVAILABLE' # map to state of FW/VSYS (reconfiguring = unavailable)?
|
1055
1109
|
)
|
1056
1110
|
balancer = LoadBalancer.new({
|
@@ -1085,7 +1139,7 @@ eofwopxml
|
|
1085
1139
|
realm = Realm::new(
|
1086
1140
|
:id => vserver['vnics'][0]['vnic'][0]['networkId'][0],
|
1087
1141
|
:name => realm_name,
|
1088
|
-
:limit => '[Network
|
1142
|
+
:limit => '[Network]',
|
1089
1143
|
:state => 'AVAILABLE' # map to state of FW/VSYS (reconfiguring = unavailable)?
|
1090
1144
|
)
|
1091
1145
|
balancer = LoadBalancer.new({
|
@@ -1143,6 +1197,12 @@ eofwopxml
|
|
1143
1197
|
# if opts['realm_id'].nil? network id specified, pick first vsys' DMZ?
|
1144
1198
|
# CreateEFM -vsysId vsysId -efmType SLB -efmName opts['name'] -networkId opts['realm_id']
|
1145
1199
|
network_id = opts[:realm_id]
|
1200
|
+
if not network_id
|
1201
|
+
xml = client.list_vsys['vsyss']
|
1202
|
+
|
1203
|
+
# use first returned system's DMZ as realm
|
1204
|
+
network_id = xml ? xml[0]['vsys'][0]['vsysId'][0] + '-N-DMZ' : nil
|
1205
|
+
end
|
1146
1206
|
efm = client.create_efm('SLB', opts[:name], network_id)
|
1147
1207
|
# [{:load_balancer_port => opts['listener_balancer_port'],
|
1148
1208
|
# :instance_port => opts['listener_instance_port'],
|
@@ -1214,7 +1274,12 @@ eofwopxml
|
|
1214
1274
|
def metric(credentials, opts={})
|
1215
1275
|
safely do
|
1216
1276
|
client = new_client(credentials)
|
1217
|
-
|
1277
|
+
begin
|
1278
|
+
perf = client.get_performance_information(opts[:id], 'hour')
|
1279
|
+
rescue Exception => ex
|
1280
|
+
return nil if ex.message =~ /RESOURCE_NOT_FOUND/
|
1281
|
+
raise
|
1282
|
+
end
|
1218
1283
|
|
1219
1284
|
metric = Metric.new(
|
1220
1285
|
:id => opts[:id],
|
@@ -1273,47 +1338,47 @@ eofwopxml
|
|
1273
1338
|
|
1274
1339
|
exceptions do
|
1275
1340
|
|
1341
|
+
# FW will be deleted in async polling thread, so can't guarantee successful completion
|
1342
|
+
on /Firewall will be deleted once it has stopped/ do
|
1343
|
+
status 202 # Accepted
|
1344
|
+
end
|
1345
|
+
|
1276
1346
|
on /ALREADY_STARTED/ do
|
1277
|
-
status 405
|
1347
|
+
status 405 # Method Not Allowed
|
1278
1348
|
end
|
1279
1349
|
|
1280
1350
|
# trying to start a running vserver, etc.
|
1281
1351
|
on /ILLEGAL_STATE/ do
|
1282
|
-
status 405
|
1352
|
+
status 405 # Method Not Allowed
|
1283
1353
|
end
|
1284
1354
|
|
1285
1355
|
on /AuthFailure/ do
|
1286
|
-
status 401
|
1356
|
+
status 401 # Unauthorized
|
1287
1357
|
end
|
1288
1358
|
|
1289
1359
|
# User not found: using certificate with wrong region
|
1290
1360
|
on /User not found in selectData./ do
|
1291
|
-
status 401
|
1361
|
+
status 401 # Unauthorized
|
1292
1362
|
end
|
1293
1363
|
|
1294
1364
|
# if user doesn't have privileges to view or operate a particular resource
|
1295
1365
|
on /User doesn.t have the right of access./ do
|
1296
|
-
status
|
1297
|
-
end
|
1298
|
-
|
1299
|
-
# time out of sync with ntp
|
1300
|
-
on /VALIDATION_ERROR.*synchronized.*API-Server time/ do
|
1301
|
-
status 502
|
1366
|
+
status 403 # Forbidden
|
1302
1367
|
end
|
1303
1368
|
|
1304
1369
|
# wrong vserverId, etc.
|
1305
1370
|
on /VALIDATION_ERROR/ do
|
1306
|
-
status 404
|
1371
|
+
status 404 # Not Found
|
1307
1372
|
end
|
1308
1373
|
|
1309
1374
|
# wrong vdiskId, etc.
|
1310
1375
|
on /RESOURCE_NOT_FOUND/ do
|
1311
|
-
status 404
|
1376
|
+
status 404 # Not Found
|
1312
1377
|
end
|
1313
1378
|
|
1314
1379
|
# wrong FW description (vsys descriptor)
|
1315
1380
|
on /does not exist. Specify one of / do
|
1316
|
-
status 404
|
1381
|
+
status 404 # Not Found
|
1317
1382
|
end
|
1318
1383
|
|
1319
1384
|
# trying an operation that is not supported (yet) by the target region
|
@@ -1321,19 +1386,24 @@ eofwopxml
|
|
1321
1386
|
status 501 # Not Implemented
|
1322
1387
|
end
|
1323
1388
|
|
1389
|
+
# time out of sync with ntp
|
1390
|
+
on /VALIDATION_ERROR.*synchronized.*API-Server time/ do
|
1391
|
+
status 502 # Bad Gateway
|
1392
|
+
end
|
1393
|
+
|
1324
1394
|
# destroying a running SLB, etc.
|
1325
1395
|
on /ALREADY_STARTED/ do
|
1326
|
-
status 502
|
1396
|
+
status 502 # Bad Gateway?
|
1327
1397
|
end
|
1328
1398
|
|
1329
1399
|
# trying to start a running vserver, etc.
|
1330
1400
|
on /ILLEGAL_STATE/ do
|
1331
|
-
status 502
|
1401
|
+
status 502 # Bad Gateway
|
1332
1402
|
end
|
1333
1403
|
|
1334
1404
|
# endpoint for country of certificate subject not found
|
1335
1405
|
on /API endpoint not found/ do
|
1336
|
-
status 502
|
1406
|
+
status 502 # Bad Gateway
|
1337
1407
|
end
|
1338
1408
|
|
1339
1409
|
on /.*/ do
|
@@ -1406,7 +1476,8 @@ eofwopxml
|
|
1406
1476
|
vsys_id = client.extract_vsys_id(instance.id)
|
1407
1477
|
if slbs = client.list_efm(vsys_id, 'SLB')['efms']
|
1408
1478
|
slbs[0]['efm'].find do |slb|
|
1409
|
-
|
1479
|
+
# note that slbVip may not be set yet (in just created SLBs)
|
1480
|
+
instance.private_addresses << InstanceAddress.new(slb['slbVip'][0], :type => :ipv4) if slb['slbVip'] and slb['efmId'][0] == instance.id
|
1410
1481
|
end
|
1411
1482
|
end
|
1412
1483
|
end
|