diff --git a/.fixtures.yml b/.fixtures.yml index d33ced52..4ae8866e 100644 --- a/.fixtures.yml +++ b/.fixtures.yml @@ -1,5 +1,6 @@ fixtures: repositories: + aviator: git://github.com/aimonb/puppet_aviator.git mysql: git://github.com/puppetlabs/puppetlabs-mysql.git stdlib: git://github.com/puppetlabs/puppetlabs-stdlib.git symlinks: diff --git a/.gitignore b/.gitignore index e2f8e338..8a0be9a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.swp -spec/fixtures/ +spec/fixtures/* +!spec/fixtures/vcr/ pkg Gemfile.lock diff --git a/Gemfile b/Gemfile index d965fa90..330d9ba5 100644 --- a/Gemfile +++ b/Gemfile @@ -4,9 +4,11 @@ group :development, :test do gem 'puppetlabs_spec_helper', :require => false gem 'puppet-lint', '~> 0.3.2' gem 'rake', '10.1.1' - gem 'rspec', '< 2.99' + gem 'rspec' + gem 'mocha' gem 'json' - gem 'webmock' + gem 'faraday', '0.8.8', :require => false + gem 'vcr', :require => false end if puppetversion = ENV['PUPPET_GEM_VERSION'] diff --git a/Modulefile b/Modulefile index 7c73b3ec..0043800c 100644 --- a/Modulefile +++ b/Modulefile @@ -7,5 +7,6 @@ summary 'Puppet Labs OpenStackLib Module' description 'Puppet module library to expose common functionality between OpenStack modules' project_page 'https://launchpad.net/puppet-openstacklib' +dependency 'aimonb/aviator', dependency 'puppetlabs/mysql', '>=2.2.0 <3.0.0' dependency 'puppetlabs/stdlib', '>=3.2.0' diff --git a/README.md b/README.md index fee75095..79fc5d69 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,61 @@ array or string; optional; default to undef Privileges given to the database user; string or array of strings; optional; default to 'ALL' +### Types and Providers + +#### Aviator + +#####`Puppet::add_aviator_params` + +The aviator type is not a real type, but it serves to simulate a mixin model, +whereby other types can call out to the Puppet::add\_aviator\_params method in +order to add aviator-specific parameters to themselves. Currently this adds the +auth parameter to the given type. The method must be called after the type is +declared, e.g.: + +```puppet +require 'puppet/type/aviator' +Puppet::Type.newtype(:my_type) do +# ... +end +Puppet::add_aviator_params(:my_type) +``` + +#####`Puppet::Provider::Aviator` + +The aviator provider is a parent provider intended to serve as a base for other +providers that need to authenticate against keystone in order to accomplish a +task. + +**`Puppet::Provider::Aviator#authenticate`** + +Either creates an authenticated session or sets up an unauthenticated session +with instance variables initialized with a token to inject into the next request. +It takes as arguments a set of authentication parameters as a hash and a path +to a log file. Puppet::Provider::Aviator#authencate looks for five different +possible methods of authenticating, in the following order: + +1) Username and password credentials in the auth parameters +2) The path to an openrc file containing credentials to read in the auth + parameters +3) A service token in the auth parameters +4) Environment variables set for the environment in which Puppet is running +5) A service token in /etc/keystone/keystone.conf. This option provides + backwards compatibility with earlier keystone providers. + +If the provider has password credentials, it can create an authenticated +session. If it only has a service token, it initializes an unauthenciated +session and a hash of session data that can be injected into a future request. + +**`Puppet::Provider::Aviator#make_request`** + +After creating a session, the make\_request method provides an interface that +providers can use to make requests without worrying about whether they have an +authenticated or unauthenticated session. It takes as arguments the +Aviator::Service it is making a request at (for example, keystone), a symbol for +the request (for example, :list\_tenants), and optionally a block to execute +that will set parameters for an update request. + Implementation -------------- diff --git a/lib/puppet/provider/aviator.rb b/lib/puppet/provider/aviator.rb new file mode 100644 index 00000000..8de1bf20 --- /dev/null +++ b/lib/puppet/provider/aviator.rb @@ -0,0 +1,297 @@ +require 'puppet' +require 'puppet/feature/aviator' +require 'puppet/util/inifile' + +class Puppet::Provider::Aviator < Puppet::Provider + + def session + @session ||= authenticate(resource[:auth], resource[:log_file]) + end + + def self.session + @session ||= authenticate(nil, nil) + end + + def request(service, request, &block) + self.class.make_request(service, request, session_data, &block) + end + + def self.request(service, request, &block) + self.make_request(service, request, session_data, &block) + end + + # needed for tests + def session_data + @session_data + end + + def self.session_data + @session_data + end + + def session_data=(data) + @session_data=data + end + + def self.session_data=(data) + @session_data=data + end + + private + + # Attempt to find credentials in this order: + # 1. username,password,tenant,host set in type parameters + # 2. openrc file path set in type parameters + # 3. service token and host set in type parameters + # 4. username,password,tenant,host set in environment variables + # 5. service token and host set in keystone.conf (backwards compatible version) + def authenticate(auth_params, log_file) + auth_params ||= {} + if password_credentials_set?(auth_params) + @session = get_authenticated_session(auth_params, log_file) + + elsif openrc_set?(auth_params) + credentials = get_credentials_from_openrc(auth_params['openrc']) + @session = get_authenticated_session(credentials, log_file) + + elsif service_credentials_set?(auth_params) + session_hash = get_unauthenticated_session(auth_params, log_file) + @session_data = session_hash[:data] + @session = session_hash[:session] + + elsif env_vars_set? + credentials = get_credentials_from_env + @session = get_authenticated_session(credentials, log_file) + + else # Last effort: try to get the token from keystone.conf + session_hash = self.class.try_auth_with_token(keystone_file, log_file) + @session_data = session_hash[:data] + @session = session_hash[:session] + end + end + + def self.authenticate(auth_params, log_file) + auth_params = {} unless auth_params + if env_vars_set? + credentials = get_credentials_from_env + @session = get_authenticated_session(credentials, log_file) + + else # Last effort: try to get the token from keystone.conf + session_hash = try_auth_with_token(keystone_file, log_file) + @session_data = session_hash[:data] + @session = session_hash[:session] + end + end + + + def self.try_auth_with_token(conf_file, log_file) + service_token = get_admin_token_from_keystone_file(conf_file) + auth_url = get_auth_url_from_keystone_file(conf_file) + session_hash = {} + if service_token + credentials = { + 'service_token' => service_token, + 'host_uri' => auth_url, + } + session_hash = get_unauthenticated_session(credentials, log_file) + else # All authentication efforts failed + raise(Puppet::Error, 'No credentials provided.') + end + end + + + def self.make_request(service, request, session_data, &block) + response = nil + if service && service.default_session_data + response = service.request(request, :endpoint_type => 'admin') do |params| + yield(params) if block + end + elsif session_data + response = service.request(request, :endpoint_type => 'admin', + :session_data => session_data) do |params| + yield(params) if block + end + else + raise(Puppet::Error, 'Cannot make a request with no session data.') + end + if response.body.hash['error'] + raise(Puppet::Error, "Error making request: #{response.body.hash['error']['code']} #{response.body.hash['error']['title']}") + end + response + end + + + def password_credentials_set?(auth_params) + auth_params['username'] && auth_params['password'] && auth_params['tenant_name'] && auth_params['host_uri'] + end + + + def openrc_set?(auth_params) + auth_params['openrc'] + end + + + def service_credentials_set?(auth_params) + auth_params['service_token'] && auth_params['host_uri'] + end + + + def self.env_vars_set? + ENV['OS_USERNAME'] && ENV['OS_PASSWORD'] && ENV['OS_TENANT_NAME'] && ENV['OS_AUTH_URL'] + end + + + def env_vars_set? + self.class.env_vars_set? + end + + + def get_credentials_from_openrc(file) + creds = {} + begin + File.open(file).readlines.delete_if{|l| l=~ /^#/}.each do |line| + key, value = line.split('=') + key = key.split(' ').last + value = value.chomp.gsub(/'/, '') + creds[key] = value + end + return creds + rescue Exception => error + return {} + end + end + + + def self.get_credentials_from_env + ENV.to_hash.dup.delete_if { |key, _| ! (key =~ /^OS/) } # Ruby 1.8.7 + end + + def get_credentials_from_env + self.class.get_credentials_from_env + end + + + def self.keystone_file + keystone_file = Puppet::Util::IniConfig::File.new + keystone_file.read('/etc/keystone/keystone.conf') + keystone_file + end + + def keystone_file + return @keystone_file if @keystone_file + @keystone_file = Puppet::Util::IniConfig::File.new + @keystone_file.read('/etc/keystone/keystone.conf') + @keystone_file + end + + + def self.get_admin_token_from_keystone_file(conf_file) + if conf_file and conf_file['DEFAULT'] and conf_file['DEFAULT']['admin_token'] + return "#{conf_file['DEFAULT']['admin_token'].strip}" + else + return nil + end + end + + def get_admin_token_from_keystone_file + conf_file = keystone_file + self.class.get_admin_token_from_keystone_file(conf_file) + end + + + def self.get_auth_url_from_keystone_file(conf_file) + if conf_file + if conf_file['DEFAULT'] + if conf_file['DEFAULT']['admin_endpoint'] + auth_url = conf_file['DEFAULT']['admin_endpoint'].strip + return versioned_endpoint(auth_url) + end + + if conf_file['DEFAULT']['admin_port'] + admin_port = conf_file['DEFAULT']['admin_port'].strip + else + admin_port = '35357' + end + + if conf_file['DEFAULT']['admin_bind_host'] + host = conf_file['DEFAULT']['admin_bind_host'].strip + if host == "0.0.0.0" + host = "127.0.0.1" + end + else + host = "127.0.0.1" + end + end + + if conf_file['ssl'] && conf_file['ssl']['enable'] && conf_file['ssl']['enable'].strip.downcase == 'true' + protocol = 'https' + else + protocol = 'http' + end + end + + "#{protocol}://#{host}:#{admin_port}/v2.0/" + end + + def get_auth_url_from_keystone_file + self.class.get_auth_url_from_keystone_file(keystone_file) + end + + + def self.make_configuration(credentials) + host_uri = versioned_endpoint(credentials['host_uri'] || credentials['OS_AUTH_URL'], credentials['api_version']) + { + :provider => 'openstack', + :auth_service => { + :name => 'identity', + :host_uri => host_uri, + :request => 'create_token', + :validator => 'list_tenants', + }, + :auth_credentials => { + :username => credentials['username'] || credentials['OS_USERNAME'], + :password => credentials['password'] || credentials['OS_PASSWORD'], + :tenant_name => credentials['tenant_name'] || credentials['OS_TENANT_NAME'] + } + } + end + + + def self.get_authenticated_session(credentials, log_file) + configuration = make_configuration(credentials) + session = ::Aviator::Session.new(:config => configuration, :log_file => log_file) + session.authenticate + session + end + + def get_authenticated_session(credentials, log_file) + self.class.get_authenticated_session(credentials, log_file) + end + + + def self.get_unauthenticated_session(credentials, log_file) + configuration = { + :provider => 'openstack', + } + session_data = { + :base_url => credentials['host_uri'], + :service_token => credentials['service_token'] + } + session = ::Aviator::Session.new(:config => configuration, :log_file => log_file) + { :session => session, :data => session_data } + end + + def get_unauthenticated_session(credentials, log_file) + self.class.get_unauthenticated_session(credentials, log_file) + end + + + def self.versioned_endpoint(endpoint, version = 'v2.0') + version = 'v2.0' if version.nil? + if endpoint =~ /\/#{version}\/?$/ || endpoint =~ /\/v2.0\/?$/ || endpoint =~ /\/v3\/?$/ + endpoint + else + "#{endpoint.chomp('/')}/#{version}" + end + end +end diff --git a/lib/puppet/util/aviator.rb b/lib/puppet/util/aviator.rb new file mode 100644 index 00000000..bc24b025 --- /dev/null +++ b/lib/puppet/util/aviator.rb @@ -0,0 +1,46 @@ +# Add the auth parameter to whatever type is given +module Puppet::Util::Aviator + def self.add_aviator_params(type) + + type.newparam(:auth) do + + desc < { + 'username' => 'test', + 'password' => 'passw0rd', + 'tenant_name' => 'test', + 'host_uri' => 'http://localhost:35357/v2.0', +} + +or a path to an openrc file containing these credentials, e.g.: + +auth => { + 'openrc' => '/root/openrc', +} + +or a service token and host, e.g.: + +auth => { + 'service_token' => 'ADMIN', + 'host_uri' => 'http://localhost:35357/v2.0', +} + +If not present, the provider will first look for environment variables +for password credentials and then to /etc/keystone/keystone.conf for a +service token. +EOT + + validate do |value| + raise(Puppet::Error, 'This property must be a hash') unless value.is_a?(Hash) + end + end + + type.newparam(:log_file) do + desc 'Log file. Defaults to no logging.' + defaultto('/dev/null') + end + end +end diff --git a/spec/fixtures/vcr/aviator/request/with_session.yml b/spec/fixtures/vcr/aviator/request/with_session.yml new file mode 100644 index 00000000..2d052df2 --- /dev/null +++ b/spec/fixtures/vcr/aviator/request/with_session.yml @@ -0,0 +1,67 @@ +--- + http_interactions: + - request: + method: post + uri: "http://192.168.11.4:35357/v2.0/tokens" + body: + encoding: UTF-8 + string: "{\x22auth\x22:{\x22passwordCredentials\x22:{\x22username\x22:\x22admin\x22,\x22password\x22:\x22fyby-tet\x22},\x22tenantName\x22:\x22admin\x22}}" + headers: + Content-Type: + - application/json + User-Agent: + - "Faraday v0.8.8" + response: + status: + code: 200 + message: + headers: + vary: + - X-Auth-Token + content-type: + - application/json + content-length: + - "9780" + date: + - "Tue, 30 Sep 2014 06:59:48 GMT" + connection: + - close + body: + encoding: UTF-8 + string: "{\x22access\x22: {\x22token\x22: {\x22issued_at\x22: \x222014-09-30T06:59:48.338940\x22, \x22expires\x22: \x222014-09-30T07:59:48Z\x22, \x22id\x22: \x22MIIRIAYJKoZIhvcNAQcCoIIRETCCEQ0CAQExCTAHBgUrDgMCGjCCD3YGCSqGSIb3DQEHAaCCD2cEgg9jeyJhY2Nlc3MiOiB7InRva2VuIjogeyJpc3N1ZWRfYXQiOiAiMjAxNC0wOS0zMFQwNjo1OTo0OC4zMzg5NDAiLCAiZXhwaXJlcyI6ICIyMDE0LTA5LTMwVDA3OjU5OjQ4WiIsICJpZCI6ICJwbGFjZWhvbGRlciIsICJ0ZW5hbnQiOiB7ImRlc2NyaXB0aW9uIjogImFkbWluIHRlbmFudCIsICJlbmFibGVkIjogdHJ1ZSwgImlkIjogImM1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgIm5hbWUiOiAiYWRtaW4ifX0sICJzZXJ2aWNlQ2F0YWxvZyI6IFt7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4Nzc0L3YyL2M1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzQvdjIvYzUxOGIzNmZhMjIwNDk5Yjg1YmE5YTcxMDE0Y2UyYTUiLCAiaWQiOiAiMWJiNzU4NWIzMzgxNGI4Mjk4NzJlYjQ0MjAyMTg5OGEiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODc3NC92Mi9jNTE4YjM2ZmEyMjA0OTliODViYTlhNzEwMTRjZTJhNSJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJjb21wdXRlIiwgIm5hbWUiOiAibm92YSJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo5Njk2LyIsICJyZWdpb24iOiAib3BlbnN0YWNrIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo5Njk2LyIsICJpZCI6ICJhYTdkNDU2NTNhYjI0ZGY2YmE5ZDE4NGE1ZWRkNGYxMyIsICJwdWJsaWNVUkwiOiAiaHR0cDovLzE5Mi4xNjguMTEuNDo5Njk2LyJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJuZXR3b3JrIiwgIm5hbWUiOiAibmV1dHJvbiJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4Nzc2L3YyL2M1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzYvdjIvYzUxOGIzNmZhMjIwNDk5Yjg1YmE5YTcxMDE0Y2UyYTUiLCAiaWQiOiAiMmJmNGQ5YzZiYTgwNDM1M2JjZGNlZGZjNTAxMDNiYjYiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODc3Ni92Mi9jNTE4YjM2ZmEyMjA0OTliODViYTlhNzEwMTRjZTJhNSJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJ2b2x1bWV2MiIsICJuYW1lIjogImNpbmRlcnYyIn0sIHsiZW5kcG9pbnRzIjogW3siYWRtaW5VUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzQvdjMiLCAicmVnaW9uIjogIm9wZW5zdGFjayIsICJpbnRlcm5hbFVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODc3NC92MyIsICJpZCI6ICIzZmQ4NDBjYmFkZDM0NmFiOTE2YjA2YWYxZjRlNWJmMCIsICJwdWJsaWNVUkwiOiAiaHR0cDovLzE5Mi4xNjguMTEuNDo4Nzc0L3YzIn1dLCAiZW5kcG9pbnRzX2xpbmtzIjogW10sICJ0eXBlIjogImNvbXB1dGV2MyIsICJuYW1lIjogIm5vdmF2MyJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo5MjkyIiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40OjkyOTIiLCAiaWQiOiAiMTJjOTM1NzkwYmM5NGE3ODljNzJmOWJiYjIxZjM5YmMiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6OTI5MiJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJpbWFnZSIsICJuYW1lIjogImdsYW5jZSJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4Nzc3IiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzciLCAiaWQiOiAiMWNlNDkwMWQ4OTE1NDIzZTk2ZGFiM2ZlMWZiMzY2M2MiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODc3NyJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJtZXRlcmluZyIsICJuYW1lIjogImNlaWxvbWV0ZXIifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODAwMC92MS8iLCAicmVnaW9uIjogIm9wZW5zdGFjayIsICJpbnRlcm5hbFVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODAwMC92MS8iLCAiaWQiOiAiNWU4ZjExYzk3ZTgwNDNiNWJkZTA1YmVhMmRlNDYxNmMiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODAwMC92MS8ifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAiY2xvdWRmb3JtYXRpb24iLCAibmFtZSI6ICJoZWF0LWNmbiJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4Nzc2L3YxL2M1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzYvdjEvYzUxOGIzNmZhMjIwNDk5Yjg1YmE5YTcxMDE0Y2UyYTUiLCAiaWQiOiAiNTRiOWVjMjhiYzYwNDI1MmIwMGNmZTZlMGU0NGFhOTQiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODc3Ni92MS9jNTE4YjM2ZmEyMjA0OTliODViYTlhNzEwMTRjZTJhNSJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJ2b2x1bWUiLCAibmFtZSI6ICJjaW5kZXIifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODc3My9zZXJ2aWNlcy9BZG1pbiIsICJyZWdpb24iOiAib3BlbnN0YWNrIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4NzczL3NlcnZpY2VzL0Nsb3VkIiwgImlkIjogIjA3NWVjNzliMGJlMzQxYmFhYmUyZTliMTIwNTkxZjQ4IiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTkyLjE2OC4xMS40Ojg3NzMvc2VydmljZXMvQ2xvdWQifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAiZWMyIiwgIm5hbWUiOiAibm92YV9lYzIifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODAwNC92MS9jNTE4YjM2ZmEyMjA0OTliODViYTlhNzEwMTRjZTJhNSIsICJyZWdpb24iOiAib3BlbnN0YWNrIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4MDA0L3YxL2M1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgImlkIjogIjI2MmM0YjM3MzY3ODQ2OGE5ODU1YTNlYmM2MDE1OTYwIiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTkyLjE2OC4xMS40OjgwMDQvdjEvYzUxOGIzNmZhMjIwNDk5Yjg1YmE5YTcxMDE0Y2UyYTUifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAib3JjaGVzdHJhdGlvbiIsICJuYW1lIjogImhlYXQifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6MzUzNTcvdjIuMCIsICJyZWdpb24iOiAib3BlbnN0YWNrIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo1MDAwL3YyLjAiLCAiaWQiOiAiMDg5ZmRiMjIyNDk1NDZiOTlhMWU1N2FlYzBiMWU3NmMiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6NTAwMC92Mi4wIn1dLCAiZW5kcG9pbnRzX2xpbmtzIjogW10sICJ0eXBlIjogImlkZW50aXR5IiwgIm5hbWUiOiAia2V5c3RvbmUifV0sICJ1c2VyIjogeyJ1c2VybmFtZSI6ICJhZG1pbiIsICJyb2xlc19saW5rcyI6IFtdLCAiaWQiOiAiM2Y3NmI5NDY2NzQzNGNmM2JkYzMyM2NmMDIxYzUwZjgiLCAicm9sZXMiOiBbeyJuYW1lIjogImFkbWluIn1dLCAibmFtZSI6ICJhZG1pbiJ9LCAibWV0YWRhdGEiOiB7ImlzX2FkbWluIjogMCwgInJvbGVzIjogWyIxZThiYzVkMWYzYTQ0OGU5YTJhMWNkYTU4ZDk3ZjkyYiJdfX19MYIBgTCCAX0CAQEwXDBXMQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVW5zZXQxDjAMBgNVBAcMBVVuc2V0MQ4wDAYDVQQKDAVVbnNldDEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tAgEBMAcGBSsOAwIaMA0GCSqGSIb3DQEBAQUABIIBAHGQ0NFb0OcE74KIU9DmmvgVyYCrNwwWrwG1CObr9111AHfEr+bn6YfX1ePRUhB2KpcuBPLeIfM-RlLHNwpLzYtvKIwdj0TxIecbF9PuTkWMEZ9Kxl+KE8F4dJOnv0XnAiWZ8QzrMZOo4d+owLJmNNLE1TKfGqv8ughdcrjHtUicHT2E0AOfO3ylEhJPsazUl8XIIWQ4sMWTrs0ROMiZnWPWbomYb49LIaREHD6nDfZX+EDZbHSfPVLTYVL-+qkiIH52-lXqz-OKPCn+Lt3RzXYDzapZd8cpzVgJpTuq2YKMZ+H06yvHFCTZNN49j6kZHz0Qkn2MjbwU8sH10wA7W6k=\x22, \x22tenant\x22: {\x22description\x22: \x22admin tenant\x22, \x22enabled\x22: true, \x22id\x22: \x22c518b36fa220499b85ba9a71014ce2a5\x22, \x22name\x22: \x22admin\x22}}, \x22serviceCatalog\x22: [{\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:8774/v2/c518b36fa220499b85ba9a71014ce2a5\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:8774/v2/c518b36fa220499b85ba9a71014ce2a5\x22, \x22id\x22: \x221bb7585b33814b829872eb442021898a\x22, \x22publicURL\x22: \x22http://192.168.11.4:8774/v2/c518b36fa220499b85ba9a71014ce2a5\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22compute\x22, \x22name\x22: \x22nova\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:9696/\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:9696/\x22, \x22id\x22: \x22aa7d45653ab24df6ba9d184a5edd4f13\x22, \x22publicURL\x22: \x22http://192.168.11.4:9696/\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22network\x22, \x22name\x22: \x22neutron\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:8776/v2/c518b36fa220499b85ba9a71014ce2a5\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:8776/v2/c518b36fa220499b85ba9a71014ce2a5\x22, \x22id\x22: \x222bf4d9c6ba804353bcdcedfc50103bb6\x22, \x22publicURL\x22: \x22http://192.168.11.4:8776/v2/c518b36fa220499b85ba9a71014ce2a5\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22volumev2\x22, \x22name\x22: \x22cinderv2\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:8774/v3\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:8774/v3\x22, \x22id\x22: \x223fd840cbadd346ab916b06af1f4e5bf0\x22, \x22publicURL\x22: \x22http://192.168.11.4:8774/v3\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22computev3\x22, \x22name\x22: \x22novav3\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:9292\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:9292\x22, \x22id\x22: \x2212c935790bc94a789c72f9bbb21f39bc\x22, \x22publicURL\x22: \x22http://192.168.11.4:9292\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22image\x22, \x22name\x22: \x22glance\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:8777\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:8777\x22, \x22id\x22: \x221ce4901d8915423e96dab3fe1fb3663c\x22, \x22publicURL\x22: \x22http://192.168.11.4:8777\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22metering\x22, \x22name\x22: \x22ceilometer\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:8000/v1/\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:8000/v1/\x22, \x22id\x22: \x225e8f11c97e8043b5bde05bea2de4616c\x22, \x22publicURL\x22: \x22http://192.168.11.4:8000/v1/\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22cloudformation\x22, \x22name\x22: \x22heat-cfn\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:8776/v1/c518b36fa220499b85ba9a71014ce2a5\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:8776/v1/c518b36fa220499b85ba9a71014ce2a5\x22, \x22id\x22: \x2254b9ec28bc604252b00cfe6e0e44aa94\x22, \x22publicURL\x22: \x22http://192.168.11.4:8776/v1/c518b36fa220499b85ba9a71014ce2a5\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22volume\x22, \x22name\x22: \x22cinder\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:8773/services/Admin\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:8773/services/Cloud\x22, \x22id\x22: \x22075ec79b0be341baabe2e9b120591f48\x22, \x22publicURL\x22: \x22http://192.168.11.4:8773/services/Cloud\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22ec2\x22, \x22name\x22: \x22nova_ec2\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:8004/v1/c518b36fa220499b85ba9a71014ce2a5\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:8004/v1/c518b36fa220499b85ba9a71014ce2a5\x22, \x22id\x22: \x22262c4b373678468a9855a3ebc6015960\x22, \x22publicURL\x22: \x22http://192.168.11.4:8004/v1/c518b36fa220499b85ba9a71014ce2a5\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22orchestration\x22, \x22name\x22: \x22heat\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:35357/v2.0\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:5000/v2.0\x22, \x22id\x22: \x22089fdb22249546b99a1e57aec0b1e76c\x22, \x22publicURL\x22: \x22http://192.168.11.4:5000/v2.0\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22identity\x22, \x22name\x22: \x22keystone\x22}], \x22user\x22: {\x22username\x22: \x22admin\x22, \x22roles_links\x22: [], \x22id\x22: \x223f76b94667434cf3bdc323cf021c50f8\x22, \x22roles\x22: [{\x22name\x22: \x22admin\x22}], \x22name\x22: \x22admin\x22}, \x22metadata\x22: {\x22is_admin\x22: 0, \x22roles\x22: [\x221e8bc5d1f3a448e9a2a1cda58d97f92b\x22]}}}" + http_version: + recorded_at: "Tue, 30 Sep 2014 06:59:48 GMT" + - request: + method: get + uri: "http://172.16.33.4:35357/v2.0/tenants" + body: + encoding: US-ASCII + string: "" + headers: + Content-Type: + - application/json + User-Agent: + - "Faraday v0.8.8" + X-Auth-Token: + - "MIIRIAYJKoZIhvcNAQcCoIIRETCCEQ0CAQExCTAHBgUrDgMCGjCCD3YGCSqGSIb3DQEHAaCCD2cEgg9jeyJhY2Nlc3MiOiB7InRva2VuIjogeyJpc3N1ZWRfYXQiOiAiMjAxNC0wOS0zMFQwNjo1OTo0OC4zMzg5NDAiLCAiZXhwaXJlcyI6ICIyMDE0LTA5LTMwVDA3OjU5OjQ4WiIsICJpZCI6ICJwbGFjZWhvbGRlciIsICJ0ZW5hbnQiOiB7ImRlc2NyaXB0aW9uIjogImFkbWluIHRlbmFudCIsICJlbmFibGVkIjogdHJ1ZSwgImlkIjogImM1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgIm5hbWUiOiAiYWRtaW4ifX0sICJzZXJ2aWNlQ2F0YWxvZyI6IFt7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4Nzc0L3YyL2M1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzQvdjIvYzUxOGIzNmZhMjIwNDk5Yjg1YmE5YTcxMDE0Y2UyYTUiLCAiaWQiOiAiMWJiNzU4NWIzMzgxNGI4Mjk4NzJlYjQ0MjAyMTg5OGEiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODc3NC92Mi9jNTE4YjM2ZmEyMjA0OTliODViYTlhNzEwMTRjZTJhNSJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJjb21wdXRlIiwgIm5hbWUiOiAibm92YSJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo5Njk2LyIsICJyZWdpb24iOiAib3BlbnN0YWNrIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo5Njk2LyIsICJpZCI6ICJhYTdkNDU2NTNhYjI0ZGY2YmE5ZDE4NGE1ZWRkNGYxMyIsICJwdWJsaWNVUkwiOiAiaHR0cDovLzE5Mi4xNjguMTEuNDo5Njk2LyJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJuZXR3b3JrIiwgIm5hbWUiOiAibmV1dHJvbiJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4Nzc2L3YyL2M1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzYvdjIvYzUxOGIzNmZhMjIwNDk5Yjg1YmE5YTcxMDE0Y2UyYTUiLCAiaWQiOiAiMmJmNGQ5YzZiYTgwNDM1M2JjZGNlZGZjNTAxMDNiYjYiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODc3Ni92Mi9jNTE4YjM2ZmEyMjA0OTliODViYTlhNzEwMTRjZTJhNSJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJ2b2x1bWV2MiIsICJuYW1lIjogImNpbmRlcnYyIn0sIHsiZW5kcG9pbnRzIjogW3siYWRtaW5VUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzQvdjMiLCAicmVnaW9uIjogIm9wZW5zdGFjayIsICJpbnRlcm5hbFVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODc3NC92MyIsICJpZCI6ICIzZmQ4NDBjYmFkZDM0NmFiOTE2YjA2YWYxZjRlNWJmMCIsICJwdWJsaWNVUkwiOiAiaHR0cDovLzE5Mi4xNjguMTEuNDo4Nzc0L3YzIn1dLCAiZW5kcG9pbnRzX2xpbmtzIjogW10sICJ0eXBlIjogImNvbXB1dGV2MyIsICJuYW1lIjogIm5vdmF2MyJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo5MjkyIiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40OjkyOTIiLCAiaWQiOiAiMTJjOTM1NzkwYmM5NGE3ODljNzJmOWJiYjIxZjM5YmMiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6OTI5MiJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJpbWFnZSIsICJuYW1lIjogImdsYW5jZSJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4Nzc3IiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzciLCAiaWQiOiAiMWNlNDkwMWQ4OTE1NDIzZTk2ZGFiM2ZlMWZiMzY2M2MiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODc3NyJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJtZXRlcmluZyIsICJuYW1lIjogImNlaWxvbWV0ZXIifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODAwMC92MS8iLCAicmVnaW9uIjogIm9wZW5zdGFjayIsICJpbnRlcm5hbFVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODAwMC92MS8iLCAiaWQiOiAiNWU4ZjExYzk3ZTgwNDNiNWJkZTA1YmVhMmRlNDYxNmMiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODAwMC92MS8ifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAiY2xvdWRmb3JtYXRpb24iLCAibmFtZSI6ICJoZWF0LWNmbiJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4Nzc2L3YxL2M1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzYvdjEvYzUxOGIzNmZhMjIwNDk5Yjg1YmE5YTcxMDE0Y2UyYTUiLCAiaWQiOiAiNTRiOWVjMjhiYzYwNDI1MmIwMGNmZTZlMGU0NGFhOTQiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODc3Ni92MS9jNTE4YjM2ZmEyMjA0OTliODViYTlhNzEwMTRjZTJhNSJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJ2b2x1bWUiLCAibmFtZSI6ICJjaW5kZXIifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODc3My9zZXJ2aWNlcy9BZG1pbiIsICJyZWdpb24iOiAib3BlbnN0YWNrIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4NzczL3NlcnZpY2VzL0Nsb3VkIiwgImlkIjogIjA3NWVjNzliMGJlMzQxYmFhYmUyZTliMTIwNTkxZjQ4IiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTkyLjE2OC4xMS40Ojg3NzMvc2VydmljZXMvQ2xvdWQifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAiZWMyIiwgIm5hbWUiOiAibm92YV9lYzIifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODAwNC92MS9jNTE4YjM2ZmEyMjA0OTliODViYTlhNzEwMTRjZTJhNSIsICJyZWdpb24iOiAib3BlbnN0YWNrIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4MDA0L3YxL2M1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgImlkIjogIjI2MmM0YjM3MzY3ODQ2OGE5ODU1YTNlYmM2MDE1OTYwIiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTkyLjE2OC4xMS40OjgwMDQvdjEvYzUxOGIzNmZhMjIwNDk5Yjg1YmE5YTcxMDE0Y2UyYTUifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAib3JjaGVzdHJhdGlvbiIsICJuYW1lIjogImhlYXQifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6MzUzNTcvdjIuMCIsICJyZWdpb24iOiAib3BlbnN0YWNrIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo1MDAwL3YyLjAiLCAiaWQiOiAiMDg5ZmRiMjIyNDk1NDZiOTlhMWU1N2FlYzBiMWU3NmMiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6NTAwMC92Mi4wIn1dLCAiZW5kcG9pbnRzX2xpbmtzIjogW10sICJ0eXBlIjogImlkZW50aXR5IiwgIm5hbWUiOiAia2V5c3RvbmUifV0sICJ1c2VyIjogeyJ1c2VybmFtZSI6ICJhZG1pbiIsICJyb2xlc19saW5rcyI6IFtdLCAiaWQiOiAiM2Y3NmI5NDY2NzQzNGNmM2JkYzMyM2NmMDIxYzUwZjgiLCAicm9sZXMiOiBbeyJuYW1lIjogImFkbWluIn1dLCAibmFtZSI6ICJhZG1pbiJ9LCAibWV0YWRhdGEiOiB7ImlzX2FkbWluIjogMCwgInJvbGVzIjogWyIxZThiYzVkMWYzYTQ0OGU5YTJhMWNkYTU4ZDk3ZjkyYiJdfX19MYIBgTCCAX0CAQEwXDBXMQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVW5zZXQxDjAMBgNVBAcMBVVuc2V0MQ4wDAYDVQQKDAVVbnNldDEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tAgEBMAcGBSsOAwIaMA0GCSqGSIb3DQEBAQUABIIBAHGQ0NFb0OcE74KIU9DmmvgVyYCrNwwWrwG1CObr9111AHfEr+bn6YfX1ePRUhB2KpcuBPLeIfM-RlLHNwpLzYtvKIwdj0TxIecbF9PuTkWMEZ9Kxl+KE8F4dJOnv0XnAiWZ8QzrMZOo4d+owLJmNNLE1TKfGqv8ughdcrjHtUicHT2E0AOfO3ylEhJPsazUl8XIIWQ4sMWTrs0ROMiZnWPWbomYb49LIaREHD6nDfZX+EDZbHSfPVLTYVL-+qkiIH52-lXqz-OKPCn+Lt3RzXYDzapZd8cpzVgJpTuq2YKMZ+H06yvHFCTZNN49j6kZHz0Qkn2MjbwU8sH10wA7W6k=" + response: + status: + code: 200 + message: + headers: + vary: + - X-Auth-Token + content-type: + - application/json + content-length: + - "491" + date: + - "Tue, 30 Sep 2014 06:59:48 GMT" + connection: + - close + body: + encoding: UTF-8 + string: "{\x22tenants_links\x22: [], \x22tenants\x22: [{\x22description\x22: \x22Test tenant\x22, \x22enabled\x22: true, \x22id\x22: \x2234e463e2bab24f78990ca864e4a28ba2\x22, \x22name\x22: \x22test2\x22}, {\x22description\x22: \x22Tenant for the openstack services\x22, \x22enabled\x22: true, \x22id\x22: \x2268c8fcf77aff4b409cc158c0f6cbff7b\x22, \x22name\x22: \x22services\x22}, {\x22description\x22: \x22Test tenant\x22, \x22enabled\x22: true, \x22id\x22: \x22c330f1bc663648df9c1e7835a1e7a955\x22, \x22name\x22: \x22test\x22}, {\x22description\x22: \x22admin tenant\x22, \x22enabled\x22: true, \x22id\x22: \x22c518b36fa220499b85ba9a71014ce2a5\x22, \x22name\x22: \x22admin\x22}]}" + http_version: + recorded_at: "Tue, 30 Sep 2014 06:59:48 GMT" + recorded_with: "VCR 2.9.3" \ No newline at end of file diff --git a/spec/fixtures/vcr/aviator/request/without_session.yml b/spec/fixtures/vcr/aviator/request/without_session.yml new file mode 100644 index 00000000..784fb2fe --- /dev/null +++ b/spec/fixtures/vcr/aviator/request/without_session.yml @@ -0,0 +1,36 @@ +--- + http_interactions: + - request: + method: get + uri: "http://192.168.11.4:35357/v2.0/tenants" + body: + encoding: US-ASCII + string: "" + headers: + Content-Type: + - application/json + User-Agent: + - "Faraday v0.8.8" + X-Auth-Token: + - sosp-kyl + response: + status: + code: 200 + message: + headers: + vary: + - X-Auth-Token + content-type: + - application/json + content-length: + - "491" + date: + - "Tue, 30 Sep 2014 06:59:48 GMT" + connection: + - close + body: + encoding: UTF-8 + string: "{\x22tenants_links\x22: [], \x22tenants\x22: [{\x22description\x22: \x22Test tenant\x22, \x22enabled\x22: true, \x22id\x22: \x2234e463e2bab24f78990ca864e4a28ba2\x22, \x22name\x22: \x22test2\x22}, {\x22description\x22: \x22Tenant for the openstack services\x22, \x22enabled\x22: true, \x22id\x22: \x2268c8fcf77aff4b409cc158c0f6cbff7b\x22, \x22name\x22: \x22services\x22}, {\x22description\x22: \x22Test tenant\x22, \x22enabled\x22: true, \x22id\x22: \x22c330f1bc663648df9c1e7835a1e7a955\x22, \x22name\x22: \x22test\x22}, {\x22description\x22: \x22admin tenant\x22, \x22enabled\x22: true, \x22id\x22: \x22c518b36fa220499b85ba9a71014ce2a5\x22, \x22name\x22: \x22admin\x22}]}" + http_version: + recorded_at: "Tue, 30 Sep 2014 06:59:48 GMT" + recorded_with: "VCR 2.9.3" \ No newline at end of file diff --git a/spec/fixtures/vcr/aviator/session/with_password.yml b/spec/fixtures/vcr/aviator/session/with_password.yml new file mode 100644 index 00000000..3faa4743 --- /dev/null +++ b/spec/fixtures/vcr/aviator/session/with_password.yml @@ -0,0 +1,67 @@ +--- + http_interactions: + - request: + method: post + uri: "http://192.168.11.4:35357/v2.0/tokens" + body: + encoding: UTF-8 + string: "{\x22auth\x22:{\x22passwordCredentials\x22:{\x22username\x22:\x22admin\x22,\x22password\x22:\x22fyby-tet\x22},\x22tenantName\x22:\x22admin\x22}}" + headers: + Content-Type: + - application/json + User-Agent: + - "Faraday v0.8.8" + response: + status: + code: 200 + message: + headers: + vary: + - X-Auth-Token + content-type: + - application/json + content-length: + - "9780" + date: + - "Tue, 30 Sep 2014 07:16:15 GMT" + connection: + - close + body: + encoding: UTF-8 + string: "{\x22access\x22: {\x22token\x22: {\x22issued_at\x22: \x222014-09-30T07:16:15.042778\x22, \x22expires\x22: \x222014-09-30T08:16:15Z\x22, \x22id\x22: \x22MIIRIAYJKoZIhvcNAQcCoIIRETCCEQ0CAQExCTAHBgUrDgMCGjCCD3YGCSqGSIb3DQEHAaCCD2cEgg9jeyJhY2Nlc3MiOiB7InRva2VuIjogeyJpc3N1ZWRfYXQiOiAiMjAxNC0wOS0zMFQwNzoxNjoxNS4wNDI3NzgiLCAiZXhwaXJlcyI6ICIyMDE0LTA5LTMwVDA4OjE2OjE1WiIsICJpZCI6ICJwbGFjZWhvbGRlciIsICJ0ZW5hbnQiOiB7ImRlc2NyaXB0aW9uIjogImFkbWluIHRlbmFudCIsICJlbmFibGVkIjogdHJ1ZSwgImlkIjogImM1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgIm5hbWUiOiAiYWRtaW4ifX0sICJzZXJ2aWNlQ2F0YWxvZyI6IFt7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4Nzc0L3YyL2M1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzQvdjIvYzUxOGIzNmZhMjIwNDk5Yjg1YmE5YTcxMDE0Y2UyYTUiLCAiaWQiOiAiMWJiNzU4NWIzMzgxNGI4Mjk4NzJlYjQ0MjAyMTg5OGEiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODc3NC92Mi9jNTE4YjM2ZmEyMjA0OTliODViYTlhNzEwMTRjZTJhNSJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJjb21wdXRlIiwgIm5hbWUiOiAibm92YSJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo5Njk2LyIsICJyZWdpb24iOiAib3BlbnN0YWNrIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo5Njk2LyIsICJpZCI6ICJhYTdkNDU2NTNhYjI0ZGY2YmE5ZDE4NGE1ZWRkNGYxMyIsICJwdWJsaWNVUkwiOiAiaHR0cDovLzE5Mi4xNjguMTEuNDo5Njk2LyJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJuZXR3b3JrIiwgIm5hbWUiOiAibmV1dHJvbiJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4Nzc2L3YyL2M1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzYvdjIvYzUxOGIzNmZhMjIwNDk5Yjg1YmE5YTcxMDE0Y2UyYTUiLCAiaWQiOiAiMmJmNGQ5YzZiYTgwNDM1M2JjZGNlZGZjNTAxMDNiYjYiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODc3Ni92Mi9jNTE4YjM2ZmEyMjA0OTliODViYTlhNzEwMTRjZTJhNSJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJ2b2x1bWV2MiIsICJuYW1lIjogImNpbmRlcnYyIn0sIHsiZW5kcG9pbnRzIjogW3siYWRtaW5VUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzQvdjMiLCAicmVnaW9uIjogIm9wZW5zdGFjayIsICJpbnRlcm5hbFVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODc3NC92MyIsICJpZCI6ICIzZmQ4NDBjYmFkZDM0NmFiOTE2YjA2YWYxZjRlNWJmMCIsICJwdWJsaWNVUkwiOiAiaHR0cDovLzE5Mi4xNjguMTEuNDo4Nzc0L3YzIn1dLCAiZW5kcG9pbnRzX2xpbmtzIjogW10sICJ0eXBlIjogImNvbXB1dGV2MyIsICJuYW1lIjogIm5vdmF2MyJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo5MjkyIiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40OjkyOTIiLCAiaWQiOiAiMTJjOTM1NzkwYmM5NGE3ODljNzJmOWJiYjIxZjM5YmMiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6OTI5MiJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJpbWFnZSIsICJuYW1lIjogImdsYW5jZSJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4Nzc3IiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzciLCAiaWQiOiAiMWNlNDkwMWQ4OTE1NDIzZTk2ZGFiM2ZlMWZiMzY2M2MiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODc3NyJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJtZXRlcmluZyIsICJuYW1lIjogImNlaWxvbWV0ZXIifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODAwMC92MS8iLCAicmVnaW9uIjogIm9wZW5zdGFjayIsICJpbnRlcm5hbFVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODAwMC92MS8iLCAiaWQiOiAiNWU4ZjExYzk3ZTgwNDNiNWJkZTA1YmVhMmRlNDYxNmMiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODAwMC92MS8ifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAiY2xvdWRmb3JtYXRpb24iLCAibmFtZSI6ICJoZWF0LWNmbiJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4Nzc2L3YxL2M1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzYvdjEvYzUxOGIzNmZhMjIwNDk5Yjg1YmE5YTcxMDE0Y2UyYTUiLCAiaWQiOiAiNTRiOWVjMjhiYzYwNDI1MmIwMGNmZTZlMGU0NGFhOTQiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODc3Ni92MS9jNTE4YjM2ZmEyMjA0OTliODViYTlhNzEwMTRjZTJhNSJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJ2b2x1bWUiLCAibmFtZSI6ICJjaW5kZXIifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODc3My9zZXJ2aWNlcy9BZG1pbiIsICJyZWdpb24iOiAib3BlbnN0YWNrIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4NzczL3NlcnZpY2VzL0Nsb3VkIiwgImlkIjogIjA3NWVjNzliMGJlMzQxYmFhYmUyZTliMTIwNTkxZjQ4IiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTkyLjE2OC4xMS40Ojg3NzMvc2VydmljZXMvQ2xvdWQifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAiZWMyIiwgIm5hbWUiOiAibm92YV9lYzIifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODAwNC92MS9jNTE4YjM2ZmEyMjA0OTliODViYTlhNzEwMTRjZTJhNSIsICJyZWdpb24iOiAib3BlbnN0YWNrIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4MDA0L3YxL2M1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgImlkIjogIjI2MmM0YjM3MzY3ODQ2OGE5ODU1YTNlYmM2MDE1OTYwIiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTkyLjE2OC4xMS40OjgwMDQvdjEvYzUxOGIzNmZhMjIwNDk5Yjg1YmE5YTcxMDE0Y2UyYTUifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAib3JjaGVzdHJhdGlvbiIsICJuYW1lIjogImhlYXQifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6MzUzNTcvdjIuMCIsICJyZWdpb24iOiAib3BlbnN0YWNrIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo1MDAwL3YyLjAiLCAiaWQiOiAiMDg5ZmRiMjIyNDk1NDZiOTlhMWU1N2FlYzBiMWU3NmMiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6NTAwMC92Mi4wIn1dLCAiZW5kcG9pbnRzX2xpbmtzIjogW10sICJ0eXBlIjogImlkZW50aXR5IiwgIm5hbWUiOiAia2V5c3RvbmUifV0sICJ1c2VyIjogeyJ1c2VybmFtZSI6ICJhZG1pbiIsICJyb2xlc19saW5rcyI6IFtdLCAiaWQiOiAiM2Y3NmI5NDY2NzQzNGNmM2JkYzMyM2NmMDIxYzUwZjgiLCAicm9sZXMiOiBbeyJuYW1lIjogImFkbWluIn1dLCAibmFtZSI6ICJhZG1pbiJ9LCAibWV0YWRhdGEiOiB7ImlzX2FkbWluIjogMCwgInJvbGVzIjogWyIxZThiYzVkMWYzYTQ0OGU5YTJhMWNkYTU4ZDk3ZjkyYiJdfX19MYIBgTCCAX0CAQEwXDBXMQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVW5zZXQxDjAMBgNVBAcMBVVuc2V0MQ4wDAYDVQQKDAVVbnNldDEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tAgEBMAcGBSsOAwIaMA0GCSqGSIb3DQEBAQUABIIBAEOAl3MRmSUB+J+kRi+qRhwOrNRmj-wDqT5nJTlbafOjofSXsHG683LaipA7oPoH-ARUPDxXIZfevRue7bQQB3I4cWIUSItIPyW4xDpF+iHy3QOm+I-3v3ctze2Z3Rp0TRaYFsItTZZETsSXI28yBt9+3Dsk3a7Vv10HAZetbV1i6qu6avLcJsmN-1J3KLwCDSEvpMgDAcpzAnhba1fi+X8GrCCTz4c1uIcPfsHxX4g8gNkB4-VT0lkRmfSxdrGeRz0uN12oDqgCL64IV1mJ6Bi9Unh15QFcLwU0F8ote+joG9G29fw3WDzneXHIeEIZSBXmOAX2kQBOnZa2sZg8gls=\x22, \x22tenant\x22: {\x22description\x22: \x22admin tenant\x22, \x22enabled\x22: true, \x22id\x22: \x22c518b36fa220499b85ba9a71014ce2a5\x22, \x22name\x22: \x22admin\x22}}, \x22serviceCatalog\x22: [{\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:8774/v2/c518b36fa220499b85ba9a71014ce2a5\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:8774/v2/c518b36fa220499b85ba9a71014ce2a5\x22, \x22id\x22: \x221bb7585b33814b829872eb442021898a\x22, \x22publicURL\x22: \x22http://192.168.11.4:8774/v2/c518b36fa220499b85ba9a71014ce2a5\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22compute\x22, \x22name\x22: \x22nova\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:9696/\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:9696/\x22, \x22id\x22: \x22aa7d45653ab24df6ba9d184a5edd4f13\x22, \x22publicURL\x22: \x22http://192.168.11.4:9696/\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22network\x22, \x22name\x22: \x22neutron\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:8776/v2/c518b36fa220499b85ba9a71014ce2a5\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:8776/v2/c518b36fa220499b85ba9a71014ce2a5\x22, \x22id\x22: \x222bf4d9c6ba804353bcdcedfc50103bb6\x22, \x22publicURL\x22: \x22http://192.168.11.4:8776/v2/c518b36fa220499b85ba9a71014ce2a5\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22volumev2\x22, \x22name\x22: \x22cinderv2\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:8774/v3\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:8774/v3\x22, \x22id\x22: \x223fd840cbadd346ab916b06af1f4e5bf0\x22, \x22publicURL\x22: \x22http://192.168.11.4:8774/v3\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22computev3\x22, \x22name\x22: \x22novav3\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:9292\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:9292\x22, \x22id\x22: \x2212c935790bc94a789c72f9bbb21f39bc\x22, \x22publicURL\x22: \x22http://192.168.11.4:9292\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22image\x22, \x22name\x22: \x22glance\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:8777\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:8777\x22, \x22id\x22: \x221ce4901d8915423e96dab3fe1fb3663c\x22, \x22publicURL\x22: \x22http://192.168.11.4:8777\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22metering\x22, \x22name\x22: \x22ceilometer\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:8000/v1/\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:8000/v1/\x22, \x22id\x22: \x225e8f11c97e8043b5bde05bea2de4616c\x22, \x22publicURL\x22: \x22http://192.168.11.4:8000/v1/\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22cloudformation\x22, \x22name\x22: \x22heat-cfn\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:8776/v1/c518b36fa220499b85ba9a71014ce2a5\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:8776/v1/c518b36fa220499b85ba9a71014ce2a5\x22, \x22id\x22: \x2254b9ec28bc604252b00cfe6e0e44aa94\x22, \x22publicURL\x22: \x22http://192.168.11.4:8776/v1/c518b36fa220499b85ba9a71014ce2a5\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22volume\x22, \x22name\x22: \x22cinder\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:8773/services/Admin\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:8773/services/Cloud\x22, \x22id\x22: \x22075ec79b0be341baabe2e9b120591f48\x22, \x22publicURL\x22: \x22http://192.168.11.4:8773/services/Cloud\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22ec2\x22, \x22name\x22: \x22nova_ec2\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:8004/v1/c518b36fa220499b85ba9a71014ce2a5\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:8004/v1/c518b36fa220499b85ba9a71014ce2a5\x22, \x22id\x22: \x22262c4b373678468a9855a3ebc6015960\x22, \x22publicURL\x22: \x22http://192.168.11.4:8004/v1/c518b36fa220499b85ba9a71014ce2a5\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22orchestration\x22, \x22name\x22: \x22heat\x22}, {\x22endpoints\x22: [{\x22adminURL\x22: \x22http://172.16.33.4:35357/v2.0\x22, \x22region\x22: \x22openstack\x22, \x22internalURL\x22: \x22http://172.16.33.4:5000/v2.0\x22, \x22id\x22: \x22089fdb22249546b99a1e57aec0b1e76c\x22, \x22publicURL\x22: \x22http://192.168.11.4:5000/v2.0\x22}], \x22endpoints_links\x22: [], \x22type\x22: \x22identity\x22, \x22name\x22: \x22keystone\x22}], \x22user\x22: {\x22username\x22: \x22admin\x22, \x22roles_links\x22: [], \x22id\x22: \x223f76b94667434cf3bdc323cf021c50f8\x22, \x22roles\x22: [{\x22name\x22: \x22admin\x22}], \x22name\x22: \x22admin\x22}, \x22metadata\x22: {\x22is_admin\x22: 0, \x22roles\x22: [\x221e8bc5d1f3a448e9a2a1cda58d97f92b\x22]}}}" + http_version: + recorded_at: "Tue, 30 Sep 2014 07:16:15 GMT" + - request: + method: get + uri: "http://192.168.11.4:5000/v2.0/tenants" + body: + encoding: US-ASCII + string: "" + headers: + Content-Type: + - application/json + User-Agent: + - "Faraday v0.8.8" + X-Auth-Token: + - "MIIRIAYJKoZIhvcNAQcCoIIRETCCEQ0CAQExCTAHBgUrDgMCGjCCD3YGCSqGSIb3DQEHAaCCD2cEgg9jeyJhY2Nlc3MiOiB7InRva2VuIjogeyJpc3N1ZWRfYXQiOiAiMjAxNC0wOS0zMFQwNzoxNjoxNS4wNDI3NzgiLCAiZXhwaXJlcyI6ICIyMDE0LTA5LTMwVDA4OjE2OjE1WiIsICJpZCI6ICJwbGFjZWhvbGRlciIsICJ0ZW5hbnQiOiB7ImRlc2NyaXB0aW9uIjogImFkbWluIHRlbmFudCIsICJlbmFibGVkIjogdHJ1ZSwgImlkIjogImM1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgIm5hbWUiOiAiYWRtaW4ifX0sICJzZXJ2aWNlQ2F0YWxvZyI6IFt7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4Nzc0L3YyL2M1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzQvdjIvYzUxOGIzNmZhMjIwNDk5Yjg1YmE5YTcxMDE0Y2UyYTUiLCAiaWQiOiAiMWJiNzU4NWIzMzgxNGI4Mjk4NzJlYjQ0MjAyMTg5OGEiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODc3NC92Mi9jNTE4YjM2ZmEyMjA0OTliODViYTlhNzEwMTRjZTJhNSJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJjb21wdXRlIiwgIm5hbWUiOiAibm92YSJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo5Njk2LyIsICJyZWdpb24iOiAib3BlbnN0YWNrIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo5Njk2LyIsICJpZCI6ICJhYTdkNDU2NTNhYjI0ZGY2YmE5ZDE4NGE1ZWRkNGYxMyIsICJwdWJsaWNVUkwiOiAiaHR0cDovLzE5Mi4xNjguMTEuNDo5Njk2LyJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJuZXR3b3JrIiwgIm5hbWUiOiAibmV1dHJvbiJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4Nzc2L3YyL2M1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzYvdjIvYzUxOGIzNmZhMjIwNDk5Yjg1YmE5YTcxMDE0Y2UyYTUiLCAiaWQiOiAiMmJmNGQ5YzZiYTgwNDM1M2JjZGNlZGZjNTAxMDNiYjYiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODc3Ni92Mi9jNTE4YjM2ZmEyMjA0OTliODViYTlhNzEwMTRjZTJhNSJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJ2b2x1bWV2MiIsICJuYW1lIjogImNpbmRlcnYyIn0sIHsiZW5kcG9pbnRzIjogW3siYWRtaW5VUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzQvdjMiLCAicmVnaW9uIjogIm9wZW5zdGFjayIsICJpbnRlcm5hbFVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODc3NC92MyIsICJpZCI6ICIzZmQ4NDBjYmFkZDM0NmFiOTE2YjA2YWYxZjRlNWJmMCIsICJwdWJsaWNVUkwiOiAiaHR0cDovLzE5Mi4xNjguMTEuNDo4Nzc0L3YzIn1dLCAiZW5kcG9pbnRzX2xpbmtzIjogW10sICJ0eXBlIjogImNvbXB1dGV2MyIsICJuYW1lIjogIm5vdmF2MyJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo5MjkyIiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40OjkyOTIiLCAiaWQiOiAiMTJjOTM1NzkwYmM5NGE3ODljNzJmOWJiYjIxZjM5YmMiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6OTI5MiJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJpbWFnZSIsICJuYW1lIjogImdsYW5jZSJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4Nzc3IiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzciLCAiaWQiOiAiMWNlNDkwMWQ4OTE1NDIzZTk2ZGFiM2ZlMWZiMzY2M2MiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODc3NyJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJtZXRlcmluZyIsICJuYW1lIjogImNlaWxvbWV0ZXIifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODAwMC92MS8iLCAicmVnaW9uIjogIm9wZW5zdGFjayIsICJpbnRlcm5hbFVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODAwMC92MS8iLCAiaWQiOiAiNWU4ZjExYzk3ZTgwNDNiNWJkZTA1YmVhMmRlNDYxNmMiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODAwMC92MS8ifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAiY2xvdWRmb3JtYXRpb24iLCAibmFtZSI6ICJoZWF0LWNmbiJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4Nzc2L3YxL2M1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgInJlZ2lvbiI6ICJvcGVuc3RhY2siLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzE3Mi4xNi4zMy40Ojg3NzYvdjEvYzUxOGIzNmZhMjIwNDk5Yjg1YmE5YTcxMDE0Y2UyYTUiLCAiaWQiOiAiNTRiOWVjMjhiYzYwNDI1MmIwMGNmZTZlMGU0NGFhOTQiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6ODc3Ni92MS9jNTE4YjM2ZmEyMjA0OTliODViYTlhNzEwMTRjZTJhNSJ9XSwgImVuZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJ2b2x1bWUiLCAibmFtZSI6ICJjaW5kZXIifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODc3My9zZXJ2aWNlcy9BZG1pbiIsICJyZWdpb24iOiAib3BlbnN0YWNrIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4NzczL3NlcnZpY2VzL0Nsb3VkIiwgImlkIjogIjA3NWVjNzliMGJlMzQxYmFhYmUyZTliMTIwNTkxZjQ4IiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTkyLjE2OC4xMS40Ojg3NzMvc2VydmljZXMvQ2xvdWQifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAiZWMyIiwgIm5hbWUiOiAibm92YV9lYzIifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6ODAwNC92MS9jNTE4YjM2ZmEyMjA0OTliODViYTlhNzEwMTRjZTJhNSIsICJyZWdpb24iOiAib3BlbnN0YWNrIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo4MDA0L3YxL2M1MThiMzZmYTIyMDQ5OWI4NWJhOWE3MTAxNGNlMmE1IiwgImlkIjogIjI2MmM0YjM3MzY3ODQ2OGE5ODU1YTNlYmM2MDE1OTYwIiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTkyLjE2OC4xMS40OjgwMDQvdjEvYzUxOGIzNmZhMjIwNDk5Yjg1YmE5YTcxMDE0Y2UyYTUifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAib3JjaGVzdHJhdGlvbiIsICJuYW1lIjogImhlYXQifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRwOi8vMTcyLjE2LjMzLjQ6MzUzNTcvdjIuMCIsICJyZWdpb24iOiAib3BlbnN0YWNrIiwgImludGVybmFsVVJMIjogImh0dHA6Ly8xNzIuMTYuMzMuNDo1MDAwL3YyLjAiLCAiaWQiOiAiMDg5ZmRiMjIyNDk1NDZiOTlhMWU1N2FlYzBiMWU3NmMiLCAicHVibGljVVJMIjogImh0dHA6Ly8xOTIuMTY4LjExLjQ6NTAwMC92Mi4wIn1dLCAiZW5kcG9pbnRzX2xpbmtzIjogW10sICJ0eXBlIjogImlkZW50aXR5IiwgIm5hbWUiOiAia2V5c3RvbmUifV0sICJ1c2VyIjogeyJ1c2VybmFtZSI6ICJhZG1pbiIsICJyb2xlc19saW5rcyI6IFtdLCAiaWQiOiAiM2Y3NmI5NDY2NzQzNGNmM2JkYzMyM2NmMDIxYzUwZjgiLCAicm9sZXMiOiBbeyJuYW1lIjogImFkbWluIn1dLCAibmFtZSI6ICJhZG1pbiJ9LCAibWV0YWRhdGEiOiB7ImlzX2FkbWluIjogMCwgInJvbGVzIjogWyIxZThiYzVkMWYzYTQ0OGU5YTJhMWNkYTU4ZDk3ZjkyYiJdfX19MYIBgTCCAX0CAQEwXDBXMQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVW5zZXQxDjAMBgNVBAcMBVVuc2V0MQ4wDAYDVQQKDAVVbnNldDEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tAgEBMAcGBSsOAwIaMA0GCSqGSIb3DQEBAQUABIIBAEOAl3MRmSUB+J+kRi+qRhwOrNRmj-wDqT5nJTlbafOjofSXsHG683LaipA7oPoH-ARUPDxXIZfevRue7bQQB3I4cWIUSItIPyW4xDpF+iHy3QOm+I-3v3ctze2Z3Rp0TRaYFsItTZZETsSXI28yBt9+3Dsk3a7Vv10HAZetbV1i6qu6avLcJsmN-1J3KLwCDSEvpMgDAcpzAnhba1fi+X8GrCCTz4c1uIcPfsHxX4g8gNkB4-VT0lkRmfSxdrGeRz0uN12oDqgCL64IV1mJ6Bi9Unh15QFcLwU0F8ote+joG9G29fw3WDzneXHIeEIZSBXmOAX2kQBOnZa2sZg8gls=" + response: + status: + code: 200 + message: + headers: + vary: + - X-Auth-Token + content-type: + - application/json + content-length: + - "143" + date: + - "Tue, 30 Sep 2014 07:16:15 GMT" + connection: + - close + body: + encoding: UTF-8 + string: "{\x22tenants_links\x22: [], \x22tenants\x22: [{\x22description\x22: \x22admin tenant\x22, \x22enabled\x22: true, \x22id\x22: \x22c518b36fa220499b85ba9a71014ce2a5\x22, \x22name\x22: \x22admin\x22}]}" + http_version: + recorded_at: "Tue, 30 Sep 2014 07:16:15 GMT" + recorded_with: "VCR 2.9.3" \ No newline at end of file diff --git a/spec/fixtures/vcr/aviator/session/with_token.yml b/spec/fixtures/vcr/aviator/session/with_token.yml new file mode 100644 index 00000000..784fb2fe --- /dev/null +++ b/spec/fixtures/vcr/aviator/session/with_token.yml @@ -0,0 +1,36 @@ +--- + http_interactions: + - request: + method: get + uri: "http://192.168.11.4:35357/v2.0/tenants" + body: + encoding: US-ASCII + string: "" + headers: + Content-Type: + - application/json + User-Agent: + - "Faraday v0.8.8" + X-Auth-Token: + - sosp-kyl + response: + status: + code: 200 + message: + headers: + vary: + - X-Auth-Token + content-type: + - application/json + content-length: + - "491" + date: + - "Tue, 30 Sep 2014 06:59:48 GMT" + connection: + - close + body: + encoding: UTF-8 + string: "{\x22tenants_links\x22: [], \x22tenants\x22: [{\x22description\x22: \x22Test tenant\x22, \x22enabled\x22: true, \x22id\x22: \x2234e463e2bab24f78990ca864e4a28ba2\x22, \x22name\x22: \x22test2\x22}, {\x22description\x22: \x22Tenant for the openstack services\x22, \x22enabled\x22: true, \x22id\x22: \x2268c8fcf77aff4b409cc158c0f6cbff7b\x22, \x22name\x22: \x22services\x22}, {\x22description\x22: \x22Test tenant\x22, \x22enabled\x22: true, \x22id\x22: \x22c330f1bc663648df9c1e7835a1e7a955\x22, \x22name\x22: \x22test\x22}, {\x22description\x22: \x22admin tenant\x22, \x22enabled\x22: true, \x22id\x22: \x22c518b36fa220499b85ba9a71014ce2a5\x22, \x22name\x22: \x22admin\x22}]}" + http_version: + recorded_at: "Tue, 30 Sep 2014 06:59:48 GMT" + recorded_with: "VCR 2.9.3" \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2c6f5664..ecd609ae 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1 +1,7 @@ require 'puppetlabs_spec_helper/module_spec_helper' +require 'vcr' + +VCR.configure do |c| + c.cassette_library_dir = 'spec/fixtures/vcr' + c.hook_into :faraday +end diff --git a/spec/unit/provider/aviator_spec.rb b/spec/unit/provider/aviator_spec.rb new file mode 100644 index 00000000..35564e64 --- /dev/null +++ b/spec/unit/provider/aviator_spec.rb @@ -0,0 +1,320 @@ +# Load libraries from aviator here to simulate how they live together in a real puppet run +$LOAD_PATH.push(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'modules', 'aviator', 'lib')) +require 'puppet' +require 'vcr' +require 'spec_helper' +require 'puppet/provider/aviator' + + +describe Puppet::Provider::Aviator do + + before(:each) do + ENV['OS_USERNAME'] = nil + ENV['OS_PASSWORD'] = nil + ENV['OS_TENANT_NAME'] = nil + ENV['OS_AUTH_URL'] = nil + end + + let(:log_file) { '/tmp/aviator_spec.log' } + + let(:type) do + Puppet::Type.newtype(:test_resource) do + newparam(:name, :namevar => true) + newparam(:auth) + newparam(:log_file) + end + end + + + shared_examples 'creating a session using environment variables' do + it 'creates an authenticated session' do + ENV['OS_USERNAME'] = 'admin' + ENV['OS_PASSWORD'] = 'fyby-tet' + ENV['OS_TENANT_NAME'] = 'admin' + ENV['OS_AUTH_URL'] = 'http://192.168.11.4:35357/v2.0' + response = nil + VCR.use_cassette('aviator/session/with_password') do + session = provider.session + response = session.identity_service.request(:list_tenants, :session_data => provider.session_data) + end + expect(response.status).to eq(200) + end + end + + shared_examples 'creating a session using a service token from keystone.conf' do + it 'creates an unauthenticated session' do + data = "[DEFAULT]\nadmin_token=sosp-kyl\nadmin_endpoint=http://192.168.11.4:35357/v2.0" + response = nil + VCR.use_cassette('aviator/session/with_token') do + # Stubbing File.read produces inconsistent results because of how IniConfig + # overrides the File class in some versions of Puppet. + # Stubbing FileType.filetype(:flat) simplifies working with IniConfig + Puppet::Util::FileType.filetype(:flat).any_instance.expects(:read).returns(StringIO.new(data).read) + session = provider.session + Puppet::Util::FileType.filetype(:flat).any_instance.unstub(:read) + response = session.identity_service.request(:list_tenants, :session_data => provider.session_data) + end + + expect(response.status).to eq(200) + end + end + + shared_examples 'it has no credentials' do + it 'fails to authenticate' do + expect{ provider.session }.to raise_error(Puppet::Error, /No credentials provided/) + end + end + + shared_examples 'making request with an existing session' do + it 'makes a successful request' do + VCR.use_cassette('aviator/request/with_session') do + session = provider.session + response = provider.request(session.identity_service, :list_tenants) + expect(response.status).to eq(200) + end + end + end + + shared_examples 'making request with injected session data' do + it 'makes a successful request' do + VCR.use_cassette('aviator/request/without_session') do + session = provider.session + response = provider.request(session.identity_service, :list_tenants) + expect(response.status).to eq(200) + end + end + end + + shared_examples 'making request with no session or session data' do + it 'fails to make a request' do + expect{ provider.request(nil, :list_tenants) }.to raise_error(Puppet::Error, /Cannot make a request/) + end + end + + describe '#session' do + + context 'with valid password credentials in parameters' do + let(:resource_attrs) do + { + :name => 'stubresource', + :auth => { + 'username' => 'admin', + 'password' => 'fyby-tet', + 'tenant_name' => 'admin', + 'host_uri' => 'http://192.168.11.4:35357/v2.0', + } + } + end + + it 'creates a session' do + provider = Puppet::Provider::Aviator.new(type.new(resource_attrs)) + response = nil + VCR.use_cassette('aviator/session/with_password') do + session = provider.session + response = session.identity_service.request(:list_tenants) + end + expect(response.status).to eq(200) + end + end + + context 'with valid openrc file in parameters' do + data = "export OS_USERNAME='admin'\nexport OS_PASSWORD='fyby-tet'\nexport OS_TENANT_NAME='admin'\nexport OS_AUTH_URL='http://192.168.11.4:35357/v2.0'" + let(:resource_attrs) do + { + :name => 'stubresource', + :auth => { + 'openrc' => '/root/openrc' + } + } + end + + it 'creates a session' do + provider = Puppet::Provider::Aviator.new(type.new(resource_attrs)) + response = nil + VCR.use_cassette('aviator/session/with_password') do + File.expects(:open).with('/root/openrc').returns(StringIO.new(data)) + session = provider.session + File.unstub(:open) # Ignore File.open calls to cassette file + response = session.identity_service.request(:list_tenants) + end + expect(response.status).to eq(200) + end + end + + context 'with valid service token in parameters' do + let(:resource_attrs) do + { + :name => 'stubresource', + :auth => { + 'service_token' => 'sosp-kyl', + 'host_uri' => 'http://192.168.11.4:35357/v2.0' + } + } + end + + subject(:session) do + provider = Puppet::Provider::Aviator.new(type.new(resource_attrs)) + VCR.use_cassette('aviator/session/with_token') do + session = provider.session + response = session.identity_service.request(:list_tenants, :session_data => provider.session_data) + end + end + + it 'creates a session' do + expect(session.status).to eq(200) + end + + end + + context 'with valid password credentials in environment variables' do + it_behaves_like 'creating a session using environment variables' do + let(:resource_attrs) do + { + :name => 'stubresource', + } + end + let(:provider) do + Puppet::Provider::Aviator.new(type.new(resource_attrs)) + end + end + end + + context 'with valid service token in keystone.conf' do + it_behaves_like 'creating a session using a service token from keystone.conf' do + let(:resource_attrs) do + { + :name => 'stubresource', + } + end + let(:provider) do + Puppet::Provider::Aviator.new(type.new(resource_attrs)) + end + end + + end + + context 'with no valid credentials' do + it_behaves_like 'it has no credentials' do + let(:resource_attrs) do + { + :name => 'stubresource', + } + end + let(:provider) { Puppet::Provider::Aviator.new(type.new(resource_attrs)) } + end + end + + end + + + describe '::session' do + + context 'with valid password credentials in environment variables' do + it_behaves_like 'creating a session using environment variables' do + let(:provider) { Puppet::Provider::Aviator.dup } + end + end + + context 'with valid service token in keystone.conf' do + it_behaves_like 'creating a session using a service token from keystone.conf' do + let(:provider) { Puppet::Provider::Aviator.dup } + end + end + + context 'with no valid credentials' do + it_behaves_like 'it has no credentials' do + let(:provider) { Puppet::Provider::Aviator.dup } + end + end + end + + describe '#request' do + context 'when a session exists' do + it_behaves_like 'making request with an existing session' do + let(:resource_attrs) do + { + :name => 'stubresource', + :auth => { + 'username' => 'admin', + 'password' => 'fyby-tet', + 'tenant_name' => 'admin', + 'host_uri' => 'http://192.168.11.4:35357/v2.0', + } + } + end + let (:provider) { Puppet::Provider::Aviator.new(type.new(resource_attrs)) } + end + end + + context 'when injecting session data' do + let(:resource_attrs) do + { + :name => 'stubresource', + :auth => { + 'service_token' => 'sosp-kyl', + 'host_uri' => 'http://192.168.11.4:35357/v2.0' + } + } + end + let(:provider) { Puppet::Provider::Aviator.new(type.new(resource_attrs)) } + it 'makes a successful request' do + provider = Puppet::Provider::Aviator.new(type.new(resource_attrs)) + VCR.use_cassette('aviator/request/without_session') do + session = provider.session + response = provider.request(session.identity_service, :list_tenants) + expect(response.status).to eq(200) + end + end + end + + context 'when there is no session or session data' do + it_behaves_like 'making request with no session or session data' do + let(:resource_attrs) do + { + :name => 'stubresource', + } + end + let(:provider) {Puppet::Provider::Aviator.new(type.new(resource_attrs)) } + end + end + end + + describe '::request' do + context 'when a session exists' do + + it_behaves_like 'making request with an existing session' do + let(:provider) { provider = Puppet::Provider::Aviator.dup } + before(:each) do + ENV['OS_USERNAME'] = 'admin' + ENV['OS_PASSWORD'] = 'fyby-tet' + ENV['OS_TENANT_NAME'] = 'admin' + ENV['OS_AUTH_URL'] = 'http://192.168.11.4:35357/v2.0' + end + end + end + + context 'when injecting session data' do + let(:session_data) do + { + :base_url => 'http://192.168.11.4:35357/v2.0', + :service_token => 'sosp-kyl' + } + end + it 'makes a successful request' do + provider = Puppet::Provider::Aviator.dup + VCR.use_cassette('aviator/request/without_session') do + session = ::Aviator::Session.new(:config => { :provider => 'openstack' }, :log_file => log_file) + provider.session_data = session_data + response = provider.request(session.identity_service, :list_tenants) + expect(response.status).to eq(200) + end + end + end + + context 'when there is no session or session data' do + it_behaves_like 'making request with no session or session data' do + let(:provider) { Puppet::Provider::Aviator.dup } + end + end + end +end