lorj 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/example/students_1/students.rb +5 -6
  3. data/example/students_2/students.rb +4 -5
  4. data/example/students_3/students.rb +4 -5
  5. data/example/students_4/students.rb +4 -5
  6. data/example/students_5/students.rb +5 -5
  7. data/lib/core/core.rb +6 -1
  8. data/lib/core/core_controller.rb +1 -9
  9. data/lib/core/core_internal.rb +2 -1
  10. data/lib/core/core_model.rb +2 -10
  11. data/lib/core/core_object_data.rb +18 -0
  12. data/lib/core/core_object_params.rb +43 -4
  13. data/lib/core/core_process.rb +1 -9
  14. data/lib/core/core_process_setup.rb +32 -6
  15. data/lib/core/core_setup_ask.rb +41 -33
  16. data/lib/core/core_setup_encrypt.rb +29 -6
  17. data/lib/core/core_setup_init.rb +2 -2
  18. data/lib/core/definition.rb +33 -10
  19. data/lib/core/definition_internal.rb +10 -14
  20. data/lib/core/lorj_basedefinition.rb +16 -24
  21. data/lib/core/lorj_baseprocess.rb +113 -44
  22. data/lib/core/lorj_data.rb +2 -9
  23. data/lib/core/lorj_keypath.rb +5 -2
  24. data/lib/core_process/cloud/process/common.rb +4 -7
  25. data/lib/core_process/cloud/process/connection.rb +44 -45
  26. data/lib/core_process/cloud/process/external_network.rb +24 -28
  27. data/lib/core_process/cloud/process/flavor.rb +31 -34
  28. data/lib/core_process/cloud/process/images.rb +12 -15
  29. data/lib/core_process/cloud/process/internet_network.rb +13 -14
  30. data/lib/core_process/cloud/process/internet_server.rb +9 -10
  31. data/lib/core_process/cloud/process/keypairs.rb +34 -27
  32. data/lib/core_process/cloud/process/network.rb +21 -23
  33. data/lib/core_process/cloud/process/public_ip.rb +17 -18
  34. data/lib/core_process/cloud/process/router.rb +86 -92
  35. data/lib/core_process/cloud/process/rules.rb +30 -31
  36. data/lib/core_process/cloud/process/security_groups.rb +21 -22
  37. data/lib/core_process/cloud/process/server.rb +30 -31
  38. data/lib/core_process/cloud/process/server_log.rb +13 -14
  39. data/lib/core_process/cloud/process/subnetwork.rb +25 -40
  40. data/lib/logging.rb +4 -17
  41. data/lib/lorj/version.rb +1 -1
  42. data/lib/lorj.rb +2 -1
  43. data/lib/lorj_account.rb +137 -90
  44. data/lib/lorj_config.rb +13 -19
  45. data/lib/lorj_defaults.rb +46 -292
  46. data/lib/lorj_meta.rb +729 -0
  47. data/lib/prc.rb +119 -30
  48. data/lib/prc_base_config.rb +53 -47
  49. data/lib/prc_core_config.rb +837 -565
  50. data/lib/prc_section_config.rb +44 -16
  51. data/lib/providers/hpcloud/hpcloud.rb +1 -1
  52. data/lib/providers/openstack/openstack.rb +278 -21
  53. data/lib/providers/openstack/openstack_create.rb +205 -0
  54. data/lib/providers/openstack/openstack_delete.rb +28 -0
  55. data/lib/providers/openstack/openstack_get.rb +39 -0
  56. data/lib/providers/openstack/openstack_process.rb +26 -0
  57. data/lib/providers/openstack/openstack_query.rb +96 -0
  58. data/lib/providers/openstack/openstack_update.rb +35 -0
  59. data/lib/rh.rb +91 -6
  60. data/lorj-spec/defaults.yaml +18 -12
  61. data/lorj.gemspec +1 -0
  62. data/spec/01_hash_rh_spec.rb +41 -2
  63. data/spec/02_prc_base_config_spec.rb +1 -1
  64. data/spec/03_prc_section_config_spec.rb +1 -1
  65. data/spec/04_prc_core_config_spec.rb +148 -4
  66. data/spec/09_prc_spec.rb +104 -0
  67. data/spec/{00_lorj_log_spec.rb → 10_lorj_log_spec.rb} +23 -2
  68. data/spec/11_lorj_config_spec.rb +9 -27
  69. data/spec/12_lorj_account_spec.rb +36 -20
  70. data/spec/20_lorj_meta_spec.rb +271 -0
  71. data/spec/21_lorj_defaults_spec.rb +85 -0
  72. metadata +31 -4
@@ -18,45 +18,73 @@ require 'rubygems'
18
18
  require 'yaml'
19
19
 
20
20
  module PRC
21
- # SectionConfig class layer
21
+ # SectionConfig class layer based on BaseConfig.
22
+ #
23
+ # It supports a data_options :section for #[], #[]=, etc...
24
+ #
22
25
  class SectionConfig < PRC::BaseConfig
23
26
  # Get the value of a specific key under a section.
27
+ # You have to call #data_options(:section => 'MySection')
24
28
  #
25
29
  # * *Args* :
26
30
  # - +keys+ : keys to get values from a section set by data_options.
27
- # If section is set, it will use :default
31
+ # If section is not set, it will use :default
28
32
  # * *Returns* :
29
33
  # - key value.
30
34
  # * *Raises* :
31
35
  # Nothing
32
36
  def [](*keys)
33
37
  return nil if keys.length == 0
34
- return _get(:default, *keys) if @data_options[:section].nil?
35
- _get(@data_options[:section], *keys)
38
+ return p_get(:default, *keys) if @data_options[:section].nil?
39
+ p_get(@data_options[:section], *keys)
36
40
  end
37
41
 
42
+ # Set the value of a specific key under a section.
43
+ # You have to call #data_options(:section => 'MySection')
44
+ #
45
+ # * *Args* :
46
+ # - +keys+ : keys to get values from a section set by data_options.
47
+ # If section is not set, it will use :default
48
+ # * *Returns* :
49
+ # - key value.
50
+ # * *Raises* :
51
+ # Nothing
38
52
  def []=(*keys, value)
39
53
  return nil if keys.length == 0
40
- return _set(:default, *keys, value) if @data_options[:section].nil?
41
- _set(@data_options[:section], *keys, value)
54
+ return p_set(:default, *keys, value) if @data_options[:section].nil?
55
+ p_set(@data_options[:section], *keys, value)
42
56
  end
43
57
 
58
+ # Check key existence under a section.
59
+ # You have to call #data_options(:section => 'MySection')
60
+ #
61
+ # * *Args* :
62
+ # - +keys+ : keys to get values from a section set by data_options.
63
+ # If section is not set, it will use :default
64
+ # * *Returns* :
65
+ # - key value.
66
+ # * *Raises* :
67
+ # Nothing
44
68
  def exist?(*keys)
45
69
  return nil if keys.length == 0
46
- return _exist?(:default, *keys) if @data_options[:section].nil?
47
- _exist?(@data_options[:section], *keys)
48
- end
49
-
50
- def where?(*keys)
51
- return nil if keys.length == 0
52
- return _exist?(:default, *keys) if @data_options[:section].nil?
53
- _where?(@data_options[:section], *keys)
70
+ return p_exist?(:default, *keys) if @data_options[:section].nil?
71
+ p_exist?(@data_options[:section], *keys)
54
72
  end
55
73
 
74
+ # remove the key under a section.
75
+ # You have to call #data_options(:section => 'MySection')
76
+ #
77
+ # * *Args* :
78
+ # - +keys+ : keys to get values from a section set by data_options.
79
+ # If section is not set, it will use :default
80
+ # * *Returns* :
81
+ # - key value.
82
+ # * *Raises* :
83
+ # Nothing
56
84
  def del(*keys)
57
85
  return nil if keys.length == 0
58
- return _del(:default, *keys) if @data_options[:section].nil?
59
- _del(@data_options[:section], *keys)
86
+ return p_del(:default, *keys) if @data_options[:section].nil?
87
+ p_del(@data_options[:section], *keys)
60
88
  end
61
89
  end
62
90
  end
@@ -61,7 +61,7 @@ class Hpcloud
61
61
  # If the query is not push through and Hash object, the Provider
62
62
  # will needs to create his own mapping function.
63
63
  define_obj :network
64
- query_mapping :external, :router_external
64
+ def_attr_mapping :external, :router_external
65
65
 
66
66
  define_obj :rule
67
67
  obj_needs :data, :dir, :mapping => :direction
@@ -16,30 +16,287 @@
16
16
 
17
17
  # This class describes how to process some actions, and will do everything prior
18
18
  # this task to make it to work.
19
- class Openstack < BaseDefinition
20
- def initialize
21
- superclass.provides([:compute, :network])
19
+ require 'fog'
20
+ require 'uri'
21
+
22
+ hpcloud_path = File.expand_path(File.dirname(__FILE__))
23
+
24
+ require File.join(hpcloud_path, 'openstack_query.rb')
25
+ require File.join(hpcloud_path, 'openstack_get.rb')
26
+ require File.join(hpcloud_path, 'openstack_delete.rb')
27
+ require File.join(hpcloud_path, 'openstack_create.rb')
28
+ require File.join(hpcloud_path, 'openstack_update.rb')
29
+
30
+ # Defines Meta Openstack object
31
+ class Openstack
32
+ process_default :use_controller => true
33
+
34
+ define_obj :services
35
+ # Define Data used by service
36
+
37
+ obj_needs :data, :account_id, :mapping => :openstack_username
38
+ obj_needs :data, :account_key, :mapping => :openstack_api_key
39
+ obj_needs :data, :auth_uri, :mapping => :openstack_auth_uri
40
+ obj_needs :data, :tenant, :mapping => :openstack_tenant
41
+ obj_needs :data, ':excon_opts/:connect_timeout', :default_value => 30
42
+ obj_needs :data, ':excon_opts/:read_timeout', :default_value => 240
43
+ obj_needs :data, ':excon_opts/:write_timeout', :default_value => 240
44
+
45
+ define_obj :compute_connection
46
+ # Defines Data used by compute.
47
+
48
+ obj_needs :data, :account_id, :mapping => :openstack_username
49
+ obj_needs :data, :account_key, :mapping => :openstack_api_key,
50
+ :decrypt => true
51
+ obj_needs :data, :auth_uri, :mapping => :openstack_auth_url
52
+ obj_needs :data, :tenant, :mapping => :openstack_tenant
53
+ obj_needs :data, :compute, :mapping => :openstack_region
54
+
55
+ define_obj :network_connection
56
+ obj_needs :data, :account_id, :mapping => :openstack_username
57
+ obj_needs :data, :account_key, :mapping => :openstack_api_key,
58
+ :decrypt => true
59
+ obj_needs :data, :auth_uri, :mapping => :openstack_auth_url
60
+ obj_needs :data, :tenant, :mapping => :openstack_tenant
61
+ obj_needs :data, :network, :mapping => :openstack_region
62
+
63
+ # Openstack tenants object
64
+ define_obj(:tenants, :create_e => :openstack_get_tenant)
65
+ obj_needs :CloudObject, :compute_connection
66
+ obj_needs :data, :tenant
67
+
68
+ # Openstack Network
69
+ define_obj :network
70
+ def_hdata :network_name, :mapping => :name
71
+ def_attr_mapping :external, :router_external
72
+
73
+ define_obj :keypairs
74
+
75
+ undefine_attribute :id # Do not return any predefined ID
76
+
77
+ define_obj :server_log
78
+
79
+ # Excon::Response object type
80
+ def_attr_mapping :output, 'output'
81
+
82
+ define_obj :security_groups
83
+ # Added tenant data to add in queries.
84
+ obj_needs :CloudObject, :tenants
85
+
86
+ define_obj :rule
87
+ obj_needs :data, :dir, :mapping => :direction
88
+ attr_value_mapping :IN, 'ingress'
89
+ attr_value_mapping :OUT, 'egress'
90
+
91
+ obj_needs :data, :proto, :mapping => :protocol
92
+ obj_needs :data, :port_min, :mapping => :port_range_min
93
+ obj_needs :data, :port_max, :mapping => :port_range_max
94
+ obj_needs :data, :addr_map, :mapping => :remote_ip_prefix
95
+ obj_needs :data, :sg_id, :mapping => :security_group_id
96
+
97
+ def_attr_mapping :dir, :direction
98
+ def_attr_mapping :proto, :protocol
99
+ def_attr_mapping :port_min, :port_range_min
100
+ def_attr_mapping :port_max, :port_range_max
101
+ def_attr_mapping :addr_map, :remote_ip_prefix
102
+ def_attr_mapping :sg_id, :security_group_id
103
+
104
+ define_data(:account_id,
105
+ :account => true,
106
+ :desc => 'Openstack Username',
107
+ :validate => /^.+/
108
+ )
109
+
110
+ define_data(:account_key,
111
+ :account => true,
112
+ :desc => 'Openstack Password',
113
+ :validate => /^.+/
114
+ )
115
+ define_data(:auth_uri,
116
+ :account => true,
117
+ :explanation => "The authentication service is identified as '"\
118
+ "identity' under your horizon UI - Project/Compute then "\
119
+ 'Access & security.',
120
+ :desc => 'Openstack Authentication service URL. '\
121
+ 'Ex: https://mycloud:5000/v2.0/tokens',
122
+ :validate => %r{^http(s)?:\/\/.*\/tokens$}
123
+ )
124
+ define_data(:tenant,
125
+ :account => true,
126
+ :explanation => 'The Project name is shown from your horizon UI'\
127
+ ', on top left, close to the logo',
128
+ :desc => 'Openstack Tenant Name',
129
+ :validate => /^.+/
130
+ )
131
+
132
+ define_data(:compute,
133
+ :account => true,
134
+ :explanation => 'Depending on your installation, you may need to'\
135
+ ' provide a Region name. This information shown under your '\
136
+ 'horizon UI - close right to the project name (top left).'\
137
+ "\nIf there is no region shown, you can ignore it.",
138
+ :desc => 'Openstack Compute Region (Ex: regionOne)'
139
+ )
140
+
141
+ define_data(:network,
142
+ :account => true,
143
+ :desc => 'Openstack Network Region (Ex: regionOne)',
144
+ :explanation => 'Depending on your installation, you may need to'\
145
+ ' provide a Region name. This information shown under your '\
146
+ 'horizon UI - close right to the project name (top left).'\
147
+ "\nIf there is no region shown, you can ignore it."
148
+ )
149
+
150
+ define_obj :server
151
+ def_attr_mapping :status, :state
152
+ attr_value_mapping :create, 'BUILD'
153
+ attr_value_mapping :boot, :boot
154
+ attr_value_mapping :active, 'ACTIVE'
155
+ attr_value_mapping :active, 'ACTIVE'
156
+
157
+ def_attr_mapping :private_ip_address, :accessIPv4
158
+ def_attr_mapping :public_ip_address, :accessIPv4
159
+ def_attr_mapping :image_id, [:image, 'id']
160
+
161
+ define_obj :router
162
+ obj_needs_optional
163
+ obj_needs :data, :router_name, :mapping => :name
164
+
165
+ # The FORJ gateway_network_id is extracted
166
+ # from Fog::HP::Network::Router[:external_gateway_info][:network_id]
167
+
168
+ obj_needs :data,
169
+ :external_gateway_id,
170
+ :mapping => [:external_gateway_info, 'network_id']
171
+
172
+ def_attr_mapping :gateway_network_id, [:external_gateway_info, 'network_id']
173
+
174
+ # Port attributes used specifically by openstack fog API.
175
+ define_obj :port
176
+ def_attribute :device_owner
177
+ def_attribute :network_id
178
+
179
+ define_obj :public_ip
180
+ def_attr_mapping :server_id, :instance_id
181
+ def_attr_mapping :public_ip, :ip
182
+
183
+ define_obj :image
184
+ def_attr_mapping :image_name, :name
185
+ end
186
+
187
+ # Following class describe how FORJ should handle Openstack Cloud objects.
188
+ class OpenstackController
189
+ def self.def_cruds(*crud_types)
190
+ crud_types.each do |crud_type|
191
+ case crud_type
192
+ when :create, :delete
193
+ base_method(crud_type)
194
+ when :query, :get
195
+ query_method(crud_type)
196
+ when :update
197
+ update_method(crud_type)
198
+ end
199
+ end
200
+ end
201
+
202
+ def self.update_method(crud_type)
203
+ define_method(crud_type) do |sObjectType, obj, hParams|
204
+ method_name = "#{crud_type}_#{sObjectType}"
205
+ if self.class.method_defined? method_name
206
+ send(method_name, obj, hParams)
207
+ else
208
+ controller_error "'%s' is not a valid object for '%s'",
209
+ sObjectType, crud_type
210
+ end
211
+ end
22
212
  end
23
213
 
24
- def compute
25
- Fog::Compute.new(
26
- :provider => :openstack,
27
- :openstack_api_key => superclass.oForjAccount.get(:account_id),
28
- :openstack_username => superclass.oForjAccount.get(:account_key),
29
- :openstack_auth_url => superclass.oForjAccount.get(:auth_uri),
30
- :openstack_tenant => superclass.oForjAccount.get(:tenant_id),
31
- :openstack_region => superclass.oForjAccount.get(:compute)
32
- )
214
+ def self.query_method(crud_type)
215
+ define_method(crud_type) do |sObjectType, sCondition, hParams|
216
+ method_name = "#{crud_type}_#{sObjectType}"
217
+ if self.class.method_defined? method_name
218
+ send(method_name, hParams, sCondition)
219
+ else
220
+ controller_error "'%s' is not a valid object for '%s'",
221
+ sObjectType, crud_type
222
+ end
223
+ end
33
224
  end
34
225
 
35
- def network
36
- Fog::Network.new(
37
- :provider => :openstack,
38
- :openstack_api_key => superclass.oForjAccount.get(:account_id),
39
- :openstack_username => superclass.oForjAccount.get(:account_key),
40
- :openstack_auth_url => superclass.oForjAccount.get(:auth_uri),
41
- :openstack_tenant => superclass.oForjAccount.get(:tenant_id),
42
- :openstack_region => superclass.oForjAccount.get(:network)
43
- )
226
+ def self.base_method(crud_type)
227
+ define_method(crud_type) do |sObjectType, hParams|
228
+ method_name = "#{crud_type}_#{sObjectType}"
229
+ if self.class.method_defined? method_name
230
+ send(method_name, hParams)
231
+ else
232
+ controller_error "'%s' is not a valid object for '%s'",
233
+ sObjectType, crud_type
234
+ end
235
+ end
236
+ end
237
+
238
+ # Define the Openstack controller handlers
239
+ def_cruds :create, :delete, :get, :query, :update
240
+
241
+ def connect(sObjectType, hParams)
242
+ case sObjectType
243
+ when :services
244
+ # Fog use URI type for auth uri: URI.parse(:auth_uri)
245
+ # Convert openstack_auth_uri to type URI
246
+ hParams[:hdata][:openstack_auth_uri] =
247
+ URI.parse(hParams[:hdata][:openstack_auth_uri])
248
+ retrieve_result =
249
+ Fog::OpenStack.retrieve_tokens_v2(hParams[:hdata],
250
+ hParams[:excon_opts])
251
+ creds = format_retrieve_result(retrieve_result)
252
+ return creds
253
+ when :compute_connection
254
+ Fog::Compute.new(
255
+ hParams[:hdata].merge(:provider => :openstack)
256
+ )
257
+ when :network_connection
258
+ Fog::Network::OpenStack.new(hParams[:hdata])
259
+ else
260
+ controller_error "'%s' is not a valid object for 'connect'", sObjectType
261
+ end
262
+ end
263
+
264
+ def set_attr(oControlerObject, key, value)
265
+ if oControlerObject.is_a?(Excon::Response)
266
+ controller_error "No set feature for '%s'", oControlerObject.class
267
+ end
268
+
269
+ attributes = oControlerObject.attributes
270
+
271
+ controller_error "attribute '%s' is unknown in '%s'. Valid one are : '%s'",
272
+ key[0],
273
+ oControlerObject.class,
274
+ oControlerObject.class.attributes unless
275
+ oControlerObject.class.attributes.include?(key[0])
276
+
277
+ attributes.rh_set(value, key)
278
+ rescue => e
279
+ controller_error "Unable to map '%s' on '%s'. %s",
280
+ key, oControlerObject, e.message
281
+ end
282
+
283
+ def get_attr(oControlerObject, key)
284
+ if oControlerObject.is_a?(Excon::Response)
285
+ oControlerObject.data.rh_get(:body, key)
286
+ else
287
+ attributes = oControlerObject.attributes
288
+ controller_error "attribute '%s' is unknown in '%s'."\
289
+ " Valid one are : '%s'",
290
+ key[0],
291
+ oControlerObject.class,
292
+ oControlerObject.class.attributes unless
293
+ oControlerObject.class.attributes.include?(key[0])
294
+
295
+ return attributes.rh_get(key) if attributes.rh_exist?(key)
296
+ return oControlerObject.send(key[0]) if key.length == 1
297
+ oControlerObject.send(key[0]).rh_get(key[1..-1])
298
+ end
299
+ rescue => e
300
+ controller_error "==>Unable to map '%s'. %s", key, e.message
44
301
  end
45
302
  end
@@ -0,0 +1,205 @@
1
+ # encoding: UTF-8
2
+
3
+ # (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ # Defined Openstack object create.
18
+ class OpenstackController
19
+ def create_security_groups(hParams)
20
+ required?(hParams, :network_connection)
21
+ required?(hParams, :tenants)
22
+ required?(hParams, :security_group)
23
+
24
+ service = hParams[:network_connection]
25
+
26
+ service.security_groups.create(:name => hParams[:security_group],
27
+ :tenant_id => hParams[:tenants].id)
28
+ end
29
+
30
+ def create_network(hParams)
31
+ required?(hParams, :network_connection)
32
+ required?(hParams, :network_name)
33
+
34
+ hParams[:network_connection].networks.create(hParams[:hdata])
35
+ end
36
+
37
+ def create_subnetwork(hParams)
38
+ required?(hParams, :network_connection)
39
+ required?(hParams, :network)
40
+
41
+ netconn = hParams[:network_connection]
42
+ netconn.subnets.create(
43
+ :network_id => hParams[:network].id,
44
+ :name => hParams[:subnetwork_name],
45
+ :cidr => get_next_subnet(netconn),
46
+ :ip_version => '4'
47
+ )
48
+ end
49
+
50
+ def create_rule(hParams)
51
+ required?(hParams, :network_connection)
52
+ required?(hParams, :security_groups)
53
+ hParams[:network_connection].security_group_rules.create(hParams[:hdata])
54
+ end
55
+
56
+ def create_router(hParams)
57
+ required?(hParams, :network_connection)
58
+ required?(hParams, :router_name)
59
+
60
+ # Forcelly used admin_status_up to true. Coming from HPCloud.
61
+ # But not sure if we need it or not.
62
+ # hParams[:hdata] = hParams[:hdata].merge(:admin_state_up => true)
63
+
64
+ hParams[:network_connection].routers.create(hParams[:hdata])
65
+ end
66
+
67
+ def create_router_interface(hParams)
68
+ required?(hParams, :network_connection)
69
+ required?(hParams, :router)
70
+ required?(hParams, :subnetwork)
71
+
72
+ service = hParams[:network_connection]
73
+ router = hParams[:router]
74
+ result = service.add_router_interface(router.id, hParams[:subnetwork].id)
75
+ fail if result.status != 200
76
+ result
77
+ end
78
+
79
+ def create_keypairs(hParams)
80
+ required?(hParams, :compute_connection)
81
+ required?(hParams, :keypair_name)
82
+ required?(hParams, :public_key)
83
+
84
+ # API:
85
+ # https://github.com/fog/fog/blob/master/lib/fog/openstack/docs/compute.md
86
+ service = hParams[:compute_connection]
87
+ service.key_pairs.create(:name => hParams[:keypair_name],
88
+ :public_key => hParams[:public_key])
89
+ end
90
+
91
+ def create_server(hParams)
92
+ [:compute_connection, :image,
93
+ :network, :flavor, :keypairs,
94
+ :security_groups, :server_name].each do |required_param|
95
+ required?(hParams, required_param)
96
+ end
97
+
98
+ options = {
99
+ :name => hParams[:server_name],
100
+ :flavor_ref => hParams[:flavor].id,
101
+ :image_ref => hParams[:image].id,
102
+ :key_name => hParams[:keypairs].name,
103
+ :security_groups => [hParams[:security_groups].name],
104
+ :nics => [{ :net_id => hParams[:network].id }]
105
+ }
106
+
107
+ if hParams[:user_data]
108
+ options[:user_data_encoded] =
109
+ Base64.strict_encode64(hParams[:user_data])
110
+ end
111
+ options[:metadata] = hParams[:meta_data] if hParams[:meta_data]
112
+
113
+ compute_connect = hParams[:compute_connection]
114
+
115
+ server = compute_connect.servers.create(options)
116
+ compute_connect.servers.get(server.id) if server
117
+ end
118
+
119
+ def create_public_ip(hParams)
120
+ required?(hParams, :compute_connection)
121
+ required?(hParams, :server)
122
+
123
+ compute_connect = hParams[:compute_connection]
124
+ server = hParams[:server]
125
+
126
+ while server.state != 'ACTIVE'
127
+ sleep(5)
128
+ server = compute_connect.servers.get(server.id)
129
+ end
130
+
131
+ addresses = compute_connect.addresses.all
132
+ address = nil
133
+ # Search for an available IP
134
+ addresses.each do |elem|
135
+ if elem.fixed_ip.nil?
136
+ address = elem
137
+ break
138
+ end
139
+ end
140
+
141
+ address = allocate_new_ip(compute_connect) if address.nil?
142
+ if address.nil?
143
+ controller_error("No Public IP to assign to server '%s'", server.name)
144
+ end
145
+
146
+ address.server = server # associate the server
147
+ address.reload
148
+ # This function needs to returns a list of object.
149
+ # This list must support the each function.
150
+ address
151
+ end
152
+
153
+ def allocate_new_ip(compute_connect)
154
+ # Create a new public IP to add in the pool.
155
+ pools = compute_connect.addresses.get_address_pools
156
+ controller_error('No IP Pool found') if pools.length == 0
157
+ # TODO: Be able to support choice of pool at setup time.
158
+ if pools.length > 1
159
+ Lorj.warning('Several pools found. Selecting the first one.')
160
+ end
161
+ compute_connect.addresses.create 'pool' => pools[0]['name']
162
+ end
163
+
164
+ def get_next_subnet(oNetworkConnect)
165
+ subnet_values = []
166
+ subnets = oNetworkConnect.subnets.all
167
+
168
+ subnets.each do|s|
169
+ subnet_values.push(s.cidr)
170
+ end
171
+
172
+ gap = false
173
+ count = 0
174
+ range_used = []
175
+ new_subnet = 0
176
+ new_cidr = ''
177
+
178
+ subnet_values = subnet_values.sort!
179
+
180
+ subnet_values.each do|value|
181
+ range_used.push(value[5])
182
+ end
183
+
184
+ range_used.each do |n|
185
+ if count.to_i == n.to_i
186
+ else
187
+ new_subnet = count
188
+ gap = true
189
+ break
190
+ end
191
+ count += 1
192
+ end
193
+
194
+ if gap
195
+ new_cidr = format('10.0.%s.0/24', count)
196
+ else
197
+ max_value = range_used.max
198
+ new_subnet = max_value.to_i + 1
199
+ new_cidr = format('10.0.%s.0/24', new_subnet)
200
+ end
201
+ new_cidr
202
+ rescue => e
203
+ Logging.error("%s\n%s", e.message, e.backtrace.join("\n"))
204
+ end
205
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: UTF-8
2
+
3
+ # (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ # Defined Openstack object delete.
18
+ class OpenstackController
19
+ def delete_server(hParams)
20
+ required?(hParams, :compute_connection)
21
+ required?(hParams, :server)
22
+
23
+ compute_connect = hParams[:compute_connection]
24
+ server = hParams[:server]
25
+
26
+ compute_connect.servers.get(server.id).destroy
27
+ end
28
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: UTF-8
2
+
3
+ # (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ # Defined Openstack object get.
18
+ class OpenstackController
19
+ def self.def_get(connection, name, property_name = nil)
20
+ property_name = property_name.nil? ? "#{name}s" : property_name.to_s
21
+ define_method("get_#{name}") do |hParams, sUniqId|
22
+ required?(hParams, connection)
23
+ hParams[connection].send(property_name).get(sUniqId)
24
+ end
25
+ end
26
+
27
+ def_get :compute_connection, :server
28
+
29
+ def_get :compute_connection, :image
30
+
31
+ def_get :network_connection, :network
32
+
33
+ def_get :compute_connection, :keypairs, :key_pairs
34
+
35
+ def get_server_log(hParams, sUniqId)
36
+ required?(hParams, :server)
37
+ hParams[:server].console(sUniqId)
38
+ end
39
+ end