lib/providers/openstack/openstack.rb in lorj-1.0.3 vs lib/providers/openstack/openstack.rb in lorj-1.0.4
- old
+ new
@@ -14,32 +14,289 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# This class describes how to process some actions, and will do everything prior
# this task to make it to work.
-class Openstack < BaseDefinition
- def initialize
- superclass.provides([:compute, :network])
+require 'fog'
+require 'uri'
+
+hpcloud_path = File.expand_path(File.dirname(__FILE__))
+
+require File.join(hpcloud_path, 'openstack_query.rb')
+require File.join(hpcloud_path, 'openstack_get.rb')
+require File.join(hpcloud_path, 'openstack_delete.rb')
+require File.join(hpcloud_path, 'openstack_create.rb')
+require File.join(hpcloud_path, 'openstack_update.rb')
+
+# Defines Meta Openstack object
+class Openstack
+ process_default :use_controller => true
+
+ define_obj :services
+ # Define Data used by service
+
+ obj_needs :data, :account_id, :mapping => :openstack_username
+ obj_needs :data, :account_key, :mapping => :openstack_api_key
+ obj_needs :data, :auth_uri, :mapping => :openstack_auth_uri
+ obj_needs :data, :tenant, :mapping => :openstack_tenant
+ obj_needs :data, ':excon_opts/:connect_timeout', :default_value => 30
+ obj_needs :data, ':excon_opts/:read_timeout', :default_value => 240
+ obj_needs :data, ':excon_opts/:write_timeout', :default_value => 240
+
+ define_obj :compute_connection
+ # Defines Data used by compute.
+
+ obj_needs :data, :account_id, :mapping => :openstack_username
+ obj_needs :data, :account_key, :mapping => :openstack_api_key,
+ :decrypt => true
+ obj_needs :data, :auth_uri, :mapping => :openstack_auth_url
+ obj_needs :data, :tenant, :mapping => :openstack_tenant
+ obj_needs :data, :compute, :mapping => :openstack_region
+
+ define_obj :network_connection
+ obj_needs :data, :account_id, :mapping => :openstack_username
+ obj_needs :data, :account_key, :mapping => :openstack_api_key,
+ :decrypt => true
+ obj_needs :data, :auth_uri, :mapping => :openstack_auth_url
+ obj_needs :data, :tenant, :mapping => :openstack_tenant
+ obj_needs :data, :network, :mapping => :openstack_region
+
+ # Openstack tenants object
+ define_obj(:tenants, :create_e => :openstack_get_tenant)
+ obj_needs :CloudObject, :compute_connection
+ obj_needs :data, :tenant
+
+ # Openstack Network
+ define_obj :network
+ def_hdata :network_name, :mapping => :name
+ def_attr_mapping :external, :router_external
+
+ define_obj :keypairs
+
+ undefine_attribute :id # Do not return any predefined ID
+
+ define_obj :server_log
+
+ # Excon::Response object type
+ def_attr_mapping :output, 'output'
+
+ define_obj :security_groups
+ # Added tenant data to add in queries.
+ obj_needs :CloudObject, :tenants
+
+ define_obj :rule
+ obj_needs :data, :dir, :mapping => :direction
+ attr_value_mapping :IN, 'ingress'
+ attr_value_mapping :OUT, 'egress'
+
+ obj_needs :data, :proto, :mapping => :protocol
+ obj_needs :data, :port_min, :mapping => :port_range_min
+ obj_needs :data, :port_max, :mapping => :port_range_max
+ obj_needs :data, :addr_map, :mapping => :remote_ip_prefix
+ obj_needs :data, :sg_id, :mapping => :security_group_id
+
+ def_attr_mapping :dir, :direction
+ def_attr_mapping :proto, :protocol
+ def_attr_mapping :port_min, :port_range_min
+ def_attr_mapping :port_max, :port_range_max
+ def_attr_mapping :addr_map, :remote_ip_prefix
+ def_attr_mapping :sg_id, :security_group_id
+
+ define_data(:account_id,
+ :account => true,
+ :desc => 'Openstack Username',
+ :validate => /^.+/
+ )
+
+ define_data(:account_key,
+ :account => true,
+ :desc => 'Openstack Password',
+ :validate => /^.+/
+ )
+ define_data(:auth_uri,
+ :account => true,
+ :explanation => "The authentication service is identified as '"\
+ "identity' under your horizon UI - Project/Compute then "\
+ 'Access & security.',
+ :desc => 'Openstack Authentication service URL. '\
+ 'Ex: https://mycloud:5000/v2.0/tokens',
+ :validate => %r{^http(s)?:\/\/.*\/tokens$}
+ )
+ define_data(:tenant,
+ :account => true,
+ :explanation => 'The Project name is shown from your horizon UI'\
+ ', on top left, close to the logo',
+ :desc => 'Openstack Tenant Name',
+ :validate => /^.+/
+ )
+
+ define_data(:compute,
+ :account => true,
+ :explanation => 'Depending on your installation, you may need to'\
+ ' provide a Region name. This information shown under your '\
+ 'horizon UI - close right to the project name (top left).'\
+ "\nIf there is no region shown, you can ignore it.",
+ :desc => 'Openstack Compute Region (Ex: regionOne)'
+ )
+
+ define_data(:network,
+ :account => true,
+ :desc => 'Openstack Network Region (Ex: regionOne)',
+ :explanation => 'Depending on your installation, you may need to'\
+ ' provide a Region name. This information shown under your '\
+ 'horizon UI - close right to the project name (top left).'\
+ "\nIf there is no region shown, you can ignore it."
+ )
+
+ define_obj :server
+ def_attr_mapping :status, :state
+ attr_value_mapping :create, 'BUILD'
+ attr_value_mapping :boot, :boot
+ attr_value_mapping :active, 'ACTIVE'
+ attr_value_mapping :active, 'ACTIVE'
+
+ def_attr_mapping :private_ip_address, :accessIPv4
+ def_attr_mapping :public_ip_address, :accessIPv4
+ def_attr_mapping :image_id, [:image, 'id']
+
+ define_obj :router
+ obj_needs_optional
+ obj_needs :data, :router_name, :mapping => :name
+
+ # The FORJ gateway_network_id is extracted
+ # from Fog::HP::Network::Router[:external_gateway_info][:network_id]
+
+ obj_needs :data,
+ :external_gateway_id,
+ :mapping => [:external_gateway_info, 'network_id']
+
+ def_attr_mapping :gateway_network_id, [:external_gateway_info, 'network_id']
+
+ # Port attributes used specifically by openstack fog API.
+ define_obj :port
+ def_attribute :device_owner
+ def_attribute :network_id
+
+ define_obj :public_ip
+ def_attr_mapping :server_id, :instance_id
+ def_attr_mapping :public_ip, :ip
+
+ define_obj :image
+ def_attr_mapping :image_name, :name
+end
+
+# Following class describe how FORJ should handle Openstack Cloud objects.
+class OpenstackController
+ def self.def_cruds(*crud_types)
+ crud_types.each do |crud_type|
+ case crud_type
+ when :create, :delete
+ base_method(crud_type)
+ when :query, :get
+ query_method(crud_type)
+ when :update
+ update_method(crud_type)
+ end
+ end
end
- def compute
- Fog::Compute.new(
- :provider => :openstack,
- :openstack_api_key => superclass.oForjAccount.get(:account_id),
- :openstack_username => superclass.oForjAccount.get(:account_key),
- :openstack_auth_url => superclass.oForjAccount.get(:auth_uri),
- :openstack_tenant => superclass.oForjAccount.get(:tenant_id),
- :openstack_region => superclass.oForjAccount.get(:compute)
- )
+ def self.update_method(crud_type)
+ define_method(crud_type) do |sObjectType, obj, hParams|
+ method_name = "#{crud_type}_#{sObjectType}"
+ if self.class.method_defined? method_name
+ send(method_name, obj, hParams)
+ else
+ controller_error "'%s' is not a valid object for '%s'",
+ sObjectType, crud_type
+ end
+ end
end
- def network
- Fog::Network.new(
- :provider => :openstack,
- :openstack_api_key => superclass.oForjAccount.get(:account_id),
- :openstack_username => superclass.oForjAccount.get(:account_key),
- :openstack_auth_url => superclass.oForjAccount.get(:auth_uri),
- :openstack_tenant => superclass.oForjAccount.get(:tenant_id),
- :openstack_region => superclass.oForjAccount.get(:network)
- )
+ def self.query_method(crud_type)
+ define_method(crud_type) do |sObjectType, sCondition, hParams|
+ method_name = "#{crud_type}_#{sObjectType}"
+ if self.class.method_defined? method_name
+ send(method_name, hParams, sCondition)
+ else
+ controller_error "'%s' is not a valid object for '%s'",
+ sObjectType, crud_type
+ end
+ end
+ end
+
+ def self.base_method(crud_type)
+ define_method(crud_type) do |sObjectType, hParams|
+ method_name = "#{crud_type}_#{sObjectType}"
+ if self.class.method_defined? method_name
+ send(method_name, hParams)
+ else
+ controller_error "'%s' is not a valid object for '%s'",
+ sObjectType, crud_type
+ end
+ end
+ end
+
+ # Define the Openstack controller handlers
+ def_cruds :create, :delete, :get, :query, :update
+
+ def connect(sObjectType, hParams)
+ case sObjectType
+ when :services
+ # Fog use URI type for auth uri: URI.parse(:auth_uri)
+ # Convert openstack_auth_uri to type URI
+ hParams[:hdata][:openstack_auth_uri] =
+ URI.parse(hParams[:hdata][:openstack_auth_uri])
+ retrieve_result =
+ Fog::OpenStack.retrieve_tokens_v2(hParams[:hdata],
+ hParams[:excon_opts])
+ creds = format_retrieve_result(retrieve_result)
+ return creds
+ when :compute_connection
+ Fog::Compute.new(
+ hParams[:hdata].merge(:provider => :openstack)
+ )
+ when :network_connection
+ Fog::Network::OpenStack.new(hParams[:hdata])
+ else
+ controller_error "'%s' is not a valid object for 'connect'", sObjectType
+ end
+ end
+
+ def set_attr(oControlerObject, key, value)
+ if oControlerObject.is_a?(Excon::Response)
+ controller_error "No set feature for '%s'", oControlerObject.class
+ end
+
+ attributes = oControlerObject.attributes
+
+ controller_error "attribute '%s' is unknown in '%s'. Valid one are : '%s'",
+ key[0],
+ oControlerObject.class,
+ oControlerObject.class.attributes unless
+ oControlerObject.class.attributes.include?(key[0])
+
+ attributes.rh_set(value, key)
+ rescue => e
+ controller_error "Unable to map '%s' on '%s'. %s",
+ key, oControlerObject, e.message
+ end
+
+ def get_attr(oControlerObject, key)
+ if oControlerObject.is_a?(Excon::Response)
+ oControlerObject.data.rh_get(:body, key)
+ else
+ attributes = oControlerObject.attributes
+ controller_error "attribute '%s' is unknown in '%s'."\
+ " Valid one are : '%s'",
+ key[0],
+ oControlerObject.class,
+ oControlerObject.class.attributes unless
+ oControlerObject.class.attributes.include?(key[0])
+
+ return attributes.rh_get(key) if attributes.rh_exist?(key)
+ return oControlerObject.send(key[0]) if key.length == 1
+ oControlerObject.send(key[0]).rh_get(key[1..-1])
+ end
+ rescue => e
+ controller_error "==>Unable to map '%s'. %s", key, e.message
end
end