Class: Aviator::Session
- Defined in:
- lib/puppet/feature/aviator/core/session.rb
Overview
Manages a provider (e.g. OpenStack) session.
- Author
-
Mark Maglana (mmaglana@gmail.com)
- Copyright
-
Copyright © 2014 Mark Maglana
- License
-
Distributed under the MIT license
- Homepage
Defined Under Namespace
Classes: AuthenticationError, EnvironmentNotDefinedError, InitializationError, InvalidConfigFilePathError, NotAuthenticatedError, ValidatorNotDefinedError
Class Method Summary collapse
-
.load(session_dump, opts = {}) ⇒ Object
Creates a new Session object from a previous session’s dump.
Instance Method Summary collapse
-
#authenticate(&block) ⇒ Object
Authenticates against the auth_service request class declared in the session’s configuration during initialization.
-
#authenticated? ⇒ Boolean
Returns true if the session has been authenticated.
-
#config ⇒ Object
Returns its configuration.
-
#dump ⇒ Object
Returns a JSON string of its configuration and auth_data.
-
#initialize(opts = {}) ⇒ Session
constructor
Create a new Session instance with options provided in
opts
which can have many forms discussed below. -
#load(session_dump) ⇒ Object
Same as Session::load but re-uses the Session instance this method is called on instead of creating a new one.
-
#log_file ⇒ Object
Returns the log file path.
- #method_missing(name, *args, &block) ⇒ Object
-
#request(service_name, request_name, opts = {}, ¶ms) ⇒ Object
Calls the given request of the given service.
-
#validate ⇒ Object
Returns true if the session is still valid in the underlying provider.
Constructor Details
#initialize(opts = {}) ⇒ Session
Create a new Session instance with options provided in opts
which can have many forms discussed below.
Initialize with a config file
Aviator::Session.new(:config_file => 'path/to/aviator.yml', :environment => :production)
In the above example, the config file must have the following form:
production:
provider: openstack
auth_service:
name: identity
host_uri: 'http://my.openstackenv.org:5000'
request: create_token
validator: list_tenants
api_version: v2
auth_credentials:
username: myusername
password: mypassword
tenant_name: myproject
Once the session has been instantiated, you may authenticate against the provider as follows:
session.authenticate
Note that the required items under auth_credentials
in the config file depends on the required parameters of the request class declared under auth_service
. If writing the auth_credentials
in the config file is not acceptable, you may omit it and just supply the credentials at runtime. For instance, assume that the auth_credentials
section in the config file above is missing. You would then authenticate as follows:
session.authenticate do |params|
params.username = ARGV[0]
params.password = ARGV[1]
params.tenant_name = ARGV[2]
end
Please see Session#authenticate for more info.
Note that while the example config file above only has one environment (production), you can declare an arbitrary number of environments in your config file. Shifting between environments is as simple as changing the :environment
to refer to that.
Initialize with an in-memory hash
You can create an in-memory hash which is similar in structure to the config file except that you don’t need to specify an environment name. For example:
configuration = {
:provider => 'openstack',
:auth_service => {
:name => 'identity',
:host_uri => 'http://devstack:5000/v2.0',
:request => 'create_token',
:validator => 'list_tenants'
}
}
Supply this to the initializer using the :config
option. For example:
Aviator::Session.new(:config => configuration)
Initialize with a session dump
You can create a new Session instance using a dump from another instance. For example:
session_dump = session1.dump
session2 = Aviator::Session.new(:session_dump => session_dump)
However, Session.load is cleaner and recommended over this method.
Optionally supply a log file
In all forms above, you may optionally add a :log_file
option to make Aviator write all HTTP calls to the given path. For example:
Aviator::Session.new(:config_file => 'path/to/aviator.yml', :environment => :production, :log_file => 'path/to/log')
138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/puppet/feature/aviator/core/session.rb', line 138 def initialize(opts={}) if opts.has_key? :session_dump initialize_with_dump(opts[:session_dump]) elsif opts.has_key? :config_file initialize_with_config(opts[:config_file], opts[:environment]) elsif opts.has_key? :config initialize_with_hash(opts[:config]) else raise InitializationError.new end @log_file = opts[:log_file] end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
250 251 252 253 254 255 256 257 258 |
# File 'lib/puppet/feature/aviator/core/session.rb', line 250 def method_missing(name, *args, &block) service_name_parts = name.to_s.match(/^(\w+)_service$/) if service_name_parts get_service_obj(service_name_parts[1]) else super name, *args, &block end end |
Class Method Details
.load(session_dump, opts = {}) ⇒ Object
269 270 271 272 273 |
# File 'lib/puppet/feature/aviator/core/session.rb', line 269 def self.load(session_dump, opts={}) opts[:session_dump] = session_dump new(opts) end |
Instance Method Details
#authenticate(&block) ⇒ Object
Authenticates against the auth_service request class declared in the session’s configuration during initialization. Please see Session.new for more information on declaring the request class to use for authentication.
If the auth_service request class accepts a parameter block, you may also supply that when calling this method and it will be directly passed to the request. For example:
session = Aviator::Session.new(:config => config)
session.authenticate do |params|
params.username = username
params.password = password
params.tenant_name = project
end
Expects an HTTP status 200 or 201. Any other status is treated as a failure.
Note that you can also treat the block’s argument like a hash with the attribute names as the keys. For example, we can rewrite the above as:
session = Aviator::Session.new(:config => config)
session.authenticate do |params|
params[:username] = username
params[:password] = password
params[:tenant_name] = project
end
Keys can be symbols or strings.
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/puppet/feature/aviator/core/session.rb', line 181 def authenticate(&block) block ||= lambda do |params| config[:auth_credentials].each do |key, value| begin params[key] = value rescue NameError => e raise NameError.new("Unknown param name '#{key}'") end end end response = auth_service.request config[:auth_service][:request].to_sym, &block if [200, 201].include? response.status @auth_response = Hashish.new({ :headers => response.headers, :body => response.body }) update_services_session_data else raise AuthenticationError.new(response.body) end self end |
#authenticated? ⇒ Boolean
Returns true if the session has been authenticated.
209 210 211 |
# File 'lib/puppet/feature/aviator/core/session.rb', line 209 def authenticated? !auth_response.nil? end |
#config ⇒ Object
Returns its configuration.
216 217 218 |
# File 'lib/puppet/feature/aviator/core/session.rb', line 216 def config @config end |
#dump ⇒ Object
231 232 233 234 235 236 |
# File 'lib/puppet/feature/aviator/core/session.rb', line 231 def dump JSON.generate({ :config => config, :auth_response => auth_response }) end |
#load(session_dump) ⇒ Object
Same as Session::load but re-uses the Session instance this method is called on instead of creating a new one.
243 244 245 246 247 |
# File 'lib/puppet/feature/aviator/core/session.rb', line 243 def load(session_dump) initialize_with_dump(session_dump) update_services_session_data self end |
#log_file ⇒ Object
Returns the log file path. May be nil if none was provided during initialization.
279 280 281 |
# File 'lib/puppet/feature/aviator/core/session.rb', line 279 def log_file @log_file end |
#request(service_name, request_name, opts = {}, ¶ms) ⇒ Object
Calls the given request of the given service. An example call might look like:
session.request :compute_service, :create_server do |p|
p.name = "My Server"
p.image_ref = "7cae8c8e-fb01-4a88-bba3-ae0fcb1dbe29"
p.flavor_ref = "fa283da1-59a5-4245-8569-b6eadf69f10b"
end
Note that you can also treat the block’s argument like a hash with the attribute names as the keys. For example, we can rewrite the above as:
session.request :compute_service, :create_server do |p|
p[:name] = "My Server"
p[:image_ref] = "7cae8c8e-fb01-4a88-bba3-ae0fcb1dbe29"
p[:flavor_ref] = "fa283da1-59a5-4245-8569-b6eadf69f10b"
end
Keys can be symbols or strings.
Request Options
You can further customize how the request is fulfilled by providing one or more options to the method call. For example, the following ensures that the request will call the :create_server request for the v1 API.
session.request :compute_service, :create_server, :api_version => v1
The available options vary depending on the provider. See the documentation on the provider’s Provider class for more information (e.g. Aviator::OpenStack::Provider)
317 318 319 320 |
# File 'lib/puppet/feature/aviator/core/session.rb', line 317 def request(service_name, request_name, opts={}, ¶ms) service = send("#{service_name.to_s}_service") service.request(request_name, opts, ¶ms) end |
#validate ⇒ Object
Returns true if the session is still valid in the underlying provider. This method does this by calling the validator request class declared declared under auth_service
in the configuration. The validator can be any request class as long as:
-
The request class exists!
-
Does not require any parameters
-
It returns an HTTP status 200 or 203 to indicate auth info validity.
-
It returns any other HTTP status to indicate that the auth info is invalid.
See Session::new for an example on how to specify the request class to use for session validation.
335 336 337 338 339 340 341 342 343 |
# File 'lib/puppet/feature/aviator/core/session.rb', line 335 def validate raise NotAuthenticatedError.new unless authenticated? raise ValidatorNotDefinedError.new unless config[:auth_service][:validator] auth_with_bootstrap = auth_response.merge({ :auth_service => config[:auth_service] }) response = auth_service.request config[:auth_service][:validator].to_sym, :session_data => auth_with_bootstrap response.status == 200 || response.status == 203 end |